java handler使用方法_Handler 使用详解

Handler 消息处理机制原理

Handler 机制处理的4个关键对象

Handler常用方法

子线程更新UI 异常处理

主线程给子线程发送消息的方法

子线程给主线程发送消息的方法

子线程方法中调用主线程更新UI的方法

Handler是 Android中用来更新UI 的一套消息处理机制。Handler 允许线程间发送Message或Runnable对象进行通信。在Android中UI修改只能通过UI Thread,子线程不能更新UI。如果子线程想更新UI,需要通过 Handler发送消息给主线程,进而达到更新UI的目的。

Handler 简介

继承关系如下:

java.lang.Object

↳ android.os.Handler

1. Handler 消息处理机制原理

当Android 应用程序创建的时候,系统会给每一个进程提供一个Looper,Looper 是一个死循环,它内部维护一个消息队列,Looper不停的从消息队列中取Message,取到的消息就发送给handler,最后Handler 根据接收的消息去修改UI等。

2. Handler 机制处理的4个关键对象

1.Message

线程之间传递的消息,可以携带一些简单的数据供子线程与主线程进行交换数据。

2.Message Queue

存放通过Handler 发送的Message 的消息队列,每一个线程只有一个消息队列。

3.Handler

消息处理者,主要用于发送跟处理消息。

主要功能:

发送消息SendMessage()

处理消息 HandleMessage()

4.Looper

内部包含一个死循环的MessageQueue,用于存储handler发送的Message,Looper则是不断的从消息队列中取消,如果有消息就取出发送给Handler 处理,没有则阻塞。

总结:

Handler负责发送Message到Message Queue,Looper负责从Message Queue 遍历Message ,然后直接把遍历的消息回传给Handler自己,通过Handler自身的handleMessage处理更新UI等操作。

3. Handler常用方法

1.Runnable对象

post(Runnable)

使用方法举例:

public void BtnRunnableMethod(View view) {
// 1.Runnable 对象

RunnableHandlderMethod();

}

/**

* Runnable 对象更新 UI

* **/

private Handler mRunnableHandler = new Handler();

public void RunnableHandlderMethod() {
new Thread() {
@Override

public void run() {
try {
Thread.sleep(1000);

mRunnableHandler.post(new Runnable() {
@Override

public void run() {
((Button) findViewById(R.id.btn_runnable))

.setText("Runnable");

}

});

} catch (InterruptedException e) {
e.printStackTrace();

}

}

}.start();

}

postAtTime(Runnable, long)

postDelayed(Runnable, long)

2. Message 对象

sendEmptyMessage(int)

使用方法举例:

public void BtnMessageThreadMethod(View view) {
// 2.Message 对象

new MessageHandlerThreadMethod("子线程不能更新UI").start();

}

/**

* Message 对象举例

* ***/

private int mCount = 0;

private Handler mMessageHandler = new Handler() {
@Override

public void handleMessage(Message msg) {
super.handleMessage(msg);

((Button) findViewById(R.id.btn_thread)).setText("" + mCount);

}

};

class MessageHandlerThreadMethod extends Thread {
String mString;

public MessageHandlerThreadMethod(String str) {
mString = str;

}

@Override

public void run() {
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(1000);

} catch (Exception e) {
}

mCount++;

mMessageHandler.sendEmptyMessage(0);

}

}

}

sendMessage(Message)

使用方法举例:

public void BtnMessageObjMethod(View view) {
HandlerMessageObjMethods();

}

/***

* handler sendmessage 处理方法

* **/

private Handler mHandlerMessageObj = new Handler() {
@Override

public void handleMessage(Message msg) {
((Button) findViewById(R.id.btn_message)).setText("arg1:"

+ msg.arg1 + "\n" + msg.obj);

}

};

private void HandlerMessageObjMethods() {
new Thread() {
@Override

public void run() {
try {
Thread.sleep(1000);

// Message message = new Message();

Message message = mHandlerMessageObj.obtainMessage();

message.arg1 = 100;

Person person = new Person();

person.name = "Lucy";

person.age = 12;

message.obj = person;

mHandlerMessageObj.sendMessage(message);

} catch (InterruptedException e) {
e.printStackTrace();

}

}

}.start();

}

