简体   繁体   中英

How to update UI from background thread in a fragment

I have an app that has a Fragment with a ListView. I ping IP addresses on the network and when I get a response I add the IP address to a list. Once I've finished pinging the IP addresses, I put this list of IP addresses that replied to my ping into a ListView.

What I want to do is update this ListView as I'm pinging rather than doing after I've pinged all the IP addresses. To ping the IP addresses I'm using an AsyncTask which then calls a Runnable Thread. How do I tell the Fragment to update the UI from that Runnable class when I find an IP address?

The rough layout of my classes is below.

public class FinderFragment extends ListFragment {

    private void CallFind(){
        new Find().execute();
    }

    private class Find extends AsyncTask<Void, Void, Void> {

        @Override
        protected Void doInBackground(Void... voids) {
            SearchNetwork searchNetwork = new SearchNetwork(ipAddress);
            try {
                searchNetwork.StartFind();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);
            UpdateDeviceList();
        }
    }
}

public class SearchNetwork {

    public void StartFind() throws InterruptedException {
        Thread t[] = new Thread[20];
        for(int i=0; i<02; i++){
            t[i] = new Thread(new FindDevices(i*5));
            t[i].start();
        }
        for(Thread thread : t){
            thread.join();
        }
    }

    class FindDevices implements Runnable{

        @Override
        public void run() {
            //Ping the IP addresses here
            //I want to update UI from here
        }
    }

Try this....

getActivity().runOnUiThread(new Runnable(){
            @Override
            public void run(){
               // Do whatever you want
               }
             });

You should use AsyncTask instead of raw threads! There is a method onPostExecute() which runs on the main UI thread and that's the point where you can update your UI ...

But you have to keep in mind, that you have to cancel the AsyncTask (threads as well) if the fragment gets destroyed, otherwise your task will continue to run and will try to change the UI of the fragment, but the fragment doesn't exist anymore which will lead to exceptions like IllegalStateException: Fragment not attached to Activity or View Not Attached Exceptions

We can use Handler , runOnUiThread , postDelayed and AsyncTask .
AsyncTask is good option other than rest as it extends the handler class.
When you have to code in thread use the doInBackground() method like this:

class myAsyncTask extends AsyncTask(Void,Void,Void){
    public doInBackground(){
        // do your code here
    }
}

And call it on the UI thread like this:

new MyAsyncTask().execute();

use Handler , runOnUiThread or View.post

android.os.Handler handler = new android.os.Handler();
        handler.post(new Runnable() {
            @Override
            public void run() {
                //update here
            }
        });

if you want to auto update every x sec you can use this:

Runnable runnable = new Runnable() {
        @Override
        public void run() {
            while(refreshing){
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        //do your stuff here
                    }
                });
                try{
                    Thread.sleep(30000);
                }catch(InterruptedException e){
                    e.printStackTrace();
                }
            }
        }
    };
    new Thread(runnable).start();

Try

publishProgress()

and catch it in the overidden method

@Override
protected void onProgressUpdate(Void... values) {
    super.onProgressUpdate(values);
}

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