Android中的多线程编程(二)Handler的原理(附源码)

Android中Handler的原理

一.Handler的原理:

1.Handler、Looper、MessageQueue之间的关系。

(1).Handler类:向MessageQueue消息队列中发送消息,接收Looper返回来的消息并处理。

(2).Looper类: 存储消息队列的容器。负责接收Handler发送的消息,并直接把消息回传给Handler自己。

(3).MessageQueue类:存储消息。

2.关系:

(1).创建Handler对象的时候,它就会绑定到默认的线程(UI线程)中,,这个线程中就会有一个消息队列。

private Handler mHandler = new Handler() {(android.os.Message msg) {Log.d(TAG, “主线程 Thread UI:” + Thread.currentThread().getId());mView.setText(“111”);};};

(2).如果是新开启一个子线程,在该线程中操作Handler的时候,就要自己创建一个Looper对象,从而找到相应的消息队列。也就是说Handle和Looper是相互关联的。

package com.chengdong.su.handlerdemo;import android.app.Activity;import android.app.ActionBar;import android.app.Fragment;import android.os.Bundle;import android.os.Handler;import android.os.Looper;import android.os.Message;import android.util.Log;import android.util.SparseArray;import android.view.LayoutInflater;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.view.ViewGroup;import android.widget.ImageView;import android.widget.TextView;import android.widget.Toast;import android.os.Build;/** * * @author scd * */{private String TAG = getClass().getSimpleName();private TextView mView;private MyThread mThread;/*** 创建一个默认的Handler*/private Handler mHandler = new Handler() {(android.os.Message msg) {Log.d(TAG, “——-UI Thread:” + Thread.currentThread().getId());mView.setText(“你好”);};};(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);init();mThread = new MyThread();mThread.start();try {mThread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}// 子线程mThread.myHandler.sendEmptyMessage(0);// 主线程mHandler.sendEmptyMessage(1);}() {mView = (TextView) findViewById(R.id.textView1);}/*** 自定义的Thread** @author scd**/{public Handler myHandler;() {Looper.prepare();myHandler = new Handler() {(Message msg) {super.handleMessage(msg);Log.d(TAG, “——>Thread:”+ Thread.currentThread().getId());System.out.println(“—子线程—-“);}};// 循环处理消息Looper.loop();}}}

但是使用以上的方式会出现多线程并发导致的空指针问题,为了避免这个问题,谷歌给我们封装了一个很好用的类:HandlerThread类。

3.HandlerThread类:

(1).解决多线程并发导致的空指针问题。 HandlerThread的使用代码如下:

package com.chengdong.su.handlerdemo;import android.app.Activity;import android.os.Bundle;import android.os.Handler;import android.os.HandlerThread;import android.os.Message;import android.util.Log;/** * * @author scd * */{private String TAG = getClass().getSimpleName();private String mName = “HandlerThread”;private HandlerThread mThread;private Handler mHandler;(Bundle savedInstanceState) {super.onCreate(savedInstanceState);// 封装类mThread = new HandlerThread(mName);// 开启线程mThread.start();// 方式一:Handler是在子线程mHandler = new Handler(mThread.getLooper()) {(Message msg) {super.handleMessage(msg);Log.d(TAG, “—子线程—-HandlerThread :”+ Thread.currentThread().getId());}};// 方式二:Handler是在主线程mHandler = new Handler() {(Message msg) {super.handleMessage(msg);Log.d(TAG, “—主线程 UI—-HandlerThread :”+ Thread.currentThread().getId());}};mHandler.sendEmptyMessage(0);Log.d(TAG, “—主线程—-UIThread :” + Thread.currentThread().getId());}}

注:方式一中的mHandler是运行在子线程中的,可以在该Handler中处理耗时的异步任务,发送消息,处理消息等。

(2).Android中主线程和子线程之间的通信:

A:子线程发送给主线程消息:让主线程更新UI界面 B:主线程发送给子线程消息:让子线程做相应的逻辑处理。 代码如下:

package com.chengdong.su.handlerdemo;import android.app.Activity;import android.os.Bundle;import android.os.Handler;import android.os.HandlerThread;import android.os.Message;import android.util.Log;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;/** * 主线程和子线程之间进行互相的发送消息,进行通信 * * @author scd * */{private String TAG = getClass().getSimpleName();private String mName = “HandlerThread”;// 初始化主线程的Handlerprivate Handler mHandler = new Handler() {(Message msg) {Message message = new Message();// 主线程发送给子线程消息mThreadHandler.sendMessageDelayed(message, 1000);Log.d(TAG, “——–>主线程发送给子线程消息”);};};// 子线程对象private HandlerThread mThread;// 子线程的Handlerprivate Handler mThreadHandler;private Button mButton1;private Button mButton2;(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);init();}/*** init the View*/() {mButton1 = (Button) findViewById(R.id.button1);mButton2 = (Button) findViewById(R.id.button2);mButton1.setOnClickListener(this);mButton2.setOnClickListener(this);// 初始化子线程的HandlermThread = new HandlerThread(mName);mThread.start();// 初始化子线程中的HandlermThreadHandler = new Handler(mThread.getLooper()) {(Message msg) {Message message = new Message();mHandler.sendMessageDelayed(message, 1000);Log.d(TAG, “——–>子线程发送给主线程消息”);}};Log.d(TAG, “——->init主线程”);}(View v) {switch (v.getId()) {case R.id.button1: {// 主线程发送消息mHandler.sendEmptyMessage(0);break;}case R.id.button2: {// 取消消息mHandler.removeMessages(0);break;}default:break;}}}

如果困难是地上的荆棘,我们脱掉鞋子,光着脚笑笑,

Android中的多线程编程(二)Handler的原理(附源码)

相关文章:

你感兴趣的文章:

标签云: