some kind of queue for asynctask - android

Hello
I have ListView with list of files. i click item and start to download this file in asynctask.
then i click another one and it must be put in queue, wait for that file and start ot download after it finishes. i can make some class that will hold all clicked links, and pass it to asynctask downloading part? and than somehow process them. but want to know is it the right way?
any links of sugestions? thanks

If you're set on using AsyncTask then, yeah, hold your clicked links and kick off new tasks when appropriate. You should note that AsyncTask is like the 'pocket knife' for threading in Android apps.
If you really need to manage a bunch of background tasks, and it sounds like you do, take a look at ThreadPoolExecutor. You get a lot of flexibility.
BlockingQueue
ThreadPoolExecutor
More Info
Example

Take a look at HandlerThread and the Handler class. You need one handler to pass tasks to the background HandlerThread and another for the UI thread to pass results back to the UI

Even though old, got here from Google: consider an IntentService.

Related

difference between onTouch and onClick listener and use of multithreading

I am trying to make some application in android (some kind of calculator app). In the app, on pressing the buttons a lot of conditions get checked using if-else. I am using onClickListener with the buttons, and so they are taking a slightly longer time to respond. So should I use multithreading to separate the logic from the main thread or rather use an onTouchListener with the buttons?
For the click event, keep using onClick, onTouch is used for tracking gestures.
It's not a good practice to do any logic operation inside the Main Thread. Leave it just for user interaction. You should consider use threading to avoid ANR (Application not responding). A good start is AsyncTask, that has it own method to do logic in a separete thread and update the UI on the Main Thread.
Please follow this link to get help with AsyncTask: https://stackoverflow.com/a/18827536/4973904
Hope that this could help you!
you should not do too much work on Main thread.The problem is not if else statements because conditional statements execute very fast but the logic you have written inside the if else blocks .may be your logic taking to much time to execute.
Solution:
if you want to perform extensive task , you should use some background thread or an alternative of this like Async task or Loaders.

Cancel AsyncTasks from collection

Let's say I have TasksManager which has static List tasks (not sure list is good solution) and there are static methods addTaskToList(MyTask task){tasks.add(task);},
removeTaskFromList(MyTask task){tasks.remove(task);}
Each task in doInBackground() calls first method, and in onPostExecute() there is second method call with "this".
MyTask has String field "method".
I want to cancel tasks of this list where task.getMethod().contains("url")..
not sure this code is good enough for stable working.. looks like onCancelled() of task not always called, multitreading can be dangerous for such methods I think.
for (MyTask task : tasks) {
if (task.getMethod().contains("url")) {
task.cancel(true);
break;
}
}
Is it normal practice to store tasks in this way or you can suggest me more elegant?
Cancelling an AsyncTask isn't always an immediate/obvious thing. If you are using cancel, you also need to make sure doInBackground is aware of isCancelled and you have to stop what you were doing yourself (see the docs for isCancelled).
I wouldn't recommended storing a list of AsyncTask objects and iterating them for doing sequential background work anyway. That sounds like it might get very messy very quickly. Each AsyncTask creates a new Thread, and that doesn't sound like what you want. Rather, you may just want one background thread you can do stuff on?
For one background thread you can use a HandlerThread and your own Looper, as follows:
HandlerThread backThread = new HandlerThread("BackLooper", Thread.NORM_PRIORITY);
backThread.start();
Looper backLooper = backThread.getLooper();
private synchronized void runOnBackThread(Runnable r) {
new Handler(backLooper).post(r);
}
Then each item you want to run in sequence you can post on the back thread by submitting a Runnable. And, you can also use the other Handler post variants too, postDelayed, postAt, and so on.
And, depending on what you're doing you may find IntentService very helpful. IntentService is provided specifically for a "work queue" type pattern. It has one background thread, does whatever you tell it to do ONE AT A TIME when you invoke it, and goes away on its own when it's not needed.
Lastly, if you're looking for a really nice general "task" type library for Android check out Square's Tape. That's not directly related to your question, but I find Tape super handy for more robust "queue it up" task type situations.

Cancel all AsyncTask?

