Android使用Handler实现子线程与子线程、主线程之间通信
2017-01-15 14:13
651 查看
今天这篇文章只讲一下怎么使用Handler实现子线程与子线程之间、子线程与主线程之间如何进行通信,关于具体的内部实现因为我也没研究过,所以这篇文章讲不了。
一、子线程向主线程传值:
这个实现比较简单,因为主线程自带Looper机制,所有我们不用创建Looper了,看一下代码吧:
首选在主线程里创建一个Handler
然后开启一个子线程,在子线程里直接使用Handler发送消息即可
二、主线程向子线程里发送消息:
主线程向子线程发送消息的话,我们需要在子线程里初始化Looper,并在主线程里创建的Handler引用子线程的Looper(Handler中引用的是哪个线程的Looper,就在哪个线程里处理消息),下面看代码:
其实这样就可以达到主线程向子线程发送消息了,然而当我们运行后发现程序会Crash掉,报了一个控制针,这是因为在Handler初始化的时候,thread.looper还没有初始化,所以会报控制针,这时我们可以让主线程等待一下子线程,也可以来一个while循环来判断thread.looper是否初始化完成。不过Android本身还提供了一个方法,那就是HandlerThread:
这时HandlerMessage所在的线程就是HandlerThread 的子线程。
然而HandlerThread 所创建处理的子线程里是不能重写Run()方法的,你写了以后,会发现,HandlerMessage不执行了,这时因为HandlerMessage本身实现了Run()方法,我们看一下内部实现:
在源代码的第4行,进行了实例化自己的Looper,如果继续追踪源代码翻看其getLooper方法你会发现,如果一个Handler在与HandlerThread进行绑定时,发现Looper为空,Handler则会一直等待直到Looper被创建出来为止,然后才继续执行后续的代码。所以我们重写了HandlerThread的run方法,肯定就不会去创建Looper对象,那么绑定的Handler就会永远处于等待状态,自然而然就不会执行到HandlerMessage信息了。这也是为什么我们要使用HandlerThread这个特殊的线程,因为使用这个,我们不必关心多线程会混乱,Looper会为空等一系列问题,只要去关心我们要实现的逻辑就行了。
三、子线程和子线程之间通信:
其实子线程向子线程之间通信,其实就是在一个子线程中创建一个Handler,它的回调自然就在此子线程中,然后在另一个子线程中调用此handler来发送消息就可以了,不过记得写上Looper哦,下面看代码:
其中 Looper.prepare()和Looper.loop()一定不要忘了写。
然后我们创建第二个子线程
一、子线程向主线程传值:
这个实现比较简单,因为主线程自带Looper机制,所有我们不用创建Looper了,看一下代码吧:
首选在主线程里创建一个Handler
1.Handler mHandler = new Handler(){ 2. 3. @Override 4. public void handleMessage(Message msg) { 5. super.handleMessage(msg); 6. switch (msg.what) { 7. case 0: 8. //do something,refresh UI; 9. break; 10. default: 11. break; 12. } 13. } 14. 15.};
然后开启一个子线程,在子线程里直接使用Handler发送消息即可
new Thread() { public void run() { Message message = new Message(); message.obj = "子线程发送的消息Hi~Hi"; mHandler .sendMessage(message); }; }.start();
二、主线程向子线程里发送消息:
主线程向子线程发送消息的话,我们需要在子线程里初始化Looper,并在主线程里创建的Handler引用子线程的Looper(Handler中引用的是哪个线程的Looper,就在哪个线程里处理消息),下面看代码:
public class ThreadHandlerActivity extends Activity{ //创建子线程 class MyThread extends Thread{ private Looper looper;//取出该子线程的Looper public void run() { Looper.prepare();//创建该子线程的Looper looper = Looper.myLooper();//取出该子线程的Looper Looper.loop();//只要调用了该方法才能不断循环取出消息 } } private Handler mHandler;//将mHandler指定轮询的Looper protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); thread = new MyThread(); thread.start();//千万别忘记开启这个线程 //下面是主线程发送消息 mHandler = new Handler(thread.looper){ public void handleMessage(android.os.Message msg) { Log.d("当前子线程是----->",Thread.currentThread()+""); }; }; mHandler.sendEmptyMessage(1); } }
其实这样就可以达到主线程向子线程发送消息了,然而当我们运行后发现程序会Crash掉,报了一个控制针,这是因为在Handler初始化的时候,thread.looper还没有初始化,所以会报控制针,这时我们可以让主线程等待一下子线程,也可以来一个while循环来判断thread.looper是否初始化完成。不过Android本身还提供了一个方法,那就是HandlerThread:
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); tv = new TextView(this); tv.setText("Handler实验"); setContentView(tv); //实例化一个特殊的线程HandlerThread,必须给其指定一个名字 HandlerThread thread = new HandlerThread("handler thread"); thread.start();//千万不要忘记开启这个线程 //将mHandler与thread相关联 mHandler = new Handler(thread.getLooper()){ public void handleMessage(android.os.Message msg) { Log.d("当前子线程是----->", Thread.currentThread()+""); }; }; mHandler.sendEmptyMessage(1);//发送消息 }
这时HandlerMessage所在的线程就是HandlerThread 的子线程。
然而HandlerThread 所创建处理的子线程里是不能重写Run()方法的,你写了以后,会发现,HandlerMessage不执行了,这时因为HandlerMessage本身实现了Run()方法,我们看一下内部实现:
@Override public void run() { mTid = Process.myTid(); Looper.prepare(); synchronized (this) { mLooper = Looper.myLooper(); notifyAll(); } Process.setThreadPriority(mPriority); onLooperPrepared(); Looper.loop(); mTid = -1; }
在源代码的第4行,进行了实例化自己的Looper,如果继续追踪源代码翻看其getLooper方法你会发现,如果一个Handler在与HandlerThread进行绑定时,发现Looper为空,Handler则会一直等待直到Looper被创建出来为止,然后才继续执行后续的代码。所以我们重写了HandlerThread的run方法,肯定就不会去创建Looper对象,那么绑定的Handler就会永远处于等待状态,自然而然就不会执行到HandlerMessage信息了。这也是为什么我们要使用HandlerThread这个特殊的线程,因为使用这个,我们不必关心多线程会混乱,Looper会为空等一系列问题,只要去关心我们要实现的逻辑就行了。
三、子线程和子线程之间通信:
其实子线程向子线程之间通信,其实就是在一个子线程中创建一个Handler,它的回调自然就在此子线程中,然后在另一个子线程中调用此handler来发送消息就可以了,不过记得写上Looper哦,下面看代码:
new Thread(new Runnable() { @Override public void run() { String msg; Looper.prepare(); childHandler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); System.out.println("这个消息是从-->>" + msg.obj+ "过来的,在" + "btn的子线程当中" + "中执行的"); } }; Looper.loop();//开始轮循 } }).start();
其中 Looper.prepare()和Looper.loop()一定不要忘了写。
然后我们创建第二个子线程
new Thread(new Runnable() { @Override public void run() { Looper loop = Looper.myLooper(); Message msg = childHandler.obtainMessage(); msg.obj = "btn2当中子线程"; childHandler.sendMessage(msg); } }).start();
相关文章推荐
- Android 使用handler实现线程间发送消息 (主线程 与 子线程之间)、(子线程 与 子线程之间)
- Android 使用handler实现线程间发送消息 (主线程 与 子线程之间)、(子线程 与 子线程之间)
- Android之用Handler实现主线程和子线程互相通信以及子线程和子线程之间的通信
- ArrayList 和数组之间的一些转换 Handler的主线程与子线程通信 内部类的使用
- 使用Handler实现主线程与子线程之间互相传递消息
- ArrayList和数组之间的一些转换 Handler的主线程与子线程通信 内部类的使用
- Android笔记(三十二) Android中线程之间的通信(四)主线程给子线程发送消息
- Android:使用Handler在线程之间通信
- Android--Handler(承担着子线程和主线程之间的通信)
- Android的消息机制,用Android线程间通信的Message机制,Android中Handler的使用方法——在子线程中更新界面,handler机制
- Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面
- Android的消息机制,用Android线程间通信的Message机制,Android中Handler的使用方法——在子线程中更新界面,handler机制
- 远程服务实现android系统中的线程之间的通信
- Android的消息机制,用Android线程间通信的Message机制,Android中Handler的使用方法——在子线程中更新界面,handler机制
- Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面 .
- Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面
- Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面 .
- Android的消息机制,用Android线程间通信的Message机制,Android中Handler的使用方法——在子线程中更新界面,handler机制
- android 实现主线程、子线程双向通信
- Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面