I was wondering how I could force a new ASyncTask in Android to be the next task executed. Imagine I have multiple ASyncTask's to load content from the internet, e.g. in my case I pre-load all objects of DataModelA, DataModelB and DataModelC. All the data is loaded to a central application model. I guess my current queue would look like this (but I do not manage it as a queue, yet):
1. DataModelA-Object1
2. DataModelA-Object2
3. DataModelA-Object3
4. DataModelB-Object1
5. DataModelB-Object2
6. DataModelB-Object3
7. DataModelB-Object4
8. DataModelC-Object1
9. DataModelC-Object2
10. ...
I start my tasks like this:
DataModelALoaderTask task = new DataModelALoaderTask();
task.execute("http://my-rest-api.com/datamodel/a");
// and the same for the other tasks
...
The task class looks like this:
private class DataModelALoaderTask extends AsyncTask<String, Void, List<DataModelA>> {
#Override
protected List<DataModelA> doInBackground(String... params) {
String data = params[0];
return DataModelAContentProvider.loadContentFromUrl(data);
}
#Override
protected void onPostExecute(List<DataModelA> models) {
// finally add the loaded content to the central application data model
...
}
}
What I would like to achieve:
Now within my GUI, I like to click on a button and force to load a single part of a model first, because I need to display it right now. Usually this is a task which is already in the queue, but in my case I could also just start a new task, e.g. to load DataModelC-Object2 first before all others are loaded. The queue could load a large number of objects, so that it makes sense to re-schedule a single task or start a new task which does the job immediately.
Any idea how I can handle that? If you would need to see more code snippets, please let me know.
Thanks in advance.
Best regards,
Michael
UPDATE: somehow my question seems to be related to this post. Is that the only way? Or could I simply start a parallel running task using the THREAD_POOL_EXECUTOR? How would I use that?
Related
I need to be able to cancel tasks involving web requests.
but I got some issues of memory management and exception handling when something fail.
For example:
I want to create a text edit for searching apps in user device.
so whenever user end a key, I want to clear current search task, and restart search.
The problem I got is in android 4.4, when trying to load the label of the app (to get it's name) I get an exception.
Also of I try to search contacts I'm getting an invlalid uri, fo rcontact photo.
I don't want any help dealing with this errors, I want a solution that will help me ignore this erros (try catach dont work) currently the entire ui get's stuck and app crash.
I'm using the executors service and call cancel when user gives me an input. but it's not enough.
Any advice will be appreciated, thanks.
if you're using AsyncTask i would like to suggest you to make it like this
AsyncTask<Void, Void, Void> a = new AsyncTask<Void, Void, Void>(){
#Override
protected Void doInBackground(Void... params) {
return null;
}
};
a.execute();
// at some point you want to cancel just use
a.cancel(true);
You can even put tasks together in List or array and loop to cancel it whenever you want.
You can try like this: what you want is getting result in background by network and show result in view ,you can Register a Listener to one task,. you can callback method of listener to use show result in view if it get the results in background ,if you do not need the result of current task and want satrt the next task ,you can only remove listener of current task,so the view will not reload
This is my idea ,I am so sorry for my bad english , if you do not see ,you can send message to me, and my email is bjltxsp#gmail.com
I haven't started coding yet. I'm trying to figure out which libraries that is out there and what the API can offer first.
I need to download a lot of resources before starting my app. Basically I'm going to have a "SplashSreen" and a progressbar that shows which file being downloaded and the progressbar for the entire progress of downloading the x-number of resources.
After looking through some discussions and tutorials on the subject, it seems to me that AsyncTask will do the job. But it's only possible to show the current progress for the current "object" being downloaded, and not for the entire queue.
Could anyone help me out here, give me some tutorials or something to dig into?
TBH; I'm not even sure if AsyncTask is what I'm looking for in this scenario. Basically I need something that can download resources, put in a queue, and let me know the progress of the entire queue, and which resource (name of it) being download at a certain time.
Thanks!
Of course an AsyncTask can do the job. Just put all your files in a asyncTask which display the progress.
class InitTask extends AsyncTask<Void, Integer, Boolean> {
private List<String> mNbFiles;
public InitTask(List<String> filesURL)
{
super();
mFilesURL = filesURL;
}
#Override
protected void onPreExecute() {
//show and init your progress bar here...
super.onPreExecute();
}
#Override
protected Boolean doInBackground(Void... params) {
for(int i = 0 ; i < mNbFiles.size() ; ++i){
//download one file ...
publishProgress(i);
}
}
}
I hope this will help you. Comment if you have any question.
AsyncTask isn't what you should be using for long running downloads. AsyncTasks are really about the UI, and it's important to know that the user navigating away or even rotating their screen will kill the download.
You should use a service to perform the download, so put all of your download code into an IntentService and update some kind of persistant storage to indicate progress (a couple variables in shared preferences would do fine (on to indicate current state, the other to indicate progress)).
You can then use your activity to fire up the service, and then monitor the progress of the downloads via the persistant storage or some callback passed via the intent (persistant storage is probably easiest).
AsyncTask is exactly what you are looking for, you can queue depending on the API an amount of tasks, im going to check the Asynctask implementation if there is a getter for the queue size, but if not you can make a list of asyncTask and update when its finished.
If you queue 15 tasks you can set your progress bar to 15 max and on each onPostExecute increment the progressBar :)
I will check the queue later and edit my answer.
Regards.
AsyncTask is very much what you're looking for. That's not really true that you can only update for the current Object. What that means is that you can update for the current AsyncTask.
Below is the onProgressUpdate method.
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
Log.i(logTag, "onProgressUpdate: " + String.valueOf(values[0]));
View view = getView();
if(view != null)
((ProgressBar)view.findViewById(R.id.progressBar)).setProgress(values[0]);
}
You see it takes any number of integers as the arguments. In your publishProgress method, you could call onProgressUpdate(itemProgress, totalProgress) and then update 2 different progress bars accordingly in onProgressUpdate.
You do all the downloading in doInBackground and each time you want to update the progress bar/bars, call publishProgress which passes your progress ints to onProgressUpdate.
In your AsyncTask doInBackground() method put your code that downloads all your objects and post updates of the progress bar using a handler. Take a look at this example:
http://developer.android.com/reference/android/widget/ProgressBar.html
The following code goes inside doInBackground():
while (mProgressStatus < 100) {
mProgressStatus = doWork();
// Update the progress bar
mHandler.post(new Runnable() {
public void run() {
mProgress.setProgress(mProgressStatus);
}
});
}
I have a bit of a problem I cannot solve, since it might a bug or something like that. I would like to make a chart with androidplot, and it works really good, but of course it needs some time to draw it (using hundreds of data), so I use a progress dialog to indicate the loading. But what happens is really weird.
I can define the appearance of the activity when it's loading and when it's loaded. When its loading I define a textview in the background setting its text to "loading" and if it is loaded, that textview contains lots of datas, text etc.
onCreate
{
Thread thread = new Thread(new Runnable() {
public void run() {
-------what needs to be appeared after its loaded ----
Textview -> 12,3245,456,78,789
}
----what is on the screen while the progressbar is on---
TextView -> loading..
}
But most of the time after the progress dialog disappears, nothing happens, the textview still says "loading" and rarely it loads the datas and makes the data appear and changes the textview. What I noticed that the more data I would like to appear the rarelier it stays at the loading phase. Of course everytime the loading progessbar appeers then disappears.
Any Suggestion? It is really weird because I use it in a tablayout and other tabs never do this, always make the data appear.
Thanks in advance!
UP: Okay, its always the first tab, whatever it contains, so the first tab is somehow wrong...
The Andoid UI toolkit is not thread-safe. So, you must not manipulate your UI
from a worker thread—you must do all manipulation to your user interface from
the UI thread. Thus, there are simply two rules to Android's single thread model:
1. Do not block the UI thread
2. Do not access the Android UI toolkit from outside the UI thread
read this for more information on how to access UI elements from outside.
edit::
use AsyncTask ::
onCreate
{
new myLoading().execute();
}
class myLoading extends AsyncTask<Void, Void, Void>
{
protected Void doInBackground(Void ... ) {
.......... do all the loading here .........
}
protected void onPostExecute(Void ) {
Textview -> 12,3245,456,78,789
}
}
I figured out some workaround. I dont have any clue about the solution, my only guess is the loading screen somehow overtake the arrival of all the data and so the chart cannot be drawn. or whatever...
I put a thread.sleep(1000) and now it works.
I have a table with about 1k rows that I want to display. This task obviously chokes the UI thread, resulting in a black screen while the onCreate() builds the table.
I've solved this by using AsyncTask which builds the wanted TableLayout in the "doInBackground" function and display it on the "onPostExecute" function.
Question #1:
Is there any better practice that I'm not familiar with?
Question #2:
My (simplified) "doInBackground" function looks like this:
protected Void doInBackground(Void... v) {
tmpTableLayout = populateTable("");
return null;
}
And my (simplified) "onPostExecute" function looks like this:
protected void onPostExecute(Void v) {
TableLayout ct = (TableLayout)findViewById(R.id.RealTable);
ct.removeAllViews();
/* WHATS HERE? */
}
What should I write instead of the "WHATS HERE?" in the last line of code in order to display the content of "tmpTableLayout" in "ct" ?
Thanks in advance!
Are you sure you want to display it all in one go?
One approach would be to dynamically load in more lines as the user scrolls down. So have a scroll listener that checks if the user is approaching the end of the content that is displayed and therefore start an AsyncTask or a thread loading more content.
Example:
Android List Activity with dynamically loaded images form the web in android
I would probably use a ListView and CursorAdapter and let Android manage fetching the data for you. See the accepted answer here.
I have an activity that needs to parse an XML from web, then read in images according to the XML info. To speed things along, I created AsyncTask to do the parsing and image fetching. However, I cannot put the images into the activity from within the thread due to "cannot update view objects from outside the view-creating thread..."
So I moved everything back to the main onCreate routine and it slows things down so much that it's not usable (UI not showing until everything is done (I guess when onCreate returns)) .
Any idea on how to tackle this problem (i.e. parsing/fetching using AsyncTask, then placing/updating images dynamically when each becomes available)? or where in the life-cycle should/can I update the UI?
Thanks in advance for all your help.
How are you using the AsyncTask? It's exactly for the purpose you mentioned: AsyncTask.doInBackground() is running in a separate thread and can be used to do the time-consuming task (loading the bitmap), and AsyncTask.onPostExecute() runs on the UI thread and can be used to perform quick operations that have to happen in the UI thread (i.e. replacing the bitmap in your View).
The async task was the right route. Use the async task to do the work in the background then use onpostexecute.
private class DownloadFilesTask extends AsyncTask<URL, Integer, imageview> {
protected imageView doInBackground(URL... urls) {
//parse and load
}
protected void onProgressUpdate(Integer... progress) {
//update progress if you have progress dialog
}
protected void onPostExecute(imageView result) {
//load image into view.
}
}
See Async task
Try this:
runOnUiThread(Runnable action)
//Runs the specified action on the UI thread.
I implemented this to update a ListView after getting data from the web and it works like a charm. If you download the source from this tutorial ( to the bottom ), you can see an implementation of how this works. :-)
Edit: see this rar file: ( Eclipse source code of an upcoming tutorial :-) )