Как позволить обработчику, который синхронизируется с основным петлителем, ждать больше данных
При поступлении нового объекта из базы данных будет создан новый обработчик, который отправляет объект в поток пользовательского интерфейса, чтобы пользовательский интерфейс обрабатывал и рисовал объект.
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 ответа
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
//Do something after 2 seceonds
}
}, 2000);
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);
}