文章出处:http://blog.csdn.net/shift_wwx
之前 Android 中Handler 中大体说了一下handler的应用过程,为了更好实现异步操作,android 提供了HandlerThread。
/** * Handy class for starting a new thread that has a looper. The looper can then be * used to create handler classes. Note that start() must still be called. */
public class HandlerThread extends Thread { int mPriority; int mTid = -1; Looper mLooper; public HandlerThread(String name) { super(name); mPriority = Process.THREAD_PRIORITY_DEFAULT; }说白了就是个Thread,但是在这里直接将Looper 给弄好了:
@Override public void run() { mTid = Process.myTid(); Looper.prepare(); synchronized (this) { mLooper = Looper.myLooper(); notifyAll(); } Process.setThreadPriority(mPriority); onLooperPrepared(); Looper.loop(); mTid = -1; }所以,在新建实例之后,必须要start 才能能应用,不然在getLooper的时候:
public Looper getLooper() { if (!isAlive()) { return null; } // If the thread has been started, wait until the looper has been created. synchronized (this) { while (isAlive() && mLooper == null) { try { wait(); } catch (InterruptedException e) { } } } return mLooper; }会认为不是alive,返回null。
所以一般应用过程是这样的:
//创建一个HandlerThread,即创建了一个包含Looper的线程。 HandlerThread handlerThread = new HandlerThread("leochin.com"); handlerThread.start(); //创建HandlerThread后一定要记得start() //获取HandlerThread的Looper Looper looper = handlerThread.getLooper(); //创建Handler,通过Looper初始化 Handler handler = new Handler(looper);这个handler 就不在UI线程,这样就可以实现了异步操作,至于发msg 还是 post 就在UI 现在操作就可以了。
弄个例子(copy 于Android TV):
public TvInputBaseSession(Context context, String inputId, int deviceId) { super(context); mInputId = inputId; mDeviceId = deviceId; mTvInputManager = (TvInputManager)context.getSystemService(Context.TV_INPUT_SERVICE); mHardware = mTvInputManager.acquireTvInputHardware(deviceId, mHardwareCallback, mTvInputManager.getTvInputInfo(inputId)); initThread(mInputId); } private void initThread(String inputId) { mHandlerThread = new HandlerThread(inputId); mHandlerThread.start(); mSessionHandler = new Handler(mHandlerThread.getLooper(), this); } private void releaseThread() { mHandlerThread.quit(); mHandlerThread = null; mSessionHandler = null; } @Override public boolean handleMessage(Message msg) { if (DEBUG) Log.d(TAG, "==== handleMessage ====" + msg.what); switch (msg.what) { case DroidLogicTvUtils.SESSION_DO_RELEASE: doRelease(); break; default: break; } return false; } public void doRelease() { mHardware.setSurface(null, null); mTvInputManager.releaseTvInputHardware(mDeviceId, mHardware); releaseThread(); } @Override public void onRelease() { mSessionHandler.obtainMessage(DroidLogicTvUtils.SESSION_DO_RELEASE).sendToTarget(); }Android TV 中要求有些操作时间不能过长,例如onRelease,通过这样的操作就成功避免了