android cancel previous http get request - android

I want to create an autoCompleteTextview with the suggestion from the web-service. On text change I call the web service with the text entered.
public String searchpalace_Searchtext(String serchtext)
{
String resultString = "";
try {
String searchtext = URLEncoder.encode(String.valueOf(serchtext), "UTF-8");
HttpClient Clientloc = new DefaultHttpClient();
String URL = baseUrl + "places?name=" + searchtext;
HttpGet httpget = new HttpGet(URL);
ResponseHandler<String> responseHandler = new BasicResponseHandler();
resultString = Clientloc.execute(httpget, responseHandler);
}
catch (Exception e) {
resultString = "";
}
return resultString;
}
This function is called from the asyncTask when reach character is entered or deleted. Now when the text is entered fast the I want to cancel the pending request when the new request is arrived. How can I cancel the previous request?

You can go through each queued task and call the cancel() method. Check if the task was cancelled using isCancelled(). Do not trigger async tasks for every change in the text box. You can introduce a small delay to avoid unnecessary creation of AsyncTask objects.

You can use Android volley network tool kid for cancel the HttpRequest,

If HttpClient.execute() can be interrupted, AsyncTask.cancel(true) will do it if you pass (true). The docs don't say if it's interruptable or not, experiment.
If it doesn't then you may need to investigate the toolkit suggested in another answer.
Anyway you can check isCancelled() and not apply the result. Probably not a huge overhead once the connection has been started.
Note that, depending on Android version, sometimes multiple AsyncTasks can run in parallel (donut - honecomb) and sometimes they only run one at a time and queue up (honeycomb onwards). You can change the thread executor to allow them to run in parallel, see the AsyncTask class docs, but this will affect the rest of your app too.
Also note you're not allowed to re-use an AsyncTask once it's been run.

Related

Android web api call without asynctask

I need to make an api call on click of button. So i do it following way.
btn.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
try
{
HttpResponse apiResponse = mySingleTonehttpClient.execute(new HttpGet(Url));
HttpEntity resEntity = apiResponse.getEntity();
InputStream instream = resEntity.getContent();
String result = convertInputStreamToString(instream);
}
}
This code is working fine if i set targetSDKVersion = 8 in Manifest file. But giving me Network mainthread error for targetSDKVersion = 11. Can anyone suggest me what should i do?
Thanks,
Jay
The reason for this is that you're not supposed to do things that can possible take a long time in the UI Thread. Because doing that will result in the UI being blocked, and you're application will be lagging.
That's why you should either use a Worker Thread or an AsyncTask to do Network IO. You can read more information about how to use them and how they can interact with the UI Thread on the Android Developer guide.
You should not do networks call on main/UI thread of Application. you may start new worker thread that will run in separate thread rather than on UI thread.

Android Worker Thread for HTTP Requests

