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?
Related
I have a simple action listener in a Swing app in Java Web Start (believe me it works great 99.99% of the time) that is getting called multiple times from the UI. Here is the scenario
the action listener calls a server side (EJB) method which populates
some tables in the database
the server side can take a long time (upto 1 minute) to process the
request
the action listener is meant to call the back end just once
in 99% of the cases (in production) the action listener works as
expected
there is 1% of cases where the back end method is called multiple
times resulting in data corruption in the database
tried to simulate with 2 UI's calling the back end with the same
inputs, but couldn't replicate
I am thinking there could be 2 hypotheses
the action listener is calling the back end method multiple times (possibly double clicks)
the back end is too overloaded to maintain thread integrity
I have seen the multiple click action in the case of HTML buttons in a browser and handled it with javascript/jquery. Does Swing have a similar hyper sensitivity?
I would like to use Eclipse debugger to diagnose thread problems, but don't know how to simulate this scenario. Stopping one thread is tripping the whole thing from launching another thread.
In any event, the Swing application is hyper sensitive, if anything. It does the job of passing the payload to the DB, but it is doing multiple times in 1% of the cases. I can write some DB code to filter the data, but I prefer a fix in Swing, if that is the root cause.
I tried to recreate the bug scenario with Sikuli by sending multiple clicks
to the button but in vain. Can you suggest me a way to simulate this possible UI/Threading bug scenario so that I can apply relevant fix? This has to be feasible as Swing has been around for decades now and lots of legacy apps use Swing and EJB.
Your help will be gratefully acknowledged.
Thank you
the action listener calls a server side (EJB) method which populates some tables in the database
A long running task should not execute on the Event Dispatch Thread (EDT). So I would suggest that when you click your button you would:
disable the button to indicate it is processing the task
start a SwingWorker to update the database on a separate thread.
when the SwingWorker finishes executing you enable the button.
This would prevent the user from clicking the button twice while the task is running.
Read the section from the Swing tutorial on Concurrency for more information on the EDT and on the SwingWorker.
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.
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'm trying to design an application that does two different tasks in parallel
each task start executing when the user presses a button in the activity "so I have three Activities two of them should do some tasks and the third one should collect the result".
When the user presses the button on the activity it will invoke a thread and then will Load the next Activity
In the third activity I have a button "I called it Send Button " that should stay inactive or disabled until all threads finish their work so at that moment it will be enabled and this activity contains plain text to show the result from these two threads and when the user presses this button it will send the information in the plain text to a web site.
My questions are : how can I run Threads in a different activity and send their result to another one? and how can I make that "Send Button" disabled until all threads finish their work.
I tried to make a while loop using a global variable in the onCreate method in the Third activity but it crashes the application and the activity didn't start up
You have two options to do a long running background task:
Using a thread which does your background work, with an singelton to access the results
Using a services which does the calculations
Depending on your actual use case the service is the first choice.
Use an Activity only when you need user interaction to your application. Else you can invoke both the threads using AsyncTask for your jobs(If you want the system to handle the worker threads for you. And unless you do not do any config changes on the fly -> performance hit).
Please keep in mind that, you should use AsyncTask only when the background jobs run for dew seconds. If you have a long running job, then use a service with a custom thread.
Hope this helped.
You can use AsyncTask. AsyncTask is one Class which is used to perform background processes without having threads. You can easily check the process is completed or not. Check this Tutorial. This can help you to understand how to run background process using an AsyncTask.
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.