Android的多线程与异步任务2-Handler

一、用handler-异步时或不可缺的组件
1.使用多线程时遇到的问题
2.我想和UI进行交互,但是每次都创建Runnable看起来很别扭,而且代码很难管理
3.我的程序中需要不断的加载更新的数据,我应该怎么确保数据的正确性?
4.用户快速 的点击按钮,我的程序无法有足够快的响应,应该怎么办?
二、什么是Handler及其作用(Handlder一定在主线程吗?)
Message
MessageQueue
looper
1)执行计划任务,你可以再预定的实现执行某些任务,可以模拟定时器
2)线程间通信。在Android的应用启动时,会创建一个主线程,主线程会创建一个消息队列来处理各种消息。当你创建子线程时,你可以在你的子线程中拿到父线程中创建的Handler对象,就可以通过该对象向父线程的消息队列发送消息了。由于Android要求在UI线程中更新界面,因此,可以通过该方法在其它线程中更新界面。
3)确保操作始终在某个特定的线程中运行。例如当我们从数据库加载数据时,除了程序启动时需要加载外,每当我们收到数据改变的通知时也需要重新加载。为了确保数据的有效性(始终使用最后一次查询时得到的数据),并减少不必要的查询操作,我们应当确保他们在同一个线程中运行。


角色描述
1.Looper(相当于隧道)一个线程可以产生一个Looper对象,由它来管理此线程里的Message Queue(车队,消息隧道)。
2.Handler:你可以构造Handler对象来与Looper沟通,以便Push新消息到Message Queue里,或者接收Looper(从Message Queue取出)所送来的消息。
3.Message Queue(消息队列):用来存放线程放入的消息。
4.线程:UI thread通常就是main thread,而Android启动程序时会替它建立一个Message Queue。


三、几个问题
1.多个Handler使用同一个HandlerThread
a.同一个HandlerThread中可以有多个Handler
b.同一个HandlerThread中使用多个Handler的Messsage不会混浴。
2.Handler可以创建到任意线程中吗?
a.在普通的Thread中不可以调用new Handler()创建并发送消息
b.在HandlerThread.onLooperPreapared()中可以调用new Handler创建并发送消息
3.如何指定Handler运行的线程
4.同一个Handler中不同的消息会同时执行吗?(不会,因为它是基于队列机制的)
a,定义两条有耗时操作的Message,并同时发送这两条消息。
b,现定义一个Runnable,尝试同时执行Message和Runnable。
5.当Handler正在运行的时候,调用removeMessage会有什么后果?
a.调用removeMessage一个还没有开始执行的Message,会直接移除掉这个未执行的Message
b.移除一个正在执行的message,这个message仍然会执行完。
总结:
1.Handler实例与消息处理是关联的,发送和接收要匹配。
2.只能依附在HandlerThread
3.可以通过设置Looper来选择其依赖的线程
4.所有操作都是在用一个线程中

5.removeMessage只能移除队列中的Message


四,代码

1.定义layout

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >


    <Button
        android:id="@+id/button_handler1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="handler_laebl_1" />


    <Button
        android:id="@+id/button_handler2_1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="handler_laebl_2.1" />


    <Button
        android:id="@+id/button_handler2_2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="handler_laebl_2.2" />


    <Button
        android:id="@+id/button_handler3_1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="handler_laebl_3.1" />


    <Button
        android:id="@+id/button_handler4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="handler_laebl_4" />
    
    <Button
        android:id="@+id/button_handler5_1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="handler_laebl_5.1" />
    
    <Button
        android:id="@+id/button_handler5_2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="handler_laebl_5.2_remove" />


</LinearLayout>


2.在java中使用Handler

package com.douzi.treaddemo;


import android.R.drawable;
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.Toast;


public class HandlerActivity extends Activity {
Handler mainHandler01;
Handler mainHandler02;

//定义一个HandlerThread
class SubHandlerThead extends HandlerThread{
public SubHandlerThead(String name){
super(name);
}
@Override
protected void onLooperPrepared() {
// TODO Auto-generated method stub

Looper looper = this.getLooper();

new Handler(looper){
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
Log.i("douzi", "在HandlerThread中获得消息:"+msg.getData().getString("key"));
}
}.sendMessage(difineNewMessage("label2.2"));
}
}