I have a worker thread that runs in an infinite loop. If it's queue of http requests is empty it waits. As soon as a http request is added to the queue it gets notified and executes this http request. This works all fine but I have some questions on this:
I'm doing it something like this (shortened!):
mHttpClient = new DefaultHttpClient();
mHttpPost = new HttpPost(MyHttpClient.getAbsoluteUrl(url);
while (true)
{
// Check if the queue is empty, if so -> wait
StringEntity se = new StringEntity(queue.poll());
mHttpPost.setEntity(se);
HttpResponse response = mHttpClient.execute(mHttpPost);
}
The question is: is this the most efficient way to do it if the queue has like 100 items? Does the http connection remain open all the time or does it get connected again and again? And if it remains open, is it a good idea to leave it open all the time when the app is running, or should I close it until new items are added to the queue?
The second question is concerning the infinite loop. I need the thread to run all the time when the app is running but the still the infinite loop doesn't look nice. I know I could make something like: while(!cancelled) but I don't call a thread.cancel() method anyway because I mean there is no App.onDestroy() event where I could call thread.cancel(), right? How would you handle that? Because I'd actually want to save the queue to "disk" when the thread is killed by the system but how can this be done?
Sorry for the long text and my bad english

Android Ice Cream Sandwhich versus Gingerbread HTTP Post

Fairly new to Android and created/tested my app using Android 2.3.5 (Gingerbread). I have multiple database connections I used HTTP Post (but did not use AsyncTask) and everything worked great. I then tested it on Android 4.0.3 (Ice Cream Sandwhich) and I'm not able to connect to the database, therefore my app does not work.
Wondering what do I need to consider to allow this working app to run on Ice Cream Sandwhich? I did move the database connection out of the UI Thread (but not AsyncTask) and it still does not connect.
Here is my class I created outside of my UI Thread:
public class InputsRecapGetTask {
public InputsRecapGetTask(InputsRecap activity,
ProgressDialog progressDialog) {
this.activity = activity;
this.progressDialog = progressDialog;
getDatabase();
}
public void getDatabase() {
// TODO Auto-generated method stub
progressDialog.show();
// create new default httpClient
HttpClient httpclient = new DefaultHttpClient();
// create new http post with url to php file as pararmenter
HttpPost httppost = new HttpPost(
"http://test.com/returnBBD.php");
// assign input text to strings
user = Login.userStatic;
Did you examine the logs? IIRC, Android 4 requires that http requests are not done from the main thread. There must be a message telling this.
On the other hand, please keep in mind that
if you turn the screen, the Activity that created the AsyncTask may
be removed from the screen (forever) and replaced by another
Activity; it (the 1st Activity) will receive the result, but will not show anything;
in Android 4, all AsyncTasks are by default serviced by a single
thread; this guarantees that responses arrive in the order the
requests are made, but also means that the 2nd request will start only after the
1st one finishes (or times out).
According to MVC, the data retrieval must be done by the model, not by the controller (Activity) whose lifetime is that of a View.

Post Data to URL through Android App

I'm trying to post data to URL by using Android App.
URL:
parameters:
"name" and "message"
I use the following code but it doesn't work:
public void onClick(View v) {
// Create a new HttpClient and Post Header
// Create a new HttpClient and Post Header
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://comparch2011.appspot.com/");
try {
// Add your data
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("name", "DEV"));
nameValuePairs.add(new BasicNameValuePair("message", "AndDev is Cool!"));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
// Execute HTTP Post Request
HttpResponse response = httpclient.execute(httppost);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
} catch (IOException e) {
// TODO Auto-generated catch block
}
}
-first thing first : you should use adb logcat. It will give you real time logs of your phone on your computers, it is incredibly useful to know what is going on.
-I suspect that you are making these calls in an Activity and in this case the app is simply crashing because of that : their is a safeguard to prevent you from doing that. It raises errors 'network on main thread' when necessary (like here).
The problem is that Activities are ran on the main thread, the one that is also used for the UI. so when you make such a network call, all the UI is blocked until the function has returned (and since it is waiting for the website to respond it can take a couple of seconds, which is very bad for the usability of your app).
The solution is to use an AsyncTask . It is an easy to use class that will allow you to make asynchronous calls (ie calls that don't block the UI).
As you can see in your LogCat, the error is a NetworkOnMainThreadException.
Which Android states here http://developer.android.com/reference/android/os/NetworkOnMainThreadException.html as:
NetworkOnMainThreadException:
The exception that is thrown when an application attempts to perform a
networking operation on its main thread.
This is only thrown for applications targeting the Honeycomb SDK or higher. Applications targeting earlier SDK versions are allowed to
do networking on their main event loop threads, but it's heavily
discouraged.
So take a look at http://developer.android.com/reference/android/os/AsyncTask.html instead, and be aware that the getResponse not should be called on the UI thread.
Alternatively you can probably just change the target or change the strictpolicy as follows, but I would no suggest doing so...
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
You shouldn't perform Network activities on the main thread. Because it doesn't allow the user to respond to the view when the network action is being performed.
Use an Asynctask, and it will work.
http://developer.android.com/reference/android/os/AsyncTask.html
Nithin

Android HttpClient : NetworkOnMainThreadException

I have some code below:
protected void testConnection(String url) {
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpGet httpget = new HttpGet(url);
ResponseHandler<String> responsehandler = new BasicResponseHandler();
try {
String connection = httpclient.execute(httpget, responsehandler);
Toast.makeText(getBaseContext(), R.string.connection_succeed, Toast.LENGTH_SHORT).show();
view_result.setText(connection);
} catch(IOException e) {
Toast.makeText(getBaseContext(), R.string.connection_failed, Toast.LENGTH_SHORT).show();
}
httpclient.getConnectionManager().shutdown();
}
and add a permission in Menifest:
<uses-permission android:name="android.permission.INTERNET"/>
But it goes an exception:
NetworkOnMainThreadException,
How can i do?
On ICS and later you cannot do network operations on the UI thread anymore. Instead you are forced to create a new thread and do your networking stuff there.
Possible tools are Android's AsyncTask and the normal Java Thread.
A good tutorial can be found here: Android Threads, Handlers and AsyncTask - Tutorial
Starting from API 11, you can not manipulate network (time-consuming) operations on main thread. Use AsyncTask or Thread to perform such operations.
You cant perform network operations in event thread, since android Api Level 11.
Instead you should do network operation in another thread than event thread, and use Handler or Asynctask to do so.
I you run your code in android 2.x and its lower version, i think this code will run perfectly. But if you run this in 3.x and it's upper version then you get an Exception. The problem is the you need to call the web service from your worker thread(AsyncTask<>) . You can not call the web service from the main thread.

Categories

Resources