I have a class which is used to get media file thumbs. This Loader like class starts an AsyncTask for every ImageView (is called in SomeAdapter#getView()). The task itself does a lot of things, and one of them is calling DiskLruCache, but when the SD card is unmounted, while the tasks are still running the application crashes.
I know how to register if the card state is changed.
So I need an approach how to stop all the running tasks. Any help would be nice.
just iterate through all list & use the following which will cancel all running asynctask.
if(myAsyncTask.getStatus().equals(AsyncTask.Status.RUNNING))
{
myAsyncTask.cancel(true);
}
call cancel() on each of you asynctasks, your asynctasks must check isCancelled() for returning true and if so then return from doInBackground. This is all in AsyncTask documentation.
There is one problem with your solution, AsyncTasks are known to work in parallel on some androids and to work serially on some other. Its actually not a good idea to run them in parallel. You might consider using ExecutorService as Veaceslav Gaidarji suggested.
You can try ExecutorService look here
There are nice examples - how to start async tasks, and how to stop them at any time you need.

Android AsyncTask inside AsyncTask

So, I'm working on a barcode decoder, which once we have the barcode goes to multiples API over the internet to decode what was just scanned.
The thing is that I have to link some XML parsing together, and I don't know if I'm doing it right.
So, once the barcode is scanned, my program calls an ASyncTask which goes over an API to retrieve the product name. Once it has the name, I want it to call another ASyncTask. I know this is possible by instantiating an ASyncTaks in the onPostExecute() of the other but, I think this is wrong, because it's like boxes within boxes.
So isn't it possible/better to instantiate my second ASyncTask inside my main Activity, and make it wait until my first ASyncTask is finished ?
(english isn't my primary language, I hope I made myself clear).
I think it's absolutely legitimate to start the second AsyncTask in the onPostExecute of the first AsyncTask, Mixing both operations is a bad logical idea, As "The Offspring" said - "You've gotta keep 'em separated"
If you don't want it to be directly inside the onPostExecute itself, set a handler to execute it in the activity and call this handler from onPostExecute.
And last thing - If you have a lot of logic - move it to a separate file, don't keep it all at the same file.
In situations like this it might be better to batch long running operations together in one AsyncTask.
Another option is to use the Loaders API, this makes chaining tasks much easier http://developer.android.com/guide/topics/fundamentals/loaders.html
You can go for another approach if you are facing often a situation like this. That is to merge requests and operations inside of runnables/callables and to manage them separately within say a queue for instance.
Here is a nice approach.
http://ugiagonzalez.com/2012/07/02/theres-life-after-asynctasks-in-android/

How to extend an existing background thread solution?

I am using Eclipse to develop an Android application that plots Bluetooth data.
I am using open source code, which has an existing solution that I want to extend and not replace to solve my development problem as stated above.
The open source code has a very nice and solid background thread that among other things continually logs BluetoothData to logcat even when I switch to a new activity.
Currently I have a solution which I am concerned about: I simply leverage a background thread method that writes to logcat to call a static plotData() method in my Plotting Activity. The result seems good. I get a nice plot. It clips along in real-time. Looks like an oscilloscope.
But I have received negative feedback about using the existing background thread coupled with a static method to plot the BluetoothDate. It has been suggested that I use a new thread, or add a handler, or use Async Task, or AIDL to solve my problem.
I have looked at all these solutions without success. Nothing seems to work like my static plotData() method. That is to say the existing background thread calls my static plotData() method which results in a real-time plot that looks great.
But I am still concerned about the negative feedback. I simply want to extend my existing background thread solution which I have done by having it call a static method to plot the data.
What are the problems I might face with this approach? Thread safety? Deadlock? I don't know.
Why do people keep suggesting that I create a new thread, handler, Async Task, or Service to solve my problem when extending my existing thread to call a static method seems to work just fine?
Any suggestions? What are the problems with extending the existing thread to use a static method to plot the data in real-time?
Anyone who says that you should use AIDL for this is a loon who should not be listened to. :) Also someone saying you need a Service if you don't want to have your background thread running when the user is not viewing your activity.
I'm not sure what you mean by "writes to logcat to call a static plotData()." You should write to logcat only for testing. Writing to logcat doesn't cause a call to any Java method.
If you are calling a static plotData() method on your Activity, you need to be extremely careful with this: first because it is difficult to figure out what activity instance should be called from there (it may go away at any time from the user finishing it, or be recreated as a new instance when the configuration changes, etc); and second because you can't touch your app's UI/view hierarchy from a background thread without risking that you corrupt its state (since the view hierarchy is single threaded).
The general model one does for this kind of thing is to have a background thread doing some work, generating the next data to display. Once it is done with the work you send a message to the main thread to have it display the new data. AsyncTask can be a simple way to do this, it takes care of the underlying message sending and threading. You can also implement this yourself, at some point having a Handler that you post a Runnable on or send a Message to that once executed on the UI thread will update your view state.
(Of course if you are using a SurfaceView, the whole point of that is to allow drawing to it outside of the main UI loop, so your background thread could just draw directly on to it as needed. Basically that is like writing a game.)

Categories

Resources