概述:
Handler 是Android Sdk封装好的一个线程间消息处理(通信)的一个类。在android中比较典型的应用就是异步加载数据,主线程更新ui(这种模式是由android操作系统所决定),虽然说在android开发中利用hanlder更新ui比较常用,但其本质上解决的还是线程间通信问题,我们完全也可以通过Hanlder实先多线程间协同工作问题。
例子1:主线程更新ui
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.widget.TextView;
public class HandlerActivity extends AppCompatActivity {
private TextView tvContent;
private Handler mHandler ;
private boolean isEnd = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_handler);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//实例化TextView和mHanlder
tvContent = (TextView) findViewById(R.id.tv_content);
mHandler= new Handler(){
@Override
public void handleMessage(Message msg) {
//主线程处理ui
tvContent.setText((String)msg.obj);
}
};
}
public void startThreadWork(){
//开启子线程模拟耗时操作
new Thread(){
@Override
public void run() {
int count =0;
while(!isEnd){
try {
//线程休眠,模拟耗时操作
sleep(1000);
}catch (InterruptedException e){
e.printStackTrace();
}
Message message = Message.obtain();
message.obj ="您好"+count;
mHandler.sendMessage(message);
count++;
}
}
}.start();
}
@Override
protected void onDestroy() {
mHandler.removeCallbacksAndMessages(null);
isEnd = true;
super.onDestroy();
}
}
布局文件:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.weiwei.testjni.HandlerActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<TextView
android:textSize="28sp"
android:id="@+id/tv_content"
android:layout_gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:padding="16dp"
/>
</android.support.design.widget.CoordinatorLayout>
运行结果:
除了通过调用Hanlder.sendMessage()方法外,也可以通过调用Hanlder.post方法传递更新消息,列子如下。
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.widget.TextView;
public class HandlerActivity extends AppCompatActivity {
private TextView tvContent;
private Handler mHandler ;
private boolean isEnd = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_handler);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//实例化TextView和mHanlder
tvContent = (TextView) findViewById(R.id.tv_content);
mHandler = new Handler();
//开启子线程模拟耗时操作
startThreadWork();
}
int count =0;
public void startThreadWork(){
//开启子线程模拟耗时操作
new Thread(){
@Override
public void run() {
while(!isEnd){
try {
//线程休眠,模拟耗时操作
sleep(1000);
}catch (InterruptedException e){
e.printStackTrace();
}
mHandler.post(new Runnable() {
@Override
public void run() {
tvContent.setText("您好"+count);
}
});
count++;
}
}
}.start();
}
@Override
protected void onDestroy() {
mHandler.removeCallbacksAndMessages(null);
isEnd = true;
super.onDestroy();
}
}
说明:当在主线程实例化一个Handler后,会自动将主线程Looper绑定到Handler上(主线程looper是在应用启动的时候生成),当调用发送message的方法时,便会将messager添加到Looper维护的一个消息队列上,而主线程的Looper.looper方法则会遍历将message取出来,并调用message的分发处理方法。也就是在主线程实例化Handler的HandlerMessager方法。
例子2:三个子线程模拟生产者消费者
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.widget.TextView;
public class HandlerActivity extends AppCompatActivity {
private Handler mHanlder1;
private Handler mHanlder2;
private static final String TAG = "HandlerActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_handler);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//开启两个消费子线程
startThreadWork1();
startThreadWork2();
//开启一个生成子线程
startThreadWork();
}
public void startThreadWork1(){
new Thread("ConsumThread1"){
@Override
public void run() {
Looper.prepare();
mHanlder1 = new Handler(){
@Override
public void handleMessage(Message msg) {
try {
//线程休眠,模拟消费时间
sleep(500);
}catch (InterruptedException e){
e.printStackTrace();
}
Log.d(TAG, "------------------------------------------");
Log.d(TAG, "消费线程名称: "+Thread.currentThread().getName());
Log.d(TAG, "handleMessage: 消费"+(String)msg.obj);
}
};
Looper.loop();
}
}.start();
}
public void startThreadWork2(){
new Thread("ConsumThread2"){
@Override
public void run() {
Looper.prepare();
mHanlder2 = new Handler(){
@Override
public void handleMessage(Message msg) {
try {
//线程休眠,模拟消费时间
sleep(800);
}catch (InterruptedException e){
e.printStackTrace();
}
Log.d(TAG, "------------------------------------------");
Log.d(TAG, "消费线程名称: "+Thread.currentThread().getName());
Log.d(TAG, "handleMessage: 消费"+(String)msg.obj);
}
};
Looper.loop();
}
}.start();
}
int count =0;
public void startThreadWork(){
//开启子线程模拟耗时操作
new Thread("ProuceThread"){
@Override
public void run() {
while(!isEnd){
try {
//线程休眠,模拟生产时间
sleep(500);
}catch (InterruptedException e){
e.printStackTrace();
}
Message message = Message.obtain();
message.obj="生成内容"+count;
Log.d(TAG, "------------------------------------------");
Log.d(TAG, "生产线程名称: "+Thread.currentThread().getName());
Log.d(TAG, "生产内容: "+message.obj);
if(count%2!=0){
mHanlder1.sendMessage(message);
}else{
mHanlder2.sendMessage(message);
}
count++;
}
}
}.start();
}
}
运行结果:
说明:例子2为多线程间通过hanlder传递消息的代码逻辑。但有一点需要说明,这样使用hanlder有可能出现内存泄漏,解决hanlder内存泄漏问题可以参考Hanlder内存泄漏解决。
本文只是描述一下hanlder的基本使用,希望对您有所帮助。