为了账号安全,请及时绑定邮箱和手机立即绑定

聊聊IntentService那些事

标签:
Android

IntentService 为在单一后台线程中执行任务提供了一种直接的实现方式。它可以处理一个耗时的任务并确保不影响到UI的响应性。另外 IntentService 的执行还不受 UI 生命周期的影响,以此来确保 AsyncTask 能够顺利运行。

但是 IntentService 有下面几个局限性:

  • 不可以直接和 UI 做交互。为了把他执行的结果体现在UI上,需要把结果返回给 Activity。

  • 工作任务队列是顺序执行的,如果一个任务正在IntentService中执行,此时你再发送一个新的任务请求,这个新的任务会一直等待直到前面一个任务执行完毕才开始执行。

  • 正在执行的任务无法打断。

虽然有上面那些限制,然而在在大多数情况下,IntentService 都是执行简单后台任务操作的理想选择。

创建 IntentService

创建一个 IntentService 组件,需要自定义一个新的类,它继承自 IntentService,并重写onHandleIntent()方法

注意

一个普通 Service 组件的其他回调,例如onStartCommand()会被 IntentService 自动调用。在 IntentService 中,要避免重写那些回调。

public class MyService extends IntentService { 
  @Override 
  protected void onHandleIntent(Intent workIntent) { 
  dataString = workIntent.getDataString(); 
 }}

在 Manifest 文件中定义 IntentService

IntentService 需要在 manifest 文件添加相应的条目。

注意

标签并没有包含任何 intent filter。因为发送任务给 IntentService 的 Activity 需要使用显式 Intent,所以不需要 filter。这也意味着只有在同一个 app 或者其他使用同一个 UserID 的组件才能够访问到这个 Service。

<application 
  android:icon="@drawable/icon" 
  android:label="@string/app_name">
  <service 
    android:name=".MyService" 
    android:exported="false"/>
<application/>

创建任务请求并发送到 IntentService

一旦执行了startService(),IntentService 在自己本身的onHandleIntent()方法里面开始执行这个任务,任务结束之后,会自动停止这个 Service。

mServiceIntent = new Intent(getActivity(), MyService.class);
mServiceIntent.setData(Uri.parse(dataUrl));
getActivity().startService(mServiceIntent);

利用 IntentService 发送任务状态

通过执行LocalBroadcastManager.sendBroadcast()来发送 Intent。Intent 被发送到任何有注册接受它的组件中。为了获取到 LocalBroadcastManager 的实例,可以执行getInstance()

Intent localIntent = new Intent(Constants.BROADCAST_ACTION)     
.putExtra(Constants.EXTENDED_DATA_STATUS, status);     
LocalBroadcastManager.getInstance(this).sendBroadcast(localIntent);

接收来自 IntentService 的状态广播

为了接受广播的数据对象,需要使用 BroadcastReceiver 的子类并实现BroadcastReceiver.onReceive()的方法,这里可以接收 LocalBroadcastManager 发出的广播数据。

private class ResponseReceiver extends BroadcastReceiver{ 
  DownloadStateReceiver() { } 
  public void onReceive(Context context, Intent intent) {
}}

一旦定义了 BroadcastReceiver,也应该定义 actions,categories 与 data 用过滤广播。为了给系统注册这个BroadcastReceiver 和 IntentFilter,需要通过 LocalBroadcastManager 执行registerReceiver()的方法。

statusIntentFilter = new IntentFilter(Constants.ACTION_ZOOM_IMAGE);
LocalBroadcastManager.getInstance(getActivity())
.registerReceiver( mDownloadStateReceiver, mIntentFilter);

最后

使用 LocalBroadcastManager 结合 IntentService 其实是一种很典型高效的做法,同时也更符合OO的思想,通过广播注册与反注册的方式,对两个组件进行解耦。如果使用 Handler 传递到后台线程作为回调,容易带来的内存泄漏。原因是:匿名内部类对外面的 Actvitiy 持有引用,如果在 Acitivity 被销毁的时候,没有对 Handler 进行显式的解绑,会导致 Activity 无法正常销毁,这样自然就有了内存泄露

原文链接:http://www.apkbus.com/blog-705730-62019.html

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号

举报

0/150
提交
取消