class DelayHandler extends Handler{
public DelayHandler(Looper looper){
super(looper);
}

@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
Log.i("douzi", "开始消息:"+msg.getData().getString("key"));
try {
Thread.sleep(5* 1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.i("douzi", "结束消息:"+msg.getData().getString("key"));
}
}


@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_handler);


mainHandler01 = new Handler() {
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
Toast.makeText(HandlerActivity.this, "[主线程]Handler1获得消息:" + msg.getData().getString("key"), 3000)
.show();
}
};


mainHandler02 = new Handler() {
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
Toast.makeText(HandlerActivity.this, "[主线程]Handler2获得消息:" + msg.getData().getString("key"), 3000)
.show();
}
};


//1.多个Handler使用同一个HandlerThread
//a.同一个HandlerThread中可以有多个Handler
//b.同一个HandlerThread中使用多个Handler的Messsage不会混浴。
findViewById(R.id.button_handler1).setOnClickListener(new OnClickListener() {


@Override
public void onClick(View v) {
// TODO Auto-generated method stub
new Thread(new Runnable() {


@Override
public void run() {
// TODO Auto-generated method stub
// mainHandler01.sendMessage(difineNewMessage("label"));


mainHandler02.sendMessage(difineNewMessage("label"));
}
}).start();
}
});


//在普通的Thread中不可以调用new Handler()创建并发送消息
findViewById(R.id.button_handler2_1).setOnClickListener(new OnClickListener() {


@Override
public void onClick(View v) {
// TODO Auto-generated method stub
new Thread(new Runnable() {


@Override
public void run() {
// TODO Auto-generated method stub
//在主线程中是可以执行的
//Handler handler = new Handler(Looper.getMainLooper());
//在普通线程不可以创建Handler
Handler handler = new Handler();
handler.sendMessage(difineNewMessage("label"));
}
}).start();
}
});

//在HandlerThread.onLooperPreapared()中可以调用new Handler创建并发送消息
findViewById(R.id.button_handler2_2).setOnClickListener(new OnClickListener() {


@Override
public void onClick(View v) {
// TODO Auto-generated method stub
SubHandlerThead subHandlerThead = new SubHandlerThead("theadone");
subHandlerThead.start();
}
});

//在HandlerThread.onLooperPreapared()中可以调用new Handler创建并发送消息
findViewById(R.id.button_handler3_1).setOnClickListener(new OnClickListener() {


@Override
public void onClick(View v) {
// TODO Auto-generated method stub
new Thread(new Runnable() {

@Override
public void run() {
// TODO Auto-generated method stub
Handler handlerLable3 = new Handler(Looper.getMainLooper()){
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
Log.i("douzi", "获得消息:"+msg.getData().getString("key")+"在子线程中被处理。");
}
};
handlerLable3.sendMessage(difineNewMessage("label3"));
Looper.loop();
}
}).start();
}
});

//定义两条有耗时操作的Message,不会同时执行,会按先进先出的方式执行。
findViewById(R.id.button_handler4).setOnClickListener(new OnClickListener() {


@Override
public void onClick(View v) {
// TODO Auto-generated method stub
HandlerThread labe4Thread = new HandlerThread("lab4_thread");
labe4Thread.start();
Handler lab4Handler = new DelayHandler(labe4Thread.getLooper());
lab4Handler.sendMessage(difineNewMessage("lab4 A"));
lab4Handler.sendMessage(difineNewMessage("lab4 B"));
}
});

HandlerThread lab5Thread = new HandlerThread("lab5_thread");
lab5Thread.start();
final Handler lab5Handler = new DelayHandler(lab5Thread.getLooper());
//
findViewById(R.id.button_handler5_1).setOnClickListener(new OnClickListener() {


@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Message message = difineNewMessage("lab5");
message.what = 1;
lab5Handler.sendMessage(message);
}
});

findViewById(R.id.button_handler5_2).setOnClickListener(new OnClickListener() {


@Override
public void onClick(View v) {
// TODO Auto-generated method stub
lab5Handler.removeMessages(1);
}
});
}


private Message difineNewMessage(String label) {
Message s = new Message();
Bundle bundle = new Bundle();
bundle.putString("key", label);
s.setData(bundle);
return s;
}
}







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值