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

线程相关——HandlerThread、IntentService、ResultReceiver:结果接收者、AsyncTask:异步任务、Android中处理线程间通信的方式

2016-04-10 17:48 1101 查看
wait()和notify()

-------------------------------

wait:等待

notify:通知,与wait联合使用时,表示“唤醒”

HandlerThread

-------------------------------

HandlerThread是一个线程类,作用是用于提供1个关联到子线程的Looper。

HandlerThread中的getLooper()方法将返回关联在子线程的Looper对象,前提是必须先调用HandlerThread的start()。

IntentService

-------------------------------

IntentService的本质是1个Service。它是一个集自动开启线程执行耗时操作、若干个任务会依次执行、任务执行结束后自动自我销毁的Service组件。

【注意】

1. 自定义的IntentService的子类,必须提供无参数的构造方法,否则,系统将无法实例化该Service对象

2. 所有任务都是串行的,如果业务中多个任务没有关联,则串行的执行序列可能会效率较低

3. 如果需要重写IntentService中的生命周期方法,务必要使用super.on???()调用父类的方法

4. 基于IntentService中的逻辑控制都是在启动模式的Service的生命周期方法中,所以,IntentService一般不用于绑定

ResultReceiver:结果接收者

-------------------------------

可以用于IPC(进程间通信),或者简单的Activity、Service等组件间的通信。

【开发步骤】

1. 在Activity中,创建内部类继承自ResultReceiver,重写onReceiveResult()方法,决定如何处理结果

2. 在Activity中,创建自定义的ResultReceiver的对象,并封装到用于激活Service组件的Intent对象中

3. 在IntentService的子类的onHandleIntent()方法中,通过参数Intent对象获取ResultReceiver对象,并根据业务在适当的时候调用该对象的send()方法将结果发送给Activity

【注意事项】

在IntentService的子类中,获取ResultReceiver对象时,类型必须声明为ResultReceiver!!!

假设在Activity中使用内部类创建的ResultReceiver的类名为InnerResultReceiver,则在IntentService中,获取对象时,声明为InnerResultReceiver是错误的!!!

AsyncTask:异步任务

-------------------------------

【AsyncTask的泛型】

使用AsyncTask时,必须确定3个数据类型:

Params:参数的类型,即执行任务时是否需要参数,如果需要,那么该参数使用哪种数据类型表示,例如下载时需要网址,则Params的类型可以是String

Progress:进度的类型,即执行任务的过程中是否需要更新进度,如果需要,那么进度使用哪种数据类型表示,通常是Integer或者Float等数值型

Result:结果的类型,即执行任务完毕后是否需要结果,如果需要,那么需要使用哪种数据类型表示,例如下载图片的业务中,下载完成后可以得到Bitmap并用于显示

*** 如果不需要确定某个数据类型,可以使用Object或者Void表示

【AsyncTask的方法】

Result doInBackground(Params... params) -> 后台执行的任务,该方法默认运行在子线程,所以执行耗时操作时不需要显式的开启线程

void publishProgress(Integer... values) -> 【非重写方法】当需要更新进度时,调用该方法发布进度,通常在doInBackground()方法中调用该方法

void onProgressUpdate(Integer... values) -> 当有进度提交时的回调方法,即每当调用了publishProgress()则该方法被回调1次,该方法是运行在主线程的,可以直接更新UI控件

void onPostExecute(Result result) -> 当后台任务执行完毕后的回调方法,用于处理结果,该方法是运行在主线程的,可以直接更新UI控件

【AsyncTask的执行与取消】

创建出AsyncTask的对象,调用execute()方法,即可开始执行。

当需要取消任务时(任务未完成之前),调用cancel()方法即可终止任务。

每个任务的对象都是一次性使用的,当任务执行完成以后,或者被调用了cancel()取消后,该任务对象就不再存在,如果需要再次使用,必须重新创建任务的对象。

【注意】如果存在多种任务(即自定了多个类都继承自AsyncTask),无论这些任务是否是同一个类的对象,都将依次执行,并不会并行处理。所以,如果某次需要执行的多个任务没有先后顺序的要求,则,最多只能有1种任务使用AsyncTask的方式进行开发和执行。

Android中处理线程间通信的方式

-------------------------------

【消息机制,即Thread+Handler+Message】

优点:自由,若干个线程是并行的,多种业务的UI更新的代码可以集中管理

缺点:代码量略多,默认若干个子线程是并行的,如果子线程过多,或者运行的数据量过大,则会严重消耗系统的性能,如果需要避免这样的状况,需要手动管理同一时间内的子线程的数量

【IntentService+ResultReceiver】

优点:不需要显式的开启子线程,进程优先级较高,更加适用于执行长时间才能完成的任务,若干个任务是串行的

缺点:代码量略多,代码管理难度略大,大材小用

【AsyncTask】

优点:不需要考虑线程的问题,同一个业务的代码集中管理,若干个任务是串行的,可以取消

缺点:若干个任务(无论是否是同一个类的任务对象)是串行的

可变参数 / 变长参数

-------------------------------

在编写方法时,声明参数的类型后面加上3个小数点,表示猜参数的数量可以是若干个(0~N个)。

在方法体重,处理参数时,该参数表现为是数组。

public class Sample {

public static void main(String[] args) {

System.out.println(sum());

System.out.println(sum(5));

System.out.println(sum(5, 10));

System.out.println(sum(5, 10, 15));

System.out.println(sum(5, 10, 15, 1, 2, 3, 4));

}

public static int sum(int... numbers) {

int result = 0;

if(numbers.length > 0) {

for (int i = 0; i < numbers.length; i++) {

result += numbers[i];

}

}

return result;

}

}

【注意事项】

1. 每个方法中最多只允许存在1个可变参数

2. 方法参数中的可变参数必须是最后一个参数
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: