I have currently the following problem:
I got a server that provides and API via Google Protobuf. A Program (in this case an Android App) can request informations. I have an Activity in Android that will request Informations in the Background via a Runnable, which will then process the network request and dispatch to a function on the mainthread to update the UI with the new informations. Therefore I give the runnable a final interface with the function to dispatch which is implemented by the Activity. Now as the network stuff happens in the background and the UI should not block (e.g. with a Loading Spinner) I dont know what happens when the user switches to another Activity while the Runnable is still active. Will it still dispatch properly even if there is another Activity active? What is good design practice to solve this.
Of course I thought about adding a variable to the Runnable to mark it as dont dispatch, but there still could be race conditions (it gets dispatched while the user hits the back button, which would already have the dispatched function in the queue for the mainthread before marking the Runnable as aborted).
If you need any additional informations, please ask, I am happy to provide them.
Related
I'm a newbie in android and it seems to be simple, but I have following app structure.
App has button in main activity (which became disabled after click) and two tab fragments.
Active tab fragment run approx 20 threads via model-class.
So only model-class knows when all threads finished, but using view element in model is awful decision.
How to enable button after all background threads finished?
Timeout is bad choice, because no one knows on what device code will be performed and it can takes some time. Thread.join() or wait() hangs ui in my case.
Appreciate for any suggestions. I can provide code if it's necessary, but question seems to be general.
You should create a new Interface that works as Listener that listens to the event of threads in the model-class
Or
Using callBack() to notify the MainActivity when the threads finished to set back the button enable.
To create a new Listener please refer to this Question:
How to create our own Listener interface in android?
I am using volley library to perform network operations. On Application launch, I hit the service, I want to stop all the operations until i get the response from the service.
So i want to perform this synchronously. As I am using Volley which by default works in a separate thread. So how can i do this.
I have created custom Interface/listener to handle this, but does Android provide some way to achieve this.
I have done following.
Splash Activity implements an interface, and it goes to Main Activity after data is loaded
#Override
public void onContainerLoaded() {
//startActivity(MainActivity)
}
Even if you want to, you should definitely never EVER run any network-related task synchronously.
What you can do instead is starting your activity normally, and replace your layout with a progressbar logo, that is set to visibility.gone when your task is completed.
EDIT : By the way, if you are just starting your app and you haven't done anything concrete yet, I would recommend you to use an AsyncTask instead of Volley, which is often causing layer-coupling mistakes.
Use some event bus such as Otto
Create an event, make your main activity subscribe to the event using the event bus, start your operation, display a "Loading..." or something ProgressDialog in your main activity. From your worker thread when it completes send an event to your main activity. Make your main activity close the "Loading" dialog when it receives the event,
I guess a better question would be why you want to force it on the main thread?
As far as I know, volley won't let you do that but you might be able to if you make your own network operation. After Honeycomb, you will get a NetworkOnMainThreadException so you will need to override the policies.
I am learning Android app development from Udacity.com by Google engineers and they said,
"It is not a good idea to use 'AsyncTask' as it is not attached to an activity life cycle. The virtual machine will hold on to the activity object as long as the Asynctask is running, even after Android has called onDestroy( ) method for the activity and expect it to be discarded.
If you rotate your phone, the behavior is to destroy the current activity and instantiate a new one. The naive AsyncTask implementation now has two threads trying to do the same update. So it is not the best pattern for a potentially very long running background operation , such as fetching from web services. If you leave the app, the asyncTask will run as long as as the process is kept alive , but will run at a lower priority, and your process will be the first thing to be killed if the device needs more resources. "
1) If using AsyncTask is disadvantageous why was it created? What would have been the design philosophy or the cause to create it in spite of having services(or something similar to achieve same kind of functionality)?
2) What are the situations where Asynctask should be used for betterment compared to Services/similar options available in Android?
3) What are the situations/places Asynctask should never be used?
Please do not downvote this question. I searched Stackoverflow and I couldn't find a similar question.
Advantages of AsyncTask
Provides generic solution for all network calls
Publish progress to UI while executing.
Run Asynchronously
Easy to maintain and read.
Problems in AysncTask
When you rotate your screen, Activity gets destroyed, so AsyncTask will not have a valid reference to publish data from onPostExecute(). In order to retain it, you need to usesetRetainState(true) if calling from fragment or onConfigChanges() if calling from activity method of an activity.
If activity gets finished, AsyncTask execution will not cancelled automatically, you need to cancel them else they will keep on running in the background.
If any exception occurs while performing network task, you need to handle them manually.
Whereas AsycTask, Services, IntentService, Threads all run on different threads and all serve different purpose.
please read more detail here.
So you need to decide when to use which component while performing non UI operations.
Im trying to do following:
Send long executing request (I use here Events.echoEvent)
Show modal dialog (Wait...) with "cancel" button
If user press "cancel", dialog is hidded and event method should not be executed.
If user don't press button and wait. event method is called and close wait dialog
How can I do that?
ZK normally does all it's work for a single request on the server in a single thread. Events.echoEvent lets you get around that by finishing the request, and then calling back to the server immediately in a brand new request (and thread). The user's interaction with the client fires off a new request, so that will be a new thread also.
So, in your example above, you will be working with three threads:
for the original request which calls echoEvent
for the new request created by the echoEvent
for the request created when the user clicks 'cancel'
Obviously, the first will be long gone by the time the last two get called, but this is what you need to be thinking about in order to solve your problem.
You'll find plenty of discussion on StackOverflow about getting two threads to interact, or more specifically, getting one thread to interrupt another.
I'll refer you to 'How to stop threads in Java?' where the accepted answer favored sharing some sort of 'stop flag' over directly calling interrupt on a thread.
In your scenario this would play out with the long running process doing it's work while periodically checking the stop flag (a simple boolean). When the user clicks 'Cancel', you just need to flip the flag to true.
You can try
Create a thread to do the long operation as Sean mentioned above
(this is an independent thread, not ZK request thread)
Create a timer to check the status of that thread periodically.
(this will create a javascript timer to send ajax request periodically at client side)
And customize the busy mask by ZK Client Side programming to add the cancel button.
(the button click perform another ajax request)
Please refer to the similar article at stackoverflow:
Override “Processing” in ZK
Edit:
There are some related articles at my blog:
ZK: Customize the mask for showBusy
ZK: Adding abort button to busy mask
ZK: Mask page manually
I have a sync service using AsyncTask. Due to its objective (sync), I prefer to block the user and show him a progressdialog. (And error if exists)
Another difficulty is that I have about 8 AsyncTask running simultaneously. So I can't do a simple call to the progress dialog page when I begin the work and a close when it's finished. It's more complex.
Can someone help me with that task ?
Regards
onPreExecute(), onProgressUpdate(Progress...) and onPostExecute(Result) in AsyncTask are invoked on the UI thread. You can use these to display a progress bar, update it as the syncing progresses and hiding it when the work is finished.
As to the 8 simultaneous async tasks, do you really need 8 concurrent tasks? Can't you run them sequentially on one background thread using a single AsyncTask?
In the first place the point of the Service is that you don't need/want to block user to do stuff because it happens in the background. To that aspect, a Service doesn't have a UI thread, so if you want a progress bar shown in your Activity you'll have to send an Intent back to your activity (using broadcast receivers), such that you can switch the progress bar on/off and do other magic.
I would not recommend blocking the user though, because the tasks you are doing might take a very long time, giving a nasty user experience. You might even want to reconsider using a Service at all (if the data you are fetching is only used locally; for example fetch the latest twitter messages or something) and just go with an ASyncTask in your Activity, unless the data your Service fetches is used in other parts of your app as well (widgets for example) and you want that data available even if the activity isn't running.
You can make use of progress dialog to show wait cursor kinda thing.
Also you can imitate the concept of CountDownLatch in your application to dismiss the cursor. Like you can have a static function in a class like updateTaskComplete and update a static counter. And once the counter is equal to number of async task then in the function updateTaskComplete cancel the progress cursor. I mean you have to do something on this line.