The only reason for me is because the queueImage() method is called before onLooperPrepared() , so mHandler not initialized.
Update
HandlerThread is simply a Thread with an implementation of the run() method, where onLooperPrepared() called.
@Override public void run() { mTid = Process.myTid(); Looper.prepare(); synchronized (this) { mLooper = Looper.myLooper(); notifyAll(); } Process.setThreadPriority(mPriority); onLooperPrepared();
Therefore, when it is called, it depends on the start of this thread. If you run it and immediately call the public method via the link of this thread, you may encounter a race condition and mHandler will not be initialized in time.
One solution would be to delay the start of image processing or playing games using synchronization technologies. However, I would use a much simpler way.
To be clear, you want your mHandler be initialized immediately after creating HandlerThread , and you do not want to do this explicitly from the main operation in which HandlerThread is created.
Update 2
Just come up with the following solution.
queueImage() provides simple and easy data. You can check if mHandler is null, if true, add queueImage() parameters to this queue. When onLoopPrepared() is called, check to see if there is anything in this queue and this data is being processed.
private LinkedBlockingQueue<Pair<String,Integer>> mQueue = new LinkedBlockingQueue<Pair<String,Integer>>(); public void queueImage(String url, int pos) { if (mHandler == null) { mQueue.put(new Pair<String,Integer>(url, pos)); return; } mHandler .obtainMessage(MESSAGE_DOWNLOAD, pos, 0, url) .sendToTarget(); } @Override protected void onLooperPrepared() {