0

When a new object from the Database arrives, a new Handler will be created which posts the object to the UI thread so that the UI processes and draws the object.

    public void notify(MyObject myObject) {
        Handler handler = new Handler(Looper.getMainLooper());
        Runnable runnable = new Runnable() {
            @Override
                public void run() {
                    myview.handleUpdate(myObject); 
                }
        };
        handler.post(runnable);
    }

This works perfectly but when 100 messages come in at a the same time, 100 threads will be created and this creates a bottleneck.

I would like to let the handler wait for 2 seconds before it starts, so it can wait for other objects.

I've tried the following but this doesn't work. The thread will be initiated but waits 2 seconds for other objects which will be added to the list. When the time is over the thread will be posted to the main thread with all the objects.

    boolean wait = false;
    ArrayList<MyObject> myObjectList = new ArrayList<>();

    public void notify(MyObject myObject) {
        if(wait) {
            myObjectList.add(myObject); // handler waits already, just add the object to the list
            return;
        }

        wait = true; // says that the handler waits for data
        myObjectList.add(myObject);
        Handler handler = new Handler(Looper.getMainLooper());
        Runnable runnable = new Runnable() {
            @Override
                public void run() {
                    Thread.sleep(2000); // wait for 2 seconds
                    myview.handleUpdate(new ArrayList<>(myObjectList)); 
                    wait = false; // posted, a new handler can be created
                    myObjectList.clear(); 
                }
        };
        handler.post(runnable);
    }
tomerpacific
  • 4,704
  • 13
  • 34
  • 52
Homer
  • 3
  • 1
  • 2
  • use `Handler#postDelayed` instead – pskink Dec 25 '18 at 10:58
  • wow, thanks! I see, theres a big difference between postDelayed and sleep. Sadly I'm not able to mark this as correct answer – Homer Dec 25 '18 at 12:14
  • Where do you create these new Threads? I only see a "post()" on the MainThread. Calling that "post()" 1000 times doesn't create 1000 Threads, but it just posts Runnables in the MainThread's queue. However a better solution is to create a HandlerThread (using "new HandlerThread()") and you post those Runnables to is Handler. After every post() you have to post an additional postDelay(SEND_TO_UI, 2000) that will remove the previous one. In this way when the HandlerThread process the SEND_TO_UI message it means that there are not arrived any other post() within last 2 seconds. – emandt Dec 25 '18 at 12:36

2 Answers2

0
 Handler handler = new Handler();
    handler.postDelayed(new Runnable() {
      @Override
      public void run() {
        //Do something after 2 seceonds
      }
    }, 2000);
DevEloper
  • 39
  • 4
0
public void notify(MyObject myObject) {// this is the ONLY method on WORKER THREAD
            waitList.add(myObject);
 }

ArrayList<MyObject> waitList = Collections.synchronizedList(new ArrayList<>());

Handler handler = new Handler();// main thread handler

Runnable runCheck = new Runnable() {
           @Override
           public void run() {// runs on main thread
             if(checking){
                 for(Iterator<MyObject> iter = waitList.listIterator(); iter.hasNext(); ){
                      myview.handleUpdate((MyObject)iter.next());
                      iter.remove();
                       // instead of removing you can add a boolean (dirty) 
                       //to MyObject and set it to false to flag it as considered object
                      //in this way you do not need to change list from multiple threads
                 } 
                 checkWaitList();// check for new items 2 seconds later
             }
 }
 private void checkWaitList(){// runs on main thread
      if(checking)
           handler.postDelayed(runCheck, 2000);
 }

 private boolean checking;

 private void startChecking(){// runs on main thread
    if(!checking){
        checking = true;
        checkWaitList();
    }
 }
 private void stopChecking(){// runs on main thread
    checking = false;
    handler.removeCallbacks(runCheck);
 }
ygngy
  • 3,630
  • 2
  • 18
  • 29