标签:
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() {
public void handleMessage(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
*
*/
public class ThridActivity extends Activity {
private String TAG = getClass().getSimpleName();
private TextView mView;
private MyThread mThread;
/**
* 创建一个默认的Handler
*/
private Handler mHandler = new Handler() {
public void handleMessage(android.os.Message msg) {
Log.d(TAG, "-------UI Thread:" + Thread.currentThread().getId());
mView.setText("你好");
};
};
@Override
protected void onCreate(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);
}
private void init() {
mView = (TextView) findViewById(R.id.textView1);
}
/**
* 自定义的Thread
*
* @author scd
*
*/
public class MyThread extends Thread {
public Handler myHandler;
@Override
public void run() {
Looper.prepare();
myHandler = new Handler() {
@Override
public void handleMessage(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
*
*/
public class FourActivity extends Activity {
private String TAG = getClass().getSimpleName();
private String mName = "HandlerThread";
private HandlerThread mThread;
private Handler mHandler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 封装类
mThread = new HandlerThread(mName);
// 开启线程
mThread.start();
// 方式一:Handler是在子线程
mHandler = new Handler(mThread.getLooper()) {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
Log.d(TAG, "---子线程----HandlerThread :"
+ Thread.currentThread().getId());
}
};
// 方式二:Handler是在主线程
mHandler = new Handler() {
@Override
public void handleMessage(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
*
*/
public class FiveActivity extends Activity implements OnClickListener {
private String TAG = getClass().getSimpleName();
private String mName = "HandlerThread";
// 初始化主线程的Handler
private Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
Message message = new Message();
// 主线程发送给子线程消息
mThreadHandler.sendMessageDelayed(message, 1000);
Log.d(TAG, "-------->主线程发送给子线程消息");
};
};
// 子线程对象
private HandlerThread mThread;
// 子线程的Handler
private Handler mThreadHandler;
private Button mButton1;
private Button mButton2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
}
/**
* init the View
*/
private void init() {
mButton1 = (Button) findViewById(R.id.button1);
mButton2 = (Button) findViewById(R.id.button2);
mButton1.setOnClickListener(this);
mButton2.setOnClickListener(this);
// 初始化子线程的Handler
mThread = new HandlerThread(mName);
mThread.start();
// 初始化子线程中的Handler
mThreadHandler = new Handler(mThread.getLooper()) {
@Override
public void handleMessage(Message msg) {
Message message = new Message();
mHandler.sendMessageDelayed(message, 1000);
Log.d(TAG, "-------->子线程发送给主线程消息");
}
};
Log.d(TAG, "------->init主线程");
}
@Override
public void onClick(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的原理(附源码)
标签:
原文地址:http://blog.csdn.net/u014225510/article/details/47069481