UI update from stream

I want to update my user interface from a thread that updates the Progressbar. Unfortunately, when updating the progress step, deduced from "runnable", the progress indicator disappears! Changing the working bars available in onCreate() on the other hand works!

Any suggestions?

 public void onCreate(Bundle savedInstanceState) { res = getResources(); super.onCreate(savedInstanceState); setContentView(R.layout.gameone); pB.setProgressDrawable(getResources().getDrawable(R.drawable.green)); //**Works**/ handler.postDelayed(runnable, 1); } private Runnable runnable = new Runnable() { public void run() { runOnUiThread(new Runnable() { public void run() { //* The Complete ProgressBar does not appear**/ pB.setProgressDrawable(getResources().getDrawable(R.drawable.green)); } }); } } 
+50
android multithreading user-interface
Dec 06 '10 at 18:13
source share
7 answers

You have to do this with AsyncTask (Intelligent Back Thread) and ProgressDialog

AsyncTask allows the user interface thread to be used correctly and easily. This class allows you to perform background operations and publish results to a user interface thread without the need to manipulate threads and / or handlers.

An asynchronous task is determined by a calculation that runs on a background thread and the result of which is published to the user interface thread. An asynchronous task is defined by three generic types called Params, Progress and Result, and 4 steps called begin, doInBackground, processProgress and end.

4 steps

When an asynchronous task is running, the task takes 4 steps:

onPreExecute() , is called in the user interface thread immediately after the task is completed. This step is typically used to set up a task, for example by showing a progress bar in the user interface.

doInBackground(Params...) is called in the background thread immediately after onPreExecute () completes the execution. This step is used to perform background calculations, which can be time consuming. The parameters of the asynchronous task are passed to this step. The result of the calculation must be returned by this step and will be returned to the last step. This step can also use publishProgress (Progress ...) to publish one or more progress units. These values ​​are published in the user interface stream at the onProgressUpdate (Progress ...) stage.

onProgressUpdate(Progress...) , is called in the user interface thread after calling publishProgress (Progress ...). The runtime is undefined. This method is used to display any form of progress in the user interface while background computing is still in progress. For example, you can use it to animate a progress bar or display logs in a text field.

onPostExecute(Result) , called in the user interface thread after the background calculation is complete. The result of calculating the background is passed to this step as a parameter. Threading Rules

There are several streaming rules that must be followed for this class to function properly:

A task instance must be created in the user interface thread. execute (Params ...) must be called in the user interface thread. Do not call onPreExecute (), onPostExecute (Result), doInBackground (Params ...), onProgressUpdate (Progress ...) manually. A task can be executed only once (an exception will be thrown when trying to perform a second execution).

Code example
What the adapter does in this example is not important, it is more important to understand that you need to use AsyncTask to display a dialog for progress.

 private class PrepareAdapter1 extends AsyncTask<Void,Void,ContactsListCursorAdapter > { ProgressDialog dialog; @Override protected void onPreExecute() { dialog = new ProgressDialog(viewContacts.this); dialog.setMessage(getString(R.string.please_wait_while_loading)); dialog.setIndeterminate(true); dialog.setCancelable(false); dialog.show(); } /* (non-Javadoc) * @see android.os.AsyncTask#doInBackground(Params[]) */ @Override protected ContactsListCursorAdapter doInBackground(Void... params) { cur1 = objItem.getContacts(); startManagingCursor(cur1); adapter1 = new ContactsListCursorAdapter (viewContacts.this, R.layout.contact_for_listitem, cur1, new String[] {}, new int[] {}); return adapter1; } protected void onPostExecute(ContactsListCursorAdapter result) { list.setAdapter(result); dialog.dismiss(); } } 
+61
Dec 06 2018-10-06
source share

The simplest solution I've seen to provide short execution on a user interface thread is through the post () method of the view. This is necessary because the user interface methods are not repetitive. method for this:

 package android.view; public class View; public boolean post(Runnable action); 

The post () method corresponds to SwingUtilities.invokeLater (). Unfortunately, I did not find something simple that corresponds to SwingUtilities.invokeAndWait (), but can be built later on the basis of the first with a monitor and flag.

So, you save this by creating a handler. You just need to find your opinion and then publish it. You can find your opinion through findViewById (), if you usually work with id-ed resources. The resulting code is very simple:

 /* inside your non-UI thread */ view.post(new Runnable() { public void run() { /* the desired UI update */ } }); } 

Note. Compared to SwingUtilities.invokeLater (), the View.post () method returns a boolean, indicating that view has an associated event queue. Since I used invokeLater () accordingly. post () in any case only for fire and forget, I did not check the meaning of the result. Basically you should call post () only after onAttachedToWindow () has been called by sight.

Regards

+23
Jan 23 '12 at 18:20
source share

Use the AsyncTask class (instead of Runnable). It has a method called onProgressUpdate that can affect the user interface (it is called in the user interface thread).

+11
Dec 6 '10 at 18:16
source share

If you use Handler (I see what you are doing and I hope you created your instance in the UI thread), then do not use runOnUiThread() inside your runnable . runOnUiThread() used when you are doing something from a thread other than the UI, however Handler already execute your runnable in the user interface thread.

Try to do something like this:

 private Handler mHandler = new Handler(); public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.gameone); res = getResources(); // pB.setProgressDrawable(getResources().getDrawable(R.drawable.green)); **//Works** mHandler.postDelayed(runnable, 1); } private Runnable runnable = new Runnable() { public void run() { pB.setProgressDrawable(getResources().getDrawable(R.drawable.green)); pB.invalidate(); // maybe this will even not needed - try to comment out } }; 
+11
Dec 06 2018-10-06
source share

You need to create a Handler in the user interface thread, and then use it to publish or send a message from another thread to update the user interface

+9
Dec 06 '10 at 18:16
source share

If you do not like AsyncTask, you can use the observer pattern. In this example, use the ResponseHandler as the inner class in your activity, then enter a string message that will indicate the percentage of bars completed ... You need to make sure that any changes in the user interface are made in the ResponseHandler to avoid freezing the UI, then your worker the stream (EventSource in the example) can perform the required tasks.

I would use AsyncTask tho, however the observer pattern may be useful for tuning reasons, and it is also easier to understand. Also, I'm not sure that this method is widely accepted or will work 100%. Im downloading and android plugin now to check it out

+1
Jun 24 2018-11-11T00:
source share

As recommended by the official documentation , you can use AsyncTask to process work items shorter than 5 ms in duration . If your task takes longer, find other alternatives.

HandlerThread is an alternative to Thread or AsyncTask . If you need to update the interface from HandlerThread , post a message in the Looper UI thread and the Handler UI thread can handle UI updates.

Code example:

Android: toast in the stream

0
Sep 26 '17 at 10:32
source share



All Articles