This question is continuation to my previous question over stack overflow how-to-download-images-asynchronously-from-web-server . I am struggling to make the asynchronous list in blackberry. Now it is working fine for me. But it is giving me another problem now.
What I have done so far
Created a list view taking value from the XML feed
List is loaded with default thumbnail
Created RunnableFactory, limiting the thread pool size to 5 and then adding the runnable's to it. Runnable objects has the capability to download the image from server.
Now list loads perfectly fine asynchronously.
Problem scenario
On loading of the list screen it is initializing the RunnableFactory and then starting download and render images in list. But, let say I have 50 number of rows in the list. And now 10 images downloaded successfully, and RunnableFactory is still in action. At this point press back key and then click next. Practically it should come to the list screen and then again initiate the download process freshly. But it is throwing IllegalThredState exception
My assumptions on this problem
As all the threads are running, I might have to cancel all of the threads on back key pressed. If this is the problem can you please let me know how could i do it? As i have created multiple threads how could i manage to stop all threads and then navigate back ?
This looks like a more complex system. can anyone help me to understand what else could be the possible fix for this problem?
I got this exception when I tried to start thread second time after finished run. Once started, a Thread may not be restarted.
if you are using any treadpool then you shutdown otherwise you can inturupt all treads on navigate to back.
Related
I'm trying to get automated blackbox testing of my Android application working.
What is happening is that I run a network operation in an asynctask every x minutes. Once it is finished, the results are put into a list. Without robotium running, this is working perfectly. However with robotium running, let's say I have it set to run every 2 minutes, results might come back in up to 5 min or another random amount of time.
I believe that one of 3 things are happening, however I don't know why or how to fix it.
The robotium sleep() method is somehow also pausing my asynctask/background thread.
The robotium methods are somehow interfering with a broadcast receiver I use to notify that new results are in to add them to the list.
Something else is going on...
Does anyone have any suggestions? My current approach is to just call the sleep method for MUCH longer than is expected, but it seams random whether or not new data will come in. And if it does it is usually MUCH later than it was expected to return. (Remember that it works to the second, perfectly without using robotium.
Cheers
Synopsis: I need a way to start a task and have it persist through onDestroy() of app until it completes, or ability to pick up where it left off.
In my app, I have a ListView containing some items from a database. Hopefully only about 10-30 items, but potentially thousands (if the user never clears it, although I have prompts to clear it from time to time).
I have set up an AsyncTask to perform clearing the selected items from the list when the user wants to. However, I've noticed that the AsyncTask is killed when onDestroy() is called, for example if the user selects all items to delete, presses delete, then swipes app out of Recents while task is still performing.
I remember learning somewhere that a Service persists longer than an AsyncTask, so when the task gets killed I hand off the data to delete to a Service that I created. It does this by
intent.putIntegerArrayListExtra(list);
and get data from it in the Service. The Service persists far longer than the AsyncTask (only about 4-6 seconds), but still not all the way to completion. I know a little about START_XXXX flags, but that would be bad practice for this task, since they'd either send the whole list back to itself, or never really stop.
What is the preferred method to delete selected items from a database without it stopping when the app is killed, or at least to pick up where it leaves off?
Thanks all!
Your problem is very much like this: You have an application open in your favorite OS which is doing things in the background and then in the middle of it, the user force closes it. Logically, it will stop everything it's doing and stop executing and there's not much you can do to interrupt it.
There's no ideal solution to stop this from happening so what most people end up doing is to warn users that stopping the app when this operation is in process can have unwanted consequences.
In Android however, you have another option which is slightly more robust: you can write a persistent background service what continues running even if your app isn't running, but that still wouldn't solve the problem of what happens if the user switches off the phone when you're deleting from the DB? which would be the next logical question given your context. (personally, I would not recommend this approach for your task).
Best you can do is to maybe write a shared preference for every row you've not yet deleted (this will be the full list of rows you want to delete when you start deleting). For every row (or bunch of rows) you delete, change this preference to remove those rows from the preference and then if the app is interrupted, when you restart your app, read this preference and continue where you left off.
Alternatively, do what others do and warn users (by use of dialogs for instance) that they shouldn't stop the app until the delete is done otherwise bad things happen, etc.
I would strongly discourage you from using a service simply because it lasts longer than an AsyncTask. That's way too hacky and not at all reliable.
I'd like to ask you about the best solution/idea how to solve a following situation.
I'm developing an Android app which on one of screens has a set of buttons. After clicking on any of them a kind of config is posted to the server over http.
To prevent multiple clicks one by one which could result in concurrency problems I decided that after each click on a particular button there'll be a waiting interval of 30 seconds before a config is sent to the server. If another click on the same button happens before this 30 seconds are exceeded, then the execution of method is delayed for another 30 seconds - as long as no new click is performed, then the config will be sent.
I need an idea of an algorithm which would implement the mechanism above. What I know is that I don't want to start a separate thread for each click (too heavy for my app). A potential idea is to make a queue of events and send them in a loop but idea of a running endless loop in a thread (or Handler) also isn't my favourite.
Maybe there's a kind of mechanism in Android or J2SE in general, that allows to schedule an execution of method to a given time in the future but still be able to postopone execution for some additional time before 30sec rolled out.
thanks in advance!
I am fetching lots of thumbnails from a remote server and displaying them in a grid view, using AsyncTask. The problem is, my grid view displays 20 thumbnails at a time, so that creates 20 AsyncTasks and starts 20 executes, one per thumbnail.
I get RejectedExecution exception in my code. I recall reading somewhere that there is a limit to number of tasks that AsyncTask can have in its queue at a time, i might be hitting that. Was this bar lifted?
Is there a way to increase this limit? Is it safe to just ignore this exception?(by having an empty catch(RejectedException e){} block?)
I am running this code on Android 1.6 emulator and the API level in my code(minSDKVersion is 3).
[EDIT: Added SDK and API level info]
I recall reading somewhere that there
is a limit to number of tasks that
AsyncTask can have in its queue at a
time, i might be hitting that. Was
this bar lifted?
AsyncTask appears to presently support 10 threads and a work queue depth of 10. In theory, that would just support 20 items...if nothing else is using AsyncTask.
Is there a way to increase this limit?
Grab the source code, modify it, put it in your own package, and use that one. I did this with my AsyncTaskEx, though that is based on the Android 1.5 source.
Is it safe to just ignore this
exception?
Your work will not be queued for execution. Whether that is "safe" is up to you. I am not aware of any other impacts on the AsyncTask infrastructure.
I've done this exact same thing myself in an application.
Launching 20 parallel threads at once to download thumbnails from a server and push them to a data adapter doesn't sound like a good idea to me. All those threads will just trip all over each other and get in each other's way.
Instead, I would launch just one thread, have it collect the thumbnails in a loop, and add them to the adapter as they arrive.
You could use the serial executor with AsyncTask.executeOnExecutor, to serialize your tasks, but that will limit the task to only one concurrent task at the time. Might be good though when getting thumbnails:
myAsyncTask.executeOnExecutor(MyAsyncTask.SERIAL_EXECUTOR, [params] );
The problem is that the number of pending AsyncTasks for AsyncTask.THREAD_POOL_EXECUTOR is 128. Once the queue is filled up no new AsyncTasks can be queued.
From AsyncTask source code:
private static final BlockingQueue<Runnable> sPoolWorkQueue =
new LinkedBlockingQueue<Runnable>(128);
In my opinion that limit makes absolutely no sense at all and AsyncTask.SERIAL_EXECUTOR has an unlimited queue.
"Safe" to ignore - You need to make sure that any kind of notification that you were planning to do in the post-execute will be done here when you catch the error - otherwise you might leave something hanging if your other code makes assumptions about hearing back from this task.
Basically I have a maps Activity that when started it starts up a thread that slowly loads in all of the map markers (overlays).
Sometimes (probably like 75% of the time) when you attempt to interact with the map while this thread is running, it throws a RuntimeException with message "sending message to a handler on a dead thread". I have concluded that this error is not thrown if you wait to interact with the map until after the thread is done.
So my initial questions are: does the maps API have known threading errors? Is there a specific way one needs to go about loading maps data asynchronously? Maybe there is some notify method I need to be calling?
Basically if I run the thread but comment this line:
mv.getOverlays().add(pin);
The thread runs like normal but does not add overlays, and the app does not crash.
I will show more code if we need it.
Thanks
You may want to look at using an AsyncTask. Here's some good background information on the subject: http://developer.android.com/resources/articles/painless-threading.html