简体   繁体   中英

How can I update the Main UI with information received from another thread? (While the thread is still running)

I'm trying to trying to update a screen element during runtime. But I cannot get this to work.

Here is some example code

public static TextView CurrentConnectionAttempt;
        CurrentConnectionAttempt = (TextView) findViewById(R.id.CurrentConnectionAttempt);

        IntentFilter afilter= new IntentFilter("SomeSortOfFilter"); 
        registerReceiver(SomeReceiver, afilter);

    private BroadcastReceiver SomeReceiver= new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {    
        for (int i = 0; i<100; 1++ ) 
        {           
            String connectionAttempt = "This is loop Iteration " + i;
            CurrentConnectionAttempt.setText(connectionAttempt);                    
            doSomething("Some Parameter");          
        }
       }
};

What I want to have happen is that the screen Textview to be updated with each new value of "i" and then have a function execute. I guess this example would be similar to a progress bar.

The hard part of this, is that the information is being discovered inside a broadcast event. So the information is not being found in the main UI thread. This is why Async task and other multi-threaded options aren't working for me. (As per my understanding)

I've looked into these solutions.

  1. Creating a runnable
  2. I've tried AyncTask
  3. Creating a second Broadcast receiver

Maybe I'm overlooking something obvious, or maybe it is impossible to affect the main UI thread in this way. Any suggestions and/or examples are appreciated.

Thanks!

EDIT: My Async task is extremely basic that I tried. I've even tried variations. I think that my problem might be similar to what I've just read on this blog. Async problems

What happens here is the broadcast receiver will run through all loop iterations, and the doInBackground function in the Async task will fire simultaneously, but never the onProgressUpdate function until the broadcast receiver has completely finished execution. Then the onProgressUpdate and the onPostExecute will execute multiple times. My guess is that since the broadcast receiver is on a separate thread from the UI, it needs to execute completely before another subthread is able to work.

Here is my code,

In my broadcast receiver:

    UpdateDynamicDisplay2 testDisplay= new UpdateDynamicDisplay2();
                    testDisplay.execute(connectionAttempt );

    // This is a sub class in my main class
class UpdateDynamicDisplay2 extends AsyncTask<String, String, String>{

    String Testing1;

        @Override
        protected void onPreExecute() {
            super.onPreExecute();

        }

        @Override
        protected String doInBackground(String... aurl) {
            publishProgress(aurl[0]);
            Testing1 = aurl[0];
                MyMainClass.CurrentConnectionAttempt.setText(Testing1);
            return Testing1;
        }

        protected void onProgressUpdate(String... progress) {
            MyMainClass.CurrentConnectionAttempt.setText(progress[0]);
        }

        @Override
        protected void onPostExecute(String unused) {   
            MyMainClass.CurrentConnectionAttempt.setText(unused);
        }
    }

Hopefully this is enough to go off of.

The problem is that you are trying to update your UI directly from a BroadcastReceiver through static variables. An AsyncTask is meant to be used by an Activity, not a BroadcastReceiver.

A better approach is to have your BroadcastReceiver update a source of data, and have your Activity monitor that data source.

If you are dealing with a lot of data, then your best bet is to create a ContentProvider and then register a ContentObserver to get notifications when data is changed.

If you only need to do this for individual values, then SharedPreferences might be an easier way to go. You can also register a listener for changes in this case.

Finally, you could create a singleton and keep your data in memory using a data structure. You can implement your own version of the Observer pattern to get notifications when data changes. This is probably not a good long term solution, since the Android environment does not make any long term guarantees regarding your in memory objects.

This question and it's answer will get you thru to exactly where you should be! Handlers works but not recommendable. In Android AsycTask is far better and readable.

How to let Asynctask update UI in different ways

Happy Coding!

EDITED

This link has some source code how to update progress bar such as 1 to 100,

http://ketankantilal.blogspot.com/2011/05/how-to-update-progress-bar-using-thread.html

Good luck

The easiest way is probably through a handler

private Handler handler; //Global Decalration
...
handler = new Handler(); //This is declared in the Main UI thread (onCreate)

Then within your thread that is doing the work:

handler.post(new Runnable() {
@Override
public void run() {
   CurrentConnectionAttempt.setText(ConnectionAttempt);
}
});

Hopefully that works.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM