展会信息港展会大全

Android开发使用后台线程 Thread+Handler的组合,AsyncTask
来源:互联网   发布日期:2016-01-14 09:14:28   浏览:1273次  

导读:相应能力对于Android系统来说太重要了。为了确保APP快速地应对用户的交互和系统事件,我们需要将所有的耗时处理和I O相关的操作移到子线程中去。文件操作、网络查询、数据库事务、还有复杂的计算都应该在后台线程 ...

相应能力对于Android系统来说太重要了。为了确保APP快速地应对用户的交互和系统事件,我们需要将所有的耗时处理和I/O相关的操作移到子线程中去。

文件操作、网络查询、数据库事务、还有复杂的计算都应该在后台线程中进行。

Android提供了一系列的措施可以让你将处理移到后台。

比如:Thread+Handler的组合,AsyncTask。

AsyncTask用来执行短期的处理非常合适。但是呢,Activity重启的时候,它是不会有所保留的。比如说设备配置发生改变,导致Activity重启,然后AsyncTask就会被打断。

通常推荐,那种相对更长时间操作的,可以选择Service组件。

相似的,CursorLoader用来优化ContentProvider的查询非常合适。

创建新的AsyncTask

每个建立的AsyncTask都需要指定3个泛型参数类型,第一个:输入的参数,第二个:进度值,第三个:结果值。

下面直接看例子:

private class MyAsyncTask extends AsyncTask<String, Integer, String> {

@Override

protected String doInBackground(String... parameter) {

// Moved to a background thread.

String result =;

int myProgress = 0;

int inputLength = parameter[0].length();

// Perform background processing task, update myProgress]

for (int i = 1; i <= inputLength; i++) {

myProgress = i;

result = result + parameter[0].charAt(inputLength-i);

try {

Thread.sleep(100);

} catch (InterruptedException e) { }

publishProgress(myProgress);

}

// Return the value to be passed to onPostExecute

return result;

}

@Override

protected void onProgressUpdate(Integer... progress) {

// Synchronized to UI thread.

// Update progress bar, Notification, or other UI elements

asyncProgress.setProgress(progress[0]);

}

@Override

protected void onPostExecute(String result) {

// Synchronized to UI thread.

// Report results via UI update, Dialog, or notifications

asyncTextView.setText(result);

}

}

下面介绍这几个函数:

1.doInBackground 故名思议,这个方法会执行在后台线程。可以在这个方法内做耗时的操作。你可以使用publishProgress方法去传递参数值给onProgressUpdate方法。

2.onProgressUpdate 这个方法用来接收过度时期的进度值,(比如你可以使用这个方法更新ProgressBar的进度)。这个方法是与UI线程同步的。

3.onPostExecute 当doInBackground完成的时候,它的返回值会作为onPostExecute的结果参数传进来,然后你就可以以此来更新UI。同样这个方法也是与UI线程同步的。

运行一个AsynTask:

String input =redrum ... redrum ;

new MyAsyncTask().execute(input);

注意:execute 方法只能执行1次,再次调用会报错。

介绍Intent Service

Intent Service是一个非常好的包装类,实现了最好的方式让后台的Service执行一系列的任务集,比如循环的网络更新或者数据处理。

它把发过来的Intent放入它自己维护的队列中,然后一个个拿出来在后台线程中处理。当所有的Intent都被处理完的时候,Intent Service会自动结束自己。

主要的方法onHandleIntent是在后台线程的:

public class MyIntentService extends IntentService {

public MyIntentService(String name) {

super(name);

// TODO Complete any required constructor tasks.

}

@Override

public void onCreate() {

super.onCreate();

// TODO: Actions to perform when service is created.

}

@Override

protected void onHandleIntent(Intent intent) {

// This handler occurs on a background thread.

// TODO The time consuming task should be implemented here.

// Each Intent supplied to this IntentService will be

// processed consecutively here. When all incoming Intents

// have been processed the Service will terminate itself.

}

}

带过一下Loader

Loader是在Android 3.0(API 11)中引入的,在Android Support Library中也可用,比如以前用到的CursorLoader。

当你想创建自己的Loader的时候,通常你只需要继承 AsyncTaskLoader。

手动异步的时候,有个方法需要提下:

View的runOnUiThread。此方法运行在UI线程。

使用ALARMS

Alarms用来发射Intents,在确定的时间或者时间间隔。不像Timer,Alarms操作不受限于你的APP,所以你可以用来触发APP事件或者动作事件,即便APP已经被关了。

Alarms非常强大,你可以与广播混合使用,你能够用来发射Broadcast Intent,启动Service,或者甚至打开Activity,不需要你的APP被打开或者运行。

Alarms是一个有效的方式用来减少你的APP资源需求,比如使你能够停止服务,然后减少时间。

你可以用Alarms来计划基于网络查询进行规律的更新,去安排耗时的操作在不紧张的时间,或者安排操作失败后的再次尝试。

当设备在睡觉模式下,Alarms仍保持活跃,可以随意得叫醒设备。当设备重启的时候,所有的Alarms都会被取消。

通过AlarmManager来处理Alarm的操作.

获取AlarmManager:

AlarmManager alarmManager =

(AlarmManager)getSystemService(Context.ALARM_SERVICE);

创建一个新的 一次性的 Alarm,使用set方法,然后再指定Alarm类型,一个触发的时间,和一个 Pending Intent。

如果你规定的触发时间已经过了,那么这个Alarm会马上触发。

下面介绍类型:

1.RTC_WAKEUP 叫醒设备,触发Alarm(在指定的时间点,发送Pending Intent)。

2.RTC 不叫醒设备,触发Alarm(在指定的时间点,发送Pending Intent)。

3.ELAPSED_REALTIME 不叫醒设备。在一定的时间流逝后,触发Alarm。

4.ELAPSED_REALTIME_WAKEUP 叫醒设备。在一定的时间流逝后,触发Alarm。

你的这些类型选择会决定set方法内传的时间是准确的时间还是需要等待的时间。

例子:创建一个等待的ALARM,10秒后触发

// Get a reference to the Alarm Manager

AlarmManager alarmManager =

(AlarmManager)getSystemService(Context.ALARM_SERVICE);

// Set the alarm to wake the device if sleeping.

int alarmType = AlarmManager.ELAPSED_REALTIME_WAKEUP;

// Trigger the device in 10 seconds.

long timeOrLengthofWait = 10000;

// Create a Pending Intent that will broadcast and action

String ALARM_ACTION =ALARM_ACTION ;

Intent intentToFire = new Intent(ALARM_ACTION);

PendingIntent alarmIntent = PendingIntent.getBroadcast(this, 0,

intentToFire, 0);

// Set the alarm

alarmManager.set(alarmType, timeOrLengthofWait, alarmIntent);

纠正一点:这里的流逝的时间是相对的,当系统刚启动的时候是0,而你测试的时候系统已经在启动了10秒肯定早过了,所以你需要SystemClock.elapsedRealtime()获取系统已经流逝的时间再加上10秒也就是10000。

取消一个Alarm

alarmManager.cancel(alarmIntent);

设置重复的Alarms

1.setRepeating 准确的重复时间间隔

2.setInexactRepeating 不准确的。。。。

指定些常量:

1.INTERVAL_FIFTEEN_MINUTES

2.INTERVAL_HALF_HOUR

3.INTERVAL_HOUR

4.INTERVAL_HALF_DAY

5.INTERVAL_DAY

使用inexact repeating alarms,可以用来阻止多个APP分开唤醒设备在一个相似但是不重叠的时间。通过同步这些alarms,使系统有能力去减少重复事件给电池带来的消耗。

// Get a reference to the Alarm Manager

AlarmManager alarmManager =

(AlarmManager)getSystemService(Context.ALARM_SERVICE);

// Set the alarm to wake the device if sleeping.

int alarmType = AlarmManager.ELAPSED_REALTIME_WAKEUP;

// Schedule the alarm to repeat every half hour.

long timeOrLengthofWait = AlarmManager.INTERVAL_HALF_HOUR;

// Create a Pending Intent that will broadcast and action

String ALARM_ACTION =ALARM_ACTION ;

Intent intentToFire = new Intent(ALARM_ACTION);

PendingIntent alarmIntent = PendingIntent.getBroadcast(this, 0,

intentToFire, 0);

// Wake up the device to fire an alarm in half an hour, and every

// half-hour after that.

alarmManager.setInexactRepeating(alarmType,

timeOrLengthofWait,

timeOrLengthofWait,

alarmIntent);

赞助本站

人工智能实验室

相关热词: 后台线程 Android

AiLab云推荐
展开

热门栏目HotCates

Copyright © 2010-2024 AiLab Team. 人工智能实验室 版权所有    关于我们 | 联系我们 | 广告服务 | 公司动态 | 免责声明 | 隐私条款 | 工作机会 | 展会港