Android:IntentService的学习

Android的四大组件中,Service排行老二,在Android中的主要做用是后台服务,进行与界面无关的操做。因为Service运行在主线程,因此进行异步操做须要在子线进行。为此Android为咱们提供了IntentServiceIntentService是一个抽象类,继承至Service,主要方便咱们新建工做线程进行异步操做。提交任务到IntentService时,异步任务以串行方式进行处理,意味着工做线程一次只处理一个任务。并且当全部任务都完成以后,会自动中止Service,不须要咱们手动中止。android

IntentService 的使用

  1. 咱们定义DownloadService类并继承至IntentService。来模拟网络下载的过程。
public class DownloadService extends IntentService {

    private static int count = 0;

    /**
     * 主要用于调用服务类构造器
     *
     * @param name 用于区分不一样任务
     */
    public DownloadService(String name) {
        super(name);
    }

    /**
     * AndroidManifest.xml配置清单须要配置
     *
     * @param
     */
    public DownloadService() {
        super("action");
    }

    /**
    *主要重写该方法,在该方法内进行异步操做。
    **/
    @Override
    protected void onHandleIntent(Intent intent) {
        Log.i("Download", "onHandleIntent" + count);
        count++;

        String name = intent.getStringExtra("action");

        if (name.equals("download")) {
            for (int i = 0; i < 5; i++) {

                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    return;
                }

                Log.i("Download", "download:" + count);
            }
        }
    }
    //如下方法的重写,仅仅为了打印日志
    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.i("Download", "onDestroy");

    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.i("Download", "onCreate");
    }

    @Override
    public void onStart(Intent intent, int startId) {
        super.onStart(intent, startId);

        Log.i("Download", "onStart");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.i("Download", "onStartCommand");
        return super.onStartCommand(intent, flags, startId);
    }
}

复制代码
  1. 在AndroidManifest.xml配置DownloadService
<service android:name=".DownloadService"/>
复制代码
  1. 在MainActivity类中循环调用Service,启动多循环任务。
@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Intent intent=new Intent(this,DownloadService.class);
        for (int i =0;i<3;i++){

            intent.putExtra("action","download");
            intent.putExtra("count",""+i);
            startService(intent);

        }
    }
复制代码
  1. 运行结果

分析: 从运行结果知道,IntentService在运行多个任务状况下,只调用一次onCreate,调用屡次onStartCommand,跟Service的生命周期一致。但,只有在运行完download:1以后才会去运行download:2,接着是download:3。最后全部任务结束后会自动调用onDestroy,中止服务。在这里须要注意的是,和Service并不一样,Service须要咱们手动中止服务。对于结果的回调,能够采用接口回调,广播,EventBusbash

那么,IntentService是如何在Service中实现异步操做和串行处理任务的呢?网络

IntentService内部实现

  1. 查看IntentService的onCreate方法
@Override
    public void onCreate() {
        super.onCreate();
        //分析一
        HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
        thread.start();

        mServiceLooper = thread.getLooper();
        分析二
        mServiceHandler = new ServiceHandler(mServiceLooper);
    }
复制代码

分析一异步

HandThread继承Thread,经过start方法建立工做线程,内部创建Looper来达到消息循环,经过Hanlder消息机制来达到串行的效果和处理多任务。HandThreadHandler消息机制,能够另外查看文章。ide

分析二oop

ServiceHandler继承Handler,与普通的Handler并无区别,在其内容处理handleMessage。即调用IntentServiceonHandleIntentpost

private final class ServiceHandler extends Handler {
        public ServiceHandler(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
            onHandleIntent((Intent)msg.obj);
            stopSelf(msg.arg1);
        }
    }
复制代码
  1. 那么,当咱们在Activity中重复调用startService方法时,只会屡次调用onStartCommand方法,并不会重复调用onCreate方法。咱们看看onStartComamnd方法的实现。
@Override
    public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
        onStart(intent, startId);
        return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
    }
复制代码

能够看得出,调用了onStart方法了。而onStart方法只是将咱们的Intent包装成Message,经过Handler发送出去,并在Handler中进行处理,调用咱们的onHandleIntent。进而调用咱们实现onHandleIntent的代码。ui

@Override
    public void onStart(@Nullable Intent intent, int startId) {
        Message msg = mServiceHandler.obtainMessage();
        msg.arg1 = startId;
        msg.obj = intent;
        mServiceHandler.sendMessage(msg);
    }
复制代码

总结

IntentService并无什么的新的技术含量,在了解HandlerTread和Handler的消息机制下,对Handler+Thread+Service做一个封装,更适合咱们后台进行异步耗时操做的场景。有效避免经过new多个Threadthis

知识点分享spa

Android消息机制

HandlerThread必知必会

点个赞,老铁

若是以为文章有用,给文章点个赞,铁子
相关文章
相关标签/搜索