HandlerThread is very suitable for this.
Here's a really working code ...
First the class itself. Data sets are sent to it for updating via ContentProvider
:
public class UpdateDataThread { Handler h; HandlerThread ht; ContentResolver contentResolver; public UpdateDataThread(ContentResolver cr) { contentResolver = cr; ht = new HandlerThread("UpdateDataThread"); ht.start(); Handler.Callback callback = new Handler.Callback() { @Override public boolean handleMessage(Message msg) { ArrayList<DataRow> data = (ArrayList<DataRow>) msg.obj; updateDataInThread(data); return false; } }; h = new Handler(ht.getLooper(), callback); } public void updateData(ArrayList<DataRow> data) { Message msg = new Message(); msg.obj = data; h.sendMessage(msg); } public void close() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { ht.quitSafely(); } else { ht.quit(); } } private void updateDataInThread(ArrayList<DataRow> data) { ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>(); ContentValues cv = new ContentValues(); for (DataRow row: data) { cv.clear(); if (row._next != null) { cv.put("next_id", row._next.id); } else { cv.putNull("next_id"); } ops.add(ContentProviderOperation.newUpdate(Uri.parse("content://"+ListDataProvider.DOMAIN+"/rows")) .withSelection("id = ?", new String[]{row.id.toString()}) .withValues(cv) .build()); } try { contentResolver.applyBatch(ListDataProvider.DOMAIN, ops); } catch (RemoteException e) { e.printStackTrace(); } catch (OperationApplicationException e) { e.printStackTrace(); } } }
In the main code, a constantly present UpdateDataThread
instance is created and, as the application updateData(...)
data is sent to it via the updateData(...)
call of this instance. Because in reality, a Message
is being sent, and for one Handler
they are lined up, as I understand, they will be processed sequentially. As required.
AsyncTask
fromHandler
? - VAndrJExecutor
e:.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
- VAndrJ pmexecuteOnExecutor
, in general, solves the problem. But the fact is that I would like to get a solution at the level ofHandler
andTask
. In the test task such a task came across and it was one of the complaints. - UncleAndyHandler
, in which there is a check whether there is a working thread (boolean flag, for example). If not, a stream is started and a flag is set. Until the flag is cleared, new data / tasks are saved for execution. When a separate thread has finished processing, it sends to theHandler
about its ending, the flag is reset, the first data is taken from the saved data and sent to the stream. Well, it will be in a circle. - VAndrJ