Как позволить обработчику, который синхронизируется с основным петлителем, ждать больше данных - PullRequest
0 голосов
/ 25 декабря 2018

Когда прибывает новый объект из базы данных, создается новый обработчик, который отправляет объект в поток пользовательского интерфейса, чтобы пользовательский интерфейс обрабатывал и рисовал объект.

    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);
    }

Это работает отлично, но когдаОдновременно поступает 100 сообщений, будет создано 100 потоков, и это создает узкое место.

Я хотел бы дать обработчику подождать 2 секунды, прежде чем он запустится, чтобы он мог ждать других объектов.

Я пробовал следующее, но это не работает.Поток будет инициирован, но ждет 2 секунды других объектов, которые будут добавлены в список.Когда время истечет, поток будет добавлен в основной поток со всеми объектами.

    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);
    }

Ответы [ 2 ]

0 голосов
/ 25 декабря 2018
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);
 }
0 голосов
/ 25 декабря 2018
 Handler handler = new Handler();
    handler.postDelayed(new Runnable() {
      @Override
      public void run() {
        //Do something after 2 seceonds
      }
    }, 2000);
...