0

I want to call adapter.notifyDataSetChanged() from another thread. I read that I should use an AsyncTask and do the adapter.notifyDataSetChanged() in post execute.

I must execute the AsyncTask every 5 seconds only on the current activity (might be parent or child activity) because only one activity can do the asynctask at the same time.

Should I create a TimerTask which executes the AsyncTask every 5 seconds, stop it when I start another activity and start it back in onResume ?

Here is my code for the thread which updates the ListView of the current Activity.

private void runEventHandler() {
    new Thread() {
        public void run() {
            while (true) {
                try {
                    runOnUiThread(new Runnable() {

                        @Override
                        public void run() {
                            users.add(new User(10, "a", false));
                            adapter.notifyDataSetChanged();
                        }
                    });
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }.start();
}

Now I must be able to update the child activities' ListViews when a new User is added.

Elbbard
  • 2,064
  • 6
  • 30
  • 53
  • 1
    you can use runOnUiThread.for more information take look at http://stackoverflow.com/questions/11140285/how-to-use-runonuithread – pouyan Jun 01 '16 at 16:56
  • It works well, but it keeps running when I start a child activity. How can I stop it and then restart it ? Or if is possible, can I update child activities from the thread ? – Elbbard Jun 01 '16 at 17:05
  • 1
    you can use flags in your threads and outside of them change the flags to pause or stop them . if you put your code here may i can help you better. – pouyan Jun 01 '16 at 17:08
  • I added the code ! – Elbbard Jun 01 '16 at 17:12
  • do you mean that you are in activity "A" for example and "runEventHandler()" function is "A" function and in "A" you call "runEventHandler()" and you expect that your list in Activity "B" updated? did i understand you right? – pouyan Jun 01 '16 at 17:19
  • Yes, you understand me right. When I'm in Activity "B" the list must get updated from the thread running in A. The only other way I found is to create the thread in A and B and stop/restart it each time I open/exit one of the activities. – Elbbard Jun 01 '16 at 17:23
  • You can imagine that I have a TCP socket running on a thread and each time I recieve a new Packet, the current activity must be updated. What I need is a way to notify the current activity that there have been changes in the Model (I need an observer pattern for activities). – Elbbard Jun 01 '16 at 17:25

2 Answers2

1

You should a timertask like in link below : https://examples.javacodegeeks.com/android/core/activity/android-timertask-example/

the code to post any change on UIThread if you are in a different thread like doInBackground of AsyncTask:

runOnUiThread(new Runnable() {

                            @Override
                            public void run() {
                                // Here you can set your Ui Components
                            }
                        });
Lucas Ferraz
  • 4,112
  • 2
  • 18
  • 23
1

one possible way is that you create a flag in both activity to control your threads to be run ( the following codes are not runable just example to understand what you can do):

Activity A
{
public static boolean stopThread = false;
    @Override
    public void onResume()
    {
     super.onResume();
    // put your code here...
     stopThread =false;
     runEventHandler();
     }
private void runEventHandler() {
new Thread() {
    public void run() {
        while (A.stopThread != false) {
            try {
                runOnUiThread(new Runnable() {

                    @Override
                    public void run() {
                        users.add(new User(10, "a", false));
                        adapter.notifyDataSetChanged();
                    }
                });
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}.start();
}


  @Override
protected void onStop(){
    super.onStop();
    stopThread =true;
   }

}



Activity B
{
public static boolean stopThread = false;
    @Override
    public void onResume()
    {
     super.onResume();
    // put your code here...
     stopThread =false;
     runEventHandler();
     }
private void runEventHandler() {
new Thread() {
    public void run() {
        while (B.stopThread != false) {
            try {
                runOnUiThread(new Runnable() {

                    @Override
                    public void run() {
                        users.add(new User(10, "a", false));
                        adapter.notifyDataSetChanged();
                    }
                });
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}.start();
}


  @Override
protected void onStop(){
    super.onStop();
    stopThread =true;
   }

}

also you can use onPause() instead of onStop(). depends on your program concept.

pouyan
  • 3,445
  • 4
  • 26
  • 44
  • Thank you, I think I'll use that. However don't you think there is a cleaner way than to create the thread in every activities that will need the updates ? – Elbbard Jun 01 '16 at 17:41
  • there is other way that you can make your adapters static and you call "notifyDataSetChanged" from a service that is run in the background. – pouyan Jun 01 '16 at 17:43