您的位置:首页 > 移动开发 > Android开发

Android 多线程操作之 Handler 与 HandlerThread

2014-05-05 18:27 330 查看
1. Handler操作


Handler主要用于执行消息队列的传送与runnable线程;消息队列用于多线程。注:Handler操作实际与UI主线程是一个线程,虽然主要操作在Runnable中,但是其实它与UI主线程是一个线程。

1) 创建一个Handler对象:Handler handler = new Handler();

2) 调用Handler对象的post方法,将要执行的对象添加到队列中:handler.post(runnable线程);

3) 将要执行的操作写在线程对象run方法中:

privateRunnable runnable = new Runnable(){

public void run(){

//相关业务操作

}

}

4) 若要循环执行操作,可在run()方法中执行handler对象的postDelayed方法。

代码演示:

[java] view
plaincopy

package com.example.handlertest;

import android.app.Activity;

import android.os.Bundle;

import android.os.Handler;

import android.os.Message;

import android.util.Log;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

import android.widget.ProgressBar;

/**

* Handler的演示操作,演示Handler的运行机制

* */

public class HandlerActivity extends Activity {

//进度条

private ProgressBar pb_handler = null;

//开始按钮

private Button btn_start = null;

//结束按钮

private Button btn_end = null;

private final static String TAG = "TEST";

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

pb_handler = (ProgressBar)findViewById(R.id.pb_handler);

btn_start = (Button)findViewById(R.id.btn_start);

Log.i(TAG, "UI主线程ID为 "+Thread.currentThread().getId());

btn_start.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

//将要执行的Runnable对象添加到消息队列中

handler.post(runtestHandler);

}

});

btn_end = (Button)findViewById(R.id.btn_end);

btn_end.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

//将正在执行的Runnable对象从消息队列移除

handler.removeCallbacks(runtestHandler);

}

});

}

private int i = 0;

private Handler handler = new Handler(){

@Override

public void handleMessage(Message msg) {

super.handleMessage(msg);

//接收Runnable操作中发过来的消息信息,改变进度条的长度

pb_handler.setProgress(msg.arg1);

}

};

private Runnable runtestHandler = new Runnable() {

@Override

public void run() {

i += 5;

Log.i(TAG, "Handler所在线程ID为 "+Thread.currentThread().getId());

Log.i(TAG, "数字="+i);

//得到一个消息

Message msg = handler.obtainMessage();

//给消息赋值,arg1与arg2主要是一些简单的int数据,优点是消耗的资源少

msg.arg1 = i;

//发送消息,自动将消息赋值给Handler对象对应的HandlerMessage中Message对象

handler.sendMessage(msg);

handler.postDelayed(runtestHandler, 1000);

}

};

}

2. HandlerThread操作


Handler类既然不是新开了一个线程,必然一些操作如大数据或网络下载操作之类的就不能仅仅用Handler,针对这种情况,出现了HandlerThread类,该类用于方便的创建一个含有looper的线程类,通过此类实现多线程操作。注意:looper用来创建handler类。并且必须调用start()方法。

将上面的demo修改为HandlerThread 多线程,演示Demo如下:

[java] view
plaincopy

import android.app.Activity;

import android.os.Bundle;

import android.os.Handler;

import android.os.HandlerThread;

import android.os.Looper;

import android.os.Message;

import android.util.Log;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

import android.widget.ProgressBar;

/**

* HandlerThread的演示操作

* 演示HandlerThread与Handler配合使用,实现多线程的运行机制

* 同时包含Message各种消息形式的演示

* */

public class HandlerThreadActivity extends Activity {

//进度条

private ProgressBar pb_handler = null;

//开始按钮

private Button btn_start = null;

//结束按钮

private Button btn_end = null;

private final static String TAG = "TEST";

private HandlerThread handlerThead = null;

private ProgressBarHandler handler = null;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

pb_handler = (ProgressBar)findViewById(R.id.pb_handler);

btn_start = (Button)findViewById(R.id.btn_start);

Log.i(TAG, "UI主线程ID为 "+Thread.currentThread().getId());

//new一个handlerThead对象

handlerThead = new HandlerThread("handlerThead");

//必须调用

handlerThead.start();

btn_start.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

handler = new ProgressBarHandler(handlerThead.getLooper());

//将要执行的Runnable对象添加到消息队列中

handler.post(runtestHandler);

}

});

btn_end = (Button)findViewById(R.id.btn_end);

btn_end.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

//将正在执行的Runnable对象从消息队列移除

handler.removeCallbacks(runtestHandler);

}

});

}

private int i = 0;

/**

* 内部类,用于Looper与Handler配合实现多线程操作,Looper轮训机制

* */

class ProgressBarHandler extends Handler{

public ProgressBarHandler(){

}

public ProgressBarHandler(Looper looper){

super(looper);

}

@Override

public void handleMessage(Message msg) {

super.handleMessage(msg);

//接收Runnable操作中发过来的消息信息,改变进度条的长度

pb_handler.setProgress(msg.arg1);

//接收推送过来的消息中的Bundle信息

Bundle bundle = msg.getData();

Log.i(TAG, "Message通过Bundle传过来的内容:"+bundle.getString("str0"));

Log.i(TAG, "Message通过Bundle传过来的内容:"+bundle.getString("str1"));

switch(msg.what){//接收自定义的消息值

case R.id.btn_end:{//此处仅是测试,下面这段代码会让进度条停止,进度条只前进一次

handler.removeCallbacks(runtestHandler);

Log.i(TAG, "此处是接收自定义消息信息");

}

}

}

};

private Runnable runtestHandler = new Runnable() {

@Override

public void run() {

i += 5;

Log.i(TAG, "采用HandlerThread后Handler所在线程ID为 "+Thread.currentThread().getId());

Log.i(TAG, "数字="+i);

//得到一个消息

Message msg = handler.obtainMessage();

//给消息赋值,arg1与arg2主要是一些简单的int数据,优点是消耗的资源少

msg.arg1 = i;

//创建一个Bundle对象

Bundle bundle = new Bundle();

bundle.putString("str0", "data 1");

bundle.putString("str1", "data 2");

msg.setData(bundle);

//msg.what自定义的消息值,这个东东在开发中经常使用

msg.what = R.id.btn_end;

//发送消息,自动将消息赋值给Handler对象对应的HandlerMessage中Message对象

msg.sendToTarget();

handler.postDelayed(runtestHandler, 1000);

}

};

}











总结,通过学习HandlerThread与Handler,可以方便的操作一些多线程,便于UI界面等友好性设计。











备注:以上学习来自mars老师的教学视频和android sdk一些资料,欢迎大家查看。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: