Android -- 线程通信之AsyncTask、Handler

线程通信方式:
AsyncTask (异步任务)和Handler(句柄)
1、写一个类,继承AsyncTask,然后指定三个泛型
第一个泛型,它是你开启异步任务需要的数据,比如,想要下载图片,就要提供url,
再如,倒计时,你需要指定倒计时多长时间,于是可以是Integer
第二个泛型,它是描述进度的,多以Integer为主,
有时候是float或者double,当然 1,2 0.56,0.78 “吃完饭了”“洗好碗了”
第三个泛型,代表了这个任务的最终目的,
比如,下载图片,最终目的就应该是Bitmap,再如,下载json,它的最终目的是String

2、默认情况下写一个方法的实现,doInBackground 方法
这个方法是后台执行的子线程方法,在这里可以随意去访问网络、耗时操作。但是不可以访问UI

3、其它方法:
onPreExecute 它是在子线程开启之前运行的方法,对于子线程开启之前进行初始化,它是主线程
onPostExecute 它是子线程运行结束后运行的方法,在这里对于子线程访问网络的结果进行设置ui,它是主线程。
onProgressUpdate接到通知之后,具体的更新进度的方法。
publishProgress(progress);在子线程中通知进度发生变化的方法

<————===========—————============>
Handler –句柄:
它是解决线程之间的通信的。它是AsyncTask的底层实现。
为什么安卓要对handler进行封装,封装出一个asynctask?
什么时候用handler?什么时候用asynctask?
解决一些小功能的时候,用handler
解决长时间休眠,用handler
解决涉及线程堵塞的问题,用handler
数据量比较大的时候用asynctask。
Handler负责线程之间的通信,它是如何获取消息对象的呢,一般的,我们都是采用 new 来创建对象。
但是在这里不提倡这样做,我们可以直接获取,方法是:
Message message = Message.obtain();
这个方法会去消息池里面获取消息对象,而消息对象是可以被复用的。但是如果消息池里面没有对象,那么他会实例一个。

//这是给消息对象里面设置一个int值
message.arg1 = 123;
//发送一个消息
handler.sendMessage(message);
在主线程的方法,先实例一个handler;然后写出handlerMessage();方法
// 主线程的一个handler,用于接收、发送消息
private Handler handler = new Handler() {
// 这个方法是当任意一个子线程给这个handler发消息时,消息接收到的时候回调,参数就是消息对象。
public void handleMessage(android.os.Message msg) {
// Message是消息
// 如果消息要携带的信息不复杂,那么用arg1和arg2两个int值来处理,
//
// msg.arg1
// 如果携带的数据是一个比较复杂的数据,那么用obj
// msg.obj Parcelable
Toast.makeText(MainActivity.this, “” + msg.arg1, Toast.LENGTH_LONG).show();
};
};

Handler都有几种形式使得子线程与主线程通信。

1、sendmessage方法,直接发送一个消息,或者发送一个空消息。
2、handler.post方法,传入一个runnable对象,而这个runnable对象的run方法就是主线程,可以更新ui
3、activity封装一个runOnUIThread方法,它是对handler.post的封装,可以直接使用。

子线程之间如何通信?
区别就是获取handler的方式不一样。
要调用Looper.perpare()和Looper.loop()

为什么主线程就可以直接获取,而子线程不行?
子线程默认情况下没有Looper去循环获取信息,这种设计可以理解,为了节省资源,你要是愿意让子线程有loop功能,
就自己去开启。默认的情况下主线程是有这样的功能的。

Handler消息机制:
我们通常将 Handler 声明在 Activity 中,然后覆写 Handler 中的 handleMessage 方法,当子线程调用
handler.sendMessage()方法后 handleMessage 方法就会在主线程中执行。
这里面除了 Handler、Message 外还有隐藏的 Looper 和 MessageQueue 对象。
在主线程中 Android 默认已经调用了 Looper.preper()方法,调用该方法的目的是在 Looper 中创建
MessageQueue 成员变量并把 Looper 对象绑定到当前线程中。当调用 Handler 的 sendMessage(对象)方法的时
候就将 Message 对象添加到了 Looper 创建的 MessageQueue 队列中,同时给 Message 指定了 target 对象,其实
这个 target 对象就是 Handler 对象。主线程默认执行了 Looper.looper()方法,该方法从 Looper 的成员变量
MessageQueue 中取出 Message,然后调用 Message 的 target 对象的 handleMessage()方法。这样就完成了整个

<—————————————->

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值