Android异步加载全解析之IntentService

来源:互联网 发布:西安市行知中学好不好 编辑:程序博客网 时间:2024/05/16 17:25

Android异步加载全解析之IntentService

搞什么IntentService

前面我们说了那么多,异步处理都使用钦定的AsyncTask,再不济也使用的Thread,那么这个IntentService是个什么鬼。
相对与前面我们提到的这两种异步加载的方式来说,IntentService有一个最大的特点,就是——IntentService不受大部分UI生命周期的影响,它为后台线程提供了一个更直接的操作方式。不过,IntentService的不足主要体现在以下几点:

  • 不可以直接和UI做交互。为了把他执行的结果体现在UI上,需要发送给Activity。
  • 工作任务队列是顺序执行的,如果一个任务正在IntentService中执行,此时你再发送一个任务请求,这个任务会一直等待直到前面一个任务执行完毕。
  • 正在执行的任务无法打断。

创建IntentService

当我们创建一个类并继承IntentService后,通过IDE的提示,我们基本可以生成如下所示的代码:
package com.imooc.intentservicetest;import android.app.IntentService;import android.content.Intent;public class MyIntentService extends IntentService {    /**     * Creates an IntentService.  Invoked by your subclass's constructor.     *     * @param name Used to name the worker thread, important only for debugging.     */    public MyIntentService(String name) {        super(name);    }    public MyIntentService() {        super("MyIntentService");    }    @Override    protected void onHandleIntent(Intent intent) {    }}

PS:需要注意的是,系统会提示我们生成一个带参数的构造方法,另外,我们还需要定义一个无参数的构造方法,并调用一个参数的构造方法。所以,一个带参数的构造方法其实是可以删掉的。

最重要的就是:
@Overrideprotected void onHandleIntent(Intent intent) {}

在这个方法里面,我们从intent中获取数据,并进行相应的操作。

ps:IntentService继承自Service,但是我们不需要手动调用onStartCommand()等Service回调方法。

申明IntentService

我们需要在Mainifest文件中对IntentService进行申明:

<service android:name=".MyIntentService"            android:exported="false"/>

与申明一个Service类似,但是却不需要申明<intent-filter>,因为发送任务给IntentService的Activity需要使用显式Intent,所以不需要filter。这也意味着只有在同一个app或者其他使用同一个UserID的组件才能够访问到这个IntentService。

启动IntentService

启动IntentService与启动Service基本类似,而且我们可以在Intent中传入相关的参数。例如:
package com.imooc.intentservicetest;import android.app.Activity;import android.content.Intent;import android.os.Bundle;public class MainActivity extends Activity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        Intent intent = null;        for (int i = 0; i < 10; i++) {            intent = new Intent(this, MyIntentService.class);            intent.putExtra("xys", "" + i);            startService(intent);        }    }}

可以看见,我们start了10个IntentService,最后执行的结果如下:
05-13 17:14:53.515  19991-20011/com.imooc.intentservicetest D/xys﹕ onHandleIntent005-13 17:14:55.528  19991-20011/com.imooc.intentservicetest D/xys﹕ onHandleIntent105-13 17:14:57.540  19991-20011/com.imooc.intentservicetest D/xys﹕ onHandleIntent205-13 17:14:59.544  19991-20011/com.imooc.intentservicetest D/xys﹕ onHandleIntent305-13 17:15:01.556  19991-20011/com.imooc.intentservicetest D/xys﹕ onHandleIntent405-13 17:15:03.569  19991-20011/com.imooc.intentservicetest D/xys﹕ onHandleIntent505-13 17:15:05.570  19991-20011/com.imooc.intentservicetest D/xys﹕ onHandleIntent605-13 17:15:07.574  19991-20011/com.imooc.intentservicetest D/xys﹕ onHandleIntent705-13 17:15:09.577  19991-20011/com.imooc.intentservicetest D/xys﹕ onHandleIntent805-13 17:15:11.581  19991-20011/com.imooc.intentservicetest D/xys﹕ onHandleIntent9

所以说,启动IntentService之后,它将默认生成一个Worker Thread,并将这些IntentService依次放入队列,每次取出一个进行执行,当执行完毕后,这个IntentService会自动stop自己,当所有intent都执行完毕后,服务就结束了,不需要自己手动来结束。


IntentService修改UI

IntentService如果要进行UI的修改,那么只能通过Handler来实现,或者使用广播机制来通知修改UI。

IntentService与AsyncTask的区别


  • 对于异步更新UI来说,IntentService使用的是Serivce+handler或者广播的方式,而AsyncTask是thread+handler的方式。
  • AsyncTask比IntentService更加轻量级一点。
  • Thread的运行独立于Activity,当Activity结束之后,如果没有结束thread,那么这个Activity将不再持有该thread的引用。
  • Service不能在onStart方法中执行耗时操作,只能放在子线程中进行处理,当有新的intent请求过来都会线onStartCommond将其入队列,当第一个耗时操作结束后,就会处理下一个耗时操作(此时调用onHandleIntent),都执行完了自动执行onDestory销毁IntengService服务。

代码地址:戳我戳我


我的Github
我的视频 慕课网




1 0
原创粉丝点击