一、IntentService
1.概述
部分新手会认为(我刚开始也是这么认为的),Service因为不用于与用户直接交互,所可以直接处理比较耗时的操作,比如网络连接等。其实不然,Service虽然不与用户交互,但是其仍是运行在主线程中,因此,Service如果操作时间过长,则会出现ANR。为了解决这个问题,Android官方给出了一个新的Service,用于处理长时间的后台任务,即IntentService。其原理是在Service中启动一个工作线程,用于执行指定的操作。
2.IntentService使用
1)创建IntentService
public class RSSPullService extends IntentService {
@Override
protected void onHandleIntent(Intent workIntent) {
// 从Intent中获取数据
String dataString = workIntent.getDataString();
// 执行任务
}
}
在IntentService中,onStartCommand()被自动调用,所以我们不需要重写onStartCommand()。
2)在Manifest中声明
<service android:name=".RSSPullService" android:exported="false" />
其中不需要包含filter,因为会使用明确的Service。同时这样也能让别的应用无法访问该Service。
3)启动服务
mServiceIntent = new Intent(getActivity(), RSSPullService.class);
mServiceIntent.setData(Uri.parse(dataUrl));
getActivity().startService(mServiceIntent);
4)发送处理结果
这里会使用一个App内部广播机制,通过LocalBroadcastManager.sendBroadcast(),其发送的广播只有自己的应用接收器才能收到。
public final class Constants {
// 定义一个Intent action
public static final String BROADCAST_ACTION = "com.example.android.threadsample.BROADCAST";
// 定义"extra"键
public static final String EXTENDED_DATA_STATUS = "com.example.android.threadsample.STATUS";
}
public class RSSPullService extends IntentService {
Intent localIntent = new Intent(Constants.BROADCAST_ACTION)
localIntent.putExtra(Constants.EXTENDED_DATA_STATUS, status);
// 发送给本应用内的广播
LocalBroadcastManager.getInstance(this).sendBroadcast(localIntent);
}
5)接收广播并与UI交互
一般采用内部类的形式,可以动态注册,也可以直接访问UI。
private class ResponseReceiver extends BroadcastReceiver
{
// 防止外部实例化
private DownloadStateReceiver() {
}
@Override
public void onReceive(Context context, Intent intent) {
// 处理结果
}
}
6)注册广播
可以在Activity或Fragment中注册广播
IntentFilter statusIntentFilter = new IntentFilter(Constants.BROADCAST_ACTION);
// 添加http协议的数据过滤器
statusIntentFilter.addDataScheme("http");
DownloadStateReceiver mDownloadStateReceiver = new DownloadStateReceiver();
// 注册
LocalBroadcastManager.getInstance(this).registerReceiver(mDownloadStateReceiver, statusIntentFilter);
同一个广播也可以处理多个请求,只需定义对应的Action(将上面的IntentFilter换掉即可)。通过这种方式不会唤醒Activity(如果不在前台),如果要通知用户任务完成,可以使用Notification。
3.其他
当然,除了IntentService,我们还可以使用AsynTask实现类来处理异步任务,而且其可以通知执行进度,这里就不赘述了。