Android Handler消息传递机制详解(3)

1 public Looper getLooper() { 2 if (!isAlive()) { 3 return null; 4 } 5 6 // If the thread has been started, wait until the looper has been created. 7 synchronized (this) { 8 while (isAlive() && mLooper == null) { 9 try { 10 wait(); 11 } catch (InterruptedException e) { 12 } 13 } 14 } 15 return mLooper; 16 }

    看第8行代码,如果这个线程可用并且looper为null时,就会调用wait()方法,处于等待状态,这样可以有效的避免多线程并发操作引起的空指针异常。在thread启动时,会调用run()方法,再来看看run()方法里面的代码:

1 @Override 2 public void run() { 3 mTid = Process.myTid(); 4 Looper.prepare(); 5 synchronized (this) { 6 mLooper = Looper.myLooper(); 7 notifyAll(); 8 } 9 Process.setThreadPriority(mPriority); 10 onLooperPrepared(); 11 Looper.loop(); 12 mTid = -1; 13 }

  第4行创建了Looper对象,第6、7行获取当前线程Looper之后调用notifyAll()方法。这时调用getLooper()方法返回一个Looper对象。 

  上面有提到使用HandlerThread避免多线程并发操作引起的空指针异常,这里解释下为什么:如果onCreate方法第11行通过程序员自定义的一个新线程创建handler时,很可能出现这样一个结果:创建handler的代码已经执行了,而新线程却还没有Looper.prepare()(创建Looper对象,那么这样就会导致空指针异常)。

  对代码稍做修改:

1 package com.example.administrator.handlertest; 2 3 import android.os.Bundle; 4 import android.os.Handler; 5 import android.os.Looper; 6 import android.os.Message; 7 import android.support.v7.app.ActionBarActivity; 8 import android.util.Log; 9 10 public class MainActivity extends ActionBarActivity { 11 12 private static final String TAG = "MainActivity"; 13 private static final int FLAG_TEST = 1; 14 15 @Override 16 protected void onCreate(Bundle savedInstanceState) { 17 super.onCreate(savedInstanceState); 18 setContentView(R.layout.activity_main); 19 Log.i(TAG,"main thread:"+Thread.currentThread()); 20 // HandlerThread thread = new HandlerThread("handler thread"); 21 // thread.start();//一定要启动该线程 22 MyThread thread = new MyThread(); 23 thread.start(); 24 Handler handler = new Handler(thread.looper){ 25 @Override 26 public void handleMessage(Message msg) { 27 Log.i(TAG,"handler thread:"+Thread.currentThread()); 28 switch (msg.what){ 29 case FLAG_TEST: 30 //耗时操作... 31 break; 32 default: 33 break; 34 } 35 super.handleMessage(msg); 36 } 37 }; 38 handler.sendEmptyMessage(FLAG_TEST); 39 } 40 41 static class MyThread extends Thread{ 42 Looper looper; 43 @Override 44 public void run() { 45 Looper.prepare();looper = Looper.myLooper(); 46 //... 47 Looper.loop(); 48 } 49 } 50 }

运行结果:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/b6d25354526072f57dde4f693ff7632b.html