class Person {
public int age;

public String name;

public String toString() {
return "Name=" + name + "\n Age=" + age;

}

}

sendMessageAtTime(Message, long),

sendMessageDelayed(Message, long)

3.接收、处理Message

handleMessage(Message)

使用方法举例:

private Handler mMessageHandler = new Handler() {
@Override

public void handleMessage(Message msg) {
super.handleMessage(msg);

((Button) findViewById(R.id.btn_thread)).setText("" + mCount);

}

};

4. 子线程更新UI 异常处理

子线程不能更新UI,如果在子线程中更新UI,会出现CalledFromWrongThreadException 异常。

CalledFromWrongThreadException

解决方法:

子线程通过Handler发送消息给主线程,让主线程处理消息,进而更新UI。

5. 主线程给子线程发送消息的方法

此例子中子线程通过Looper不断遍历主线程发送的消息,Looper使用方法如下:

准备Looper 轮询器

Looper.prepare();

Handler 处理遍历消息

Handler mHandler = new Handler()

遍历消息队列

Looper.loop();

Looper 使用方法如下:

// 自定义 Loop 线程 ---> 不停的处理主线程发的消息

class ChildLooperThread extends Thread {
@Override

public void run() {
// 1.准备成为loop线程

Looper.prepare();

// 2.处理消息

mMainHandler = new Handler() {
// 处理消息

public void handleMessage(Message msg) {
super.handleMessage(msg);

... ...

}

});

}

};

// 3.Loop循环方法

Looper.loop();

}

}

主线程发送消息给子线程 的使用例子如下:

启动 子线程,并再启动后发送消息

public void BtnMainMessageMethod(View view) {
// 点击主线程 按钮,启动子线程,并在子线程启动后发送消息

Message msg = new Message();

msg.obj = "主线程:这是我携带的信息";

if (mMainHandler != null) {
// 2.主线程发送消息

mMainHandler.sendMessage(msg);

} else {
Toast.makeText(getApplicationContext(), "开启子线程轮询消息,请再次点击发送消息",

Toast.LENGTH_SHORT).show();

// 1.开启轮询线程,不断等待接收主线成消息

new ChildLooperThread().start();

}

}

子线程启动,不停的变量主线程发送的消息

private Handler mMainHandler;

String mMainMessage;

// 自定义 Loop 线程 ---> 不停的处理主线程发的消息

class ChildLooperThread extends Thread {
@Override

public void run() {
// 1.准备成为loop线程

Looper.prepare();

// 2.处理消息

mMainHandler = new Handler() {
// 处理消息

public void handleMessage(Message msg) {
super.handleMessage(msg);

mMainMessage = (String) msg.obj;

Log.i("TAG", "子线程:从主线程中接受的消息为:\n" + mMainMessage);

// 使用 runOnUiThread 在主线程中更新UI

runOnUiThread(new Runnable() {
@Override

public void run() {
((Button) findViewById(R.id.btn_main_message))

.setText(mMainMessage);

}

});

}

};

// 3.Loop循环方法

Looper.loop();

}

}

6. 子线程给主线程发送消息的方法

1.子线程发送消息给主线程方法

public void BtnChildMessageMethod(View view) {
new Thread() {
public void run() {
while (mCount < 100) {
mCount++;

try {
Thread.sleep(100);

} catch (InterruptedException e) {
// TODO Auto-generated catch block

e.printStackTrace();

}

/**

* 利用handler 对象发送消息 Message msg=Message.obtain(); Message

* msg=new Message(); 获取一个消息对象message

* */

Message msg = Message.obtain();

// 消息标记

msg.what = 1;

// 传递整型值msg.obj="传递object数据"

msg.arg1 = mCount;

Log.i("TAG", "count 值=" + mCount);

if (mhandler != null) {
mhandler.sendMessage(msg);

}

}

}

}.start();

}

2.主线程接收并处理消息的方法

// 定义一个handler 主线程 接收子线程发来的信息

private Handler mhandler = new Handler() {
// 處理消息的方法

public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case 1:

int value = msg.arg1;

Log.i("TAG", "value值=" + value);

((Button) findViewById(R.id.btn_child_message)).setText("当前值="

+ value);

break;

default:

break;

}

}

};


 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值