Hy!!
I have a thread class and want to set a timeout inside after 10 sec.
How is this been made?
Class:
public class HttpConnection extends Thread{
List<NameValuePair> list;
String url;
Handler handler;
public HttpConnection(List<NameValuePair> params, String url, Handler handler) {
this.list = params;
this.url = url;
this.handler = handler;
}
#Override
public void run() {
try
{
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(url);
String result;
BufferedReader in = null;
httppost.setEntity(new UrlEncodedFormEntity(this.list));
// Execute HTTP Post Request
HttpResponse response = httpclient.execute(httppost);
if(response != null){
in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
StringBuffer sb = new StringBuffer("");
String line = "";
String NL = System.getProperty("line.separator");
while ((line = in.readLine()) != null) {
sb.append(line + NL);
}
in.close();
Message msg = Message.obtain();
if ((result = sb.toString()) != null)
{
msg.obj = result;
}
else
{
msg.obj = null;
throw new Exception("ERROR");
}
handler.sendMessage(msg);
}
}
catch (Exception e)
{
Log.e("XXX", e.getMessage());
}
super.run();
}
}
httpclient.getParams().setParameter("http.socket.timeout", 10000);//10 seconds
the httpconnection will timeout in 10 seconds, probably throwing some exception, in which case you can end your thread
In Java you should be able to use the ThreadPoolExecutor's awaitTermination method to set a timeout. Whichever class is creating and executing this thread should be able to call awaitTermination on the executor for 10 seconds. Is this what you are trying to do (set a timeout ON or WITHIN your thread)?
threadPoolExecutor.awaitTermination(10, TimeUnit.SECONDS);
i may not sure we can use thread handler for these kind of tasks,you better use Asynchronous task for this purpose because it depends up on internet strength availability,it may takes more time to get response from server, so go through developer.android.com for this topic.
super.run();
to
handler.postDelayed(this, 10000);
Hope it's help.
Related
I'm running a Java code that listen to a long polling HTTP stream.
This is the method I'm using.
void connectStream() throws IOException, URISyntaxException {
URIBuilder uriBuilder = new URIBuilder("...");
HttpGet httpGet = new HttpGet(uriBuilder.build());
HttpResponse response = httpClient.execute(httpGet);
HttpEntity entity = response.getEntity();
if (null != entity) {
InputStreamReader stream = new InputStreamReader((entity.getContent()));
BufferedReader reader = new BufferedReader(stream);
String line;
while ((line = reader.readLine()) != null) {
// do stuff
}
}
}
I need to interrupt gracefully this stream from the main thread. What is the best way to do it?
For now, I'm adding an AtomicBoolean variable and check it in each iteration of the loop.
private AtomicBoolean interrupt = new AtomicBoolean(false);
void connectStream() throws IOException, URISyntaxException {
URIBuilder uriBuilder = new URIBuilder("...");
HttpGet httpGet = new HttpGet(uriBuilder.build());
HttpResponse response = httpClient.execute(httpGet);
HttpEntity entity = response.getEntity();
if (null != entity) {
InputStreamReader stream = new InputStreamReader((entity.getContent()));
BufferedReader reader = new BufferedReader(stream);
String line;
while ((line = reader.readLine()) != null) {
if (interrupt.get()) {
break;
}
// do stuff
}
}
}
public void setInterrupt() {
this.interrupt.set(true);
}
This works well when the buffer often contains data. But what if the buffer remains empty for a long time?
I've already tried to close stream and reader: the program does not execute the code inside the loop any more it does not exit from it.
Solved! I could find a way to get the socket underlying the HTTP connection. By closing it, the thread quits correctly.
// No need this anymore
// private AtomicBoolean interrupt = new AtomicBoolean(false);
// New
private Socket socket;
void connectStream() throws IOException, URISyntaxException {
URIBuilder uriBuilder = new URIBuilder("...");
HttpGet httpGet = new HttpGet(uriBuilder.build());
// New block code here
HttpClientContext context = HttpClientContext.create();
HttpResponse response = httpClient.execute(httpGet, context);
ManagedHttpClientConnection connection = context.getConnection(ManagedHttpClientConnection.class);
socket = connection.getSocket();
HttpEntity entity = response.getEntity();
if (null != entity) {
InputStreamReader stream = new InputStreamReader((entity.getContent()));
BufferedReader reader = new BufferedReader(stream);
String line;
while ((line = reader.readLine()) != null) {
// do stuff
}
}
}
public void setInterrupt() {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
I'm using Apache HttpClient 4.3.6 and I'm having a hard time with it in one particular instance.
Normally, all of my HttpPost calls are in a single main thread and happen serially. However, there's one instance where once a particular type of HttpPost happens, I need to start a side thread to monitor it. This side thread periodically tries to connect to the server to see if it's still up. If the connection to the server drops, I need to abort() the connection back in main so that it doesn't just get stuck until the timeout happens (I can legitimately have an operation where it's possible to take 45 minutes to complete).
I set up a PoolingHttpClientConnectionManager and a CloseableHttpClient at the beginning of main, and then I have a send method that main and the side thread both use to set up HttpPost objects that are local to the method. However, the client.execute(httpPost) local variable result from the side thread instance of the send method is somehow getting assigned to the local variable result in the main thread instance of the send method. They're getting crossed. I've searched around for the last few hours and I haven't found any solutions to this.
EDIT: Added example code. Had to obfuscated company stuff by changing various things to basic variables where classes would be used, so forgive some typos/whatever during that.
Class variables:
CloseableHttpClient client;
HttpPost longHttpPost;
boolean diePlz = false;
In main:
clientPool = new PoolingHttpClientConnectionManager();
clientPool.setMaxTotal(20);
clientPool.setDefaultMaxPerRoute(20);
client = HttpClients.custom().setConnectionManager(clientPool).build();
//Lots of logic here to set up things to be 'send()'ed
Send method:
private String send(String message, boolean longCall){
RequestConfig.Builder requestConfig = RequestConfig.custom();
requestConfig.setConnectTimeout(10000);
String url = "http://" + ip + ":" + port + "/connector";
HttpPost httpPost;
if(longCall){
httpPost = longHttpPost = new HttpPost(url);
} else {
httpPost = new HttpPost(url);
}
httpPost.setConfig(requestConfig.build());
httpPost.setHeader("Content-Type", "application/xml");
httpPost.setHeader("charset", "UTF-8");
httpPost.setEntity(getEntity(message)); //getEntity() is a local method that overrides AbstractHttpEntity
try {
if(longCall && !threadRunning){
diePlz = false;
ConnectionCheck watcher = new ConnectionCheck();
watcher.start();
}
//httpReponse is what seems to get crossed between invocations of send()
CloseableHttpResponse httpResponse = client.execute(longCall ? longHttpPost : httpPost);
//more stuff here to work with response
} catch (Exception e) {
LOG.error(e, e);
return null;
} finally {
if(longCall){
longHttpPost.releaseConnection();
} else {
httpPost.releaseConnection();
}
}
}
Nested thread class inside main class:
private class ConnectionCheck extends Thread implements Runnable, Serializable {
#Override
public void run(){
threadRunning = true;
try{Thread.sleep(5000);}catch(Exception e){LOG.error(e, e);}
boolean registerReturn = register(false); //this calls send()
if(registerReturn){
String response = checkStatus(); //this calls send()
if(response == null){ //if the connection we're watching drops...
if(longHttpPost != null){
longHttpPost.abort(); //...then kill it
}
} else {
while(response != null && !diePlz){
try {
Thread.sleep(5000);
} catch (Exception e){
LOG.error(e, e);
register(true);
threadRunning = false;
return;
}
response = checkStatus();
if(response == null){
if(longHttpPost != null){
longHttpPost.abort();
}
}
}
register(true); //this calls send()
threadRunning = false;
}
} else {
register(true); //this calls send()
threadRunning = false;
}
}
}
I wrote a Restful WCF service and it is deployed on IIS. I have been attempting to consume the WCF Service using a AsyncTask Thread. I built the thread in to the main UI class so that I can update the GUI.
public class ServiceRunning extends AsyncTask<String, Void, String>{
private Exception exception;
String line = "";
public void setLine(String line)
{
this.line = line;
}
public String getLine()
{
return line;
}
#Override
protected String doInBackground(String... url) {
try
{
DefaultHttpClient httpClient = new DefaultHttpClient();
URI uri = new URI(url[0]);
HttpGet httpget = new HttpGet(uri);
httpget.setHeader("Accept", "application/json");
httpget.setHeader("Content-type", "application/json; charset=utf-8");
HttpResponse response = httpClient.execute(httpget);
HttpEntity responseEntity = response.getEntity();
BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
// while ((line = rd.readLine()) != null) {
// Log.d("****Status Line***", "Webservice: " + line);
// }
while((line = rd.readLine()) != null)
{
setLine(line);
Log.d("****Status Line***", "Webservices: " + getLine());
}
}
catch (Exception e)
{
e.printStackTrace();
}
return "String :" + line;
}
protected void onPostExecute(String result) {
TextView txt = (TextView)findViewById(R.id.textView1);
txt.setText(getLine());
}
}
In the code, I write the response to a String and I attempt to display it after execution. For some resound, when I run the program I don't get the response, I get a blank TextView but the message displays in the Eclipse LogCat. I cant find the problem, what causes this?
AsyncTask is tied to the activity kicking it off. If you rotate the device or the app goes into the background, is added or removed from a dock, the original activity is destroyed. The AsyncTask continues though and responds to the original activity that is no longer visible.
You are better off using an IntentService or Service to call web services, it is a much more reliable pattern.
I am trying to access the android network by starting a TCP server. But when I create a new thread, either by
Thread t = new Thread(runnable);
t.start();
or FutureTask I still get the networkonmainthreadexception...
Use AsyncTask to perform network related ops
For Example :
private class DownloadWebPageTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
String response = "";
for (String url : urls) {
DefaultHttpClient client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
try {
HttpResponse execute = client.execute(httpGet);
InputStream content = execute.getEntity().getContent();
BufferedReader buffer = new BufferedReader(new InputStreamReader(content));
String s = "";
while ((s = buffer.readLine()) != null) {
response += s;
}
} catch (Exception e) {
e.printStackTrace();
}
}
return response;
}
#Override
protected void onPostExecute(String result) {
textView.setText(result);
}
}
Or you can do this, Although it is not recommended
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy =
new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
adding this code will not give you network on main thread exception anymore.
You have to do the actual network IO on the run() function of the runnable in the thread. You don't just create a thread and then do the IO.
I want to post String data over HttpClient in android
but i'm tired after receive response status code 503 - service unavailable and
return response as Html code for our url.
I write in the following Code in JAVA Application and i return the data but when I write the same code in Android Application i receive an exception file I/O not found, I'm Puzzled for this case:
public void goButton(View v)
{
try{
URL url = new URL("https://xxxxxxxxx");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
Test ts= new ApiRequest("null","getUserbyID",new String[] { "66868706" });
String payLoad = ts.toString(); //toSting is override method that create //JSON Object
System.out.println("--->>> " + payLoad);
conn.setDoOutput(true);
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
System.out.println("=================>>> "+ payLoad);
wr.write(payLoad);
wr.flush();
BufferedReader rd = new BufferedReader(new nputStreamReader(conn.getInputStream()));
String line;
while ((line = rd.readLine()) != null) {
System.out.println("-->> " + line);
response += line;
}
wr.close();
rd.close();
System.out.println("=================>>> "+ response);
} catch (Exception e) {
e.printStackTrace();
System.out.println("=================>>> " + e.toString());
throw new RuntimeException(e);
}
I try to put this code in AsynTask, Thread but i receive the same response status code.
I write in the following Android code as an example data
public void goButton(View v)
{
try{
new Thread(new Runnable() {
public void run() {
HttpClient client = new DefaultHttpClient();
HttpConnectionParams.setConnectionTimeout(client.getParams(),
10000); // Timeout Limit
HttpResponse response;
String url = "https://xxxxxxxxxxxxx";
JSONObject json = new JSONObject();
try {
HttpPost post = new HttpPost(url);
post.setHeader("Content-type", "application/json");
json.put("service","null");
json.put("method", getUserByID.toString());
json.put("parameters", "1111");
System.out.println(">>>>>>>>>>>" + json.toString());
StringEntity se = new StringEntity(json.toString());
se.setContentType(new BasicHeader(HTTP.CONTENT_TYPE,
"application/json"));
post.setEntity(se);
String response = client.execute(post);
if (response != null) {
String temp = EntityUtils.toString(response.getEntity());
System.out.println(">>>>>>>>>>>" + temp);
}
} catch (Exception e) {
e.printStackTrace();
System.out.println(">>>>>>>>>>>" + e.getMessage());
}
}
}).start();
}
Please Help me to find solution for this problem :(
Thank you in advance
Here is an code snippet , hoping it will help you.
1)An function which carries the http get service
private String SendDataFromAndroidDevice() {
String result = "";
try {
HttpClient httpclient = new DefaultHttpClient();
HttpGet getMethod = new HttpGet("your url + data appended");
BufferedReader in = null;
BasicHttpResponse httpResponse = (BasicHttpResponse) httpclient
.execute(getMethod);
in = new BufferedReader(new InputStreamReader(httpResponse
.getEntity().getContent()));
StringBuffer sb = new StringBuffer("");
String line = "";
while ((line = in.readLine()) != null) {
sb.append(line);
}
in.close();
result = sb.toString();
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
2) An Class which extends AsyncTask
private class HTTPdemo extends
AsyncTask<String, Void, String> {
#Override
protected void onPreExecute() {}
#Override
protected String doInBackground(String... params) {
String result = SendDataFromAndroidDevice();
return result;
}
#Override
protected void onProgressUpdate(Void... values) {}
#Override
protected void onPostExecute(String result) {
if (result != null && !result.equals("")) {
try {
JSONObject resObject = new JSONObject(result);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
3) Inside your onCreate method
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView("your layout");
if ("check here where network/internet is avaliable") {
new HTTPdemo().execute("");
}
}
This code snippet ,
Android device will send the data via URL towards Server
now server needs to fetch that data from the URL
Hey Mohammed Saleem
The code snippet provided by me works in the following way,
1)Android device send the URL+data to server
2)Server [say ASP.NET platform used] receive the data and gives an acknowledgement
Now the Code which should be written at client side (Android) is provided to you, the later part of receiving that data at server is
Server needs to receive the data
An webservice should be used to do that
Implement an webservice at server side
The webservice will be invoked whenever android will push the URL+data
Once you have the data ,manipulated it as you want