I have 2 main AsyncTask which goal is to syncronize my app.
uploadFile and SyncData
So, if I have 3 pic to upload, I will have 3+1 = 4 threads
Each process fill a global error variable.
So what I need is to get a way to run this method after all threads are done.
How can I do it???
for (Captura capt : lCapturassASync) {
uploadFile(capt, ctx); // Is also an AsyncTask
}
new SyncData(ctx, lTiendasASync, lCapturassASync).execute("upload_datos", null);
Basically what you want to do is know when the async tasks were done in other threads.
About doing it on java specifically you can read this it might give you a very good idea on how:
How to know if other threads have finished?
Related
I have a gridview of bitmaps of very large number. To prevent out of memory error I only load a number of bitmaps and using onScrollListener I recycle the non nessecary bitmaps and create the ones that need to be shown. The loading bitmaps proccess is done in async task. This is the update method which is called every time the scrolling stops
AsyncCaller asyncCaller;
public void updateImageList(int first, int last){
if(!asyncCaller.isCancelled()){asyncCaller.cancel(true);}
asyncCaller=null;
asyncCaller=new AsyncCaller();
asyncInput input=new asyncInput();
input.first=first;
input.last=last;
input.id=Integer.toString(asyncId);
asyncId++;
asyncCaller.execute(input);
}
where asyncCaller is a class variable.
This code causes a NullPointerException at the asyncCaller.execute(input); line. Can someone tell me why since I assing to asyncCaller a new instance before calling execute?
I used asyncCaller as class variable in order to be able to cancel it if a new scroll has been made before the currently running AsyncTask has finished. No reason to keep it running since those bitmaps are no longer needed.
If I use asyncCaller as a local variable in the updateImageList method there is no way to cancel the currently running instances...correct?
EDIT: the question is pointless since the problem was a simple error from my part. I leave the question with my code corrected and working for refference for anyone looking for something like that
replace this line
asyncCaller.execute(input);
with
new AsyncCaller().execute(input);
I am using Async task to populate auto-complete suggestions from server.
Problem:
when user types and removes the text in edittext so many times.
lets say he typed: cofee > cof > coffee >coffee late .... etc for so many times.
for each text changed after 3 keyword(threshold) i am initializing an asynctask and ask for result.
so in current scenario i have so many threads running in background. so some of my latest async threads are waiting for there chance.
Whole this make my app very slow.
What can I do to tackle this problem?
If it is possible to load entire data from server at beginning...then you can avoid calling asynctask repeatedly and fetching the data from server. This will improve performance of you app. If data displayed in Listview is String, following link show how to filter it:
http://www.androidhive.info/2012/09/android-adding-search-functionality-to-listview/
And if custom object is used in ListView adapter, try:
Filtering ListView with custom (object) adapter
Hopefully this helps.
You should cancel the current task before issuing a new one. Use AsyncTask#cancel(true) for that and make sure that the execution of the task can be quickly stopped. This means correct handling of interruption and frequent checking whether the task was cancelled in the body of AsyncTask#doInBackground.
And you cannot execute again the AsyncTask you have cancelled. You have to create a new one. (Trying to execute it again leads to IllegalStateExceptions)
It worked for me by cancelling the task each time you change the text (if it is still running).
You need to define your request once outside the listener(private for the class), and then start your listener function by (if your request is not finished, then cancel it).
define your request out side the function
private YourSearchTaskClass YourTaskReq = new YourSearchTaskClass();
then start your addTextChangeListener/afterTextChanged by this
if (YourTaskReq.getStatus()!= AsyncTask.Status.FINISHED)
YourTaskAvReq.cancel(false);
YourTaskReq= new YourSearchTaskClass(keyword);
I have to edit huge bitmap files, so I want to use all cores of my device to speed up the process. I thought it would be a good solution to:
Count the number of available cores
Split the image into [numberofcores] parts
For each core create a new thread and let this thread handle one part of the image
How do I make sure all threads are done before I continue with other tasks, like saving the picture or return a message that the bitmap has been processed completely?
I think you should make another AsyncTask that waits for all the other threads to complete, so in the doInBackground() method of your waiting AsyncTask you can do the following :
while( task1.getStatus()!=AsyncTask.Status.FINISHED
|| task1.getStatus()!= AsyncTask.Status.FINISHED){
Thread.sleep(500);
}
and then in the onPostExecute() method of your "waiting task" you can continue with the other tasks.
Join each worker thread after you've started all of them.
Extend a Handler.Callback class with an array that keeps track of threads processing a particular image (might need to extend Thread too, so that you can specify what portion of the Bitmap the particular thread is processing), a the end of each threads processing sendMessage to a Handler object you create with your extended class instance.
Override handleMessage in the extended class, to receive result of particular thread remove thread from processing array store results of particular thread. When processing array size is 0, put results together.
Although I have not tried it yet, but from theoretical point of view I'm asking this question just to clear my doubts.
I have a scenario like:
1. Send a request to a server and receive JSON response. For this I'm using AsyncTask as there can be delay in receiving response.
2. From this response fetch an image URL.
3. Using one more AsyncTask, call the image URL and fetch the image. (Again may take time to fetch image)
So do you think using of 2 AyncTask just to get that image is inefficient.
OR, in step 1, instead of using AsyncTask, run the code sequentially and set Timeout instead.
Please suggest.
I'm going to go ahead and suggest this as an answer, which was originally in my comment:
Just fetch the image synchronously in the same AsyncTask that you're fetching the JSON from. For example:
doInBackground(Void...params){
//fetch JSON
// once JSON is fetched, fetch image
}
Not sure how you want to structure this exactly, but documentation says:
execute(Params...) must be invoked on the UI thread.
http://developer.android.com/reference/android/os/AsyncTask.html
so you cannot execute new async task from other async task background method.
even if you tried doing this from progress method, then since HONEYCOMB asynctasks are serialized, so your second async task will get queued anyway - you would have to use THREAD_POOL_EXECUTOR to make it run parallel.
I have a simple query returning a Cursor, and then I walk the cursor and create objects that I throw in an ArrayList, like this:
List<Element> myElements = new ArrayList<Element>();
Cursor c = db.query(...);
c.moveToFirst();
while (c != null && !c.isAfterLast()) {
myElements.add(new Element(cursor.getString(0).........)); <-- CREATING THE ELEMENT
c.moveToNext();
}
...
You get the idea.
The problem is that I need to run 4 queries like this hitting different tables, etc, but they all return the same Element object in the end (after walking the cursor).
Being a good Android citizen I created a class extending AsyncTask to avoid hogging the UI Thread. Also, I want to run the 4 queries in 4 threads to speed things up.
The question:
in my onPostExecute(Cursor c), I'm running the logic marked as "CREATING THE ELEMENT" above. If I run 4 threads with 4 queries and all modifying the List, will I have thread conflicts touching the same variable from them? How do I prevent that? Do I gain anything by threading this if the list I need to modify is synchronized? I mean, the threads will have to wait in line anyway, I might as well write the 4 queries and run them sequentially... or not?
I understand I want to keep this out of the UI Thread. The question is if I want to create 4 threads (each running in an AsyncTask) or just ONE AsyncTask that runs the 4 queries sequentially.
Thanks!
Llappall
will I have thread conflicts touching the same variable from them?
You will certainly have race conditions - if you are fine with it then no issues.
How do I prevent that? Do I gain anything by threading this if the list I need to modify is synchronized?
I don't think so.
I mean, the threads will have to wait in line anyway, I might as well write the 4 queries and run them sequentially... or not?
The question is if I want to create 4 threads (each running in an AsyncTask) or just ONE AsyncTask that runs the 4 queries sequentially.
I would run all the 4 queries in one AsyncTask, creating 4 AsyncTasks would be a lot to do and maintain.
Vector, as opposed to ArrayList, is synchronized and thread safe, so I would suggest to use it instead.
http://download.oracle.com/javase/6/docs/api/java/util/Vector.html
Another alternative would be to create a new List per thread and then use Collections.addAll() to incorporate the elements to the original list.
To answer the question whether you would gain anything by starting multiple threads, probably the answer will depend on how expensive are the queries you are doing. Starting a new thread has an intrinsic overhead, so you want to make sure that the query you are starting is worth the cost.