IntentService 源码分析

Posted yian_

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了IntentService 源码分析相关的知识,希望对你有一定的参考价值。

转载请注明出处:http://blog.csdn.net/yianemail/article/details/51713399

  • IntentService(Service)的使用场景
  • IntentService与Service的区别
  • IntentService使用
  • IntentService原理源码实现

IntentService(Service)的使用场景

Service 是android系统中实现程序后台运行的解决方案,非常适合那些不需要跟用户直接交互并且长期运行的任务。
Service运行于UiThread,因此若想要在Service 执行耗时操作,就需要在Service中创建线程成完成耗时任务。

IntentService与Service的区别

IntentService 是继承于Service的并处理异步请求的一个类,二者的启动方式并没有什么差别。区别是IntentService 会自动运行在子线程中,并且执行完毕会自我stop。

区别总结:如果必须在Service (IntentService) 中执行耗时任务,在Service 中我们必须要采用开启新线程的方式,(比如new Thread().start()),且执行完毕要手动退出。而在IntentService中则可以直接执行,也不必手动干预退出。

IntentService的使用

一:模拟耗时任务,执行完毕更新界面ui

首先看下效果图

这里写图片描述
点击耗时任务,启动IntentService模拟耗时任务执行,执行完毕通过广播更新界面ui,(也可以采用handler)

二:代码实现

IntentService

package com.huanjulu.intentservice;/*
 * Copyright (C) 2016,
 * Author: huanjulu on 16/6/17
 * to: 
 */

import android.app.IntentService;
import android.content.Intent;

public class TaskIntentService extends IntentService {
    public TaskIntentService() {
        super("TaskIntentService-Thread");
    }
    public TaskIntentService(String name) {
        super(name);
    }
    @Override
    protected void onHandleIntent(Intent intent) {
        //直接在此执行耗时任务
        if (null != intent) {
            onTashHandler();
        }
    }

    /**
     * 模拟耗时任务  如果采用serivce 你就需new Thread 处理
     */
    private void onTashHandler() {
        try {
            Thread.sleep(3000);
            Intent intent = new Intent();
            intent.setAction(MainActivity.TNTENT_SERVICE);
            sendBroadcast(intent);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }
}

继承IntentService的类至少要实现两个函数:构造函数和onHandleIntent()函数。要覆盖IntentService的其它函数时,注意要通过super调用父类的对应的函数。

此处注意一下IntentService 的生命周期。我们在onHandleIntent()中模拟耗时任务(Thread.sleep(3000):模拟执行时间为3秒)执行完毕,发送广播,通知主界面更新ui。

Activity 代码实现

package com.huanjulu.intentservice;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;

public class MainActivity extends Activity {
    public static final String TNTENT_SERVICE = "com.huanjulu.intentservice.TaskIntentService";
    TextView textView;

    private BroadcastReceiver uploadImgReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            Log.d("TAG","onReceive");
            if (intent.getAction() .equals(TNTENT_SERVICE)) {
                Log.d("TAG","intent.getAction()");
                textView.setText("耗时任务执行完毕!");
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = (TextView) findViewById(R.id.message_tv);

        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(TNTENT_SERVICE);
        registerReceiver(uploadImgReceiver, intentFilter);

        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                textView.setText("正在执行任务...");
                Intent intent = new Intent(MainActivity.this, TaskIntentService.class);
                startService(intent);
            }
        });
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(uploadImgReceiver);
    }
}

在onCreate()中我们注册广播,在onDestroy()中注销,点击事件去开启IntentService 执行任务。
Service 为四大组件之一,所以必须在AndroidMainfest.xml中声明。

IntentService原理源码实现

通过IntentService 的执行生命周期,第一次执行是要走onCreat()

    @Override
    public void onCreate() {
        super.onCreate();
    }

super.onCreate(); 调用 父类(也就是IntentService) 的onCreat()函数。

分析一下IntentService 的onCreat() 做了什么

   @Override
    public void onCreate() {
        // TODO: It would be nice to have an option to hold a partial wakelock
        // during processing, and to have a static startService(Context, Intent)
        // method that would launch the service & hand off a wakelock.

        super.onCreate();
        HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
        thread.start();

        mServiceLooper = thread.getLooper();
        mServiceHandler = new ServiceHandler(mServiceLooper);
    }

可以看到主要做了两件事,一是开启了一个HandlerThread 线程(有关HandlerThread 我稍后的博文会分析,这里只要知道HandlerThread 继承了Thread, 重点分析run()方法),二是通过mServiceLooper 实例化了ServiceHandler 对象。

分析 thread.start() ,


    @Override
    public void run() {
        mTid = Process.myTid();
        Looper.prepare();
        synchronized (this) {
            mLooper = Looper.myLooper();
            notifyAll();
        }
        Process.setThreadPriority(mPriority);
        onLooperPrepared();
        Looper.loop();
        mTid = -1;
    }

我们看到了什么? 没错!实例化mq ,开启消息循环..依旧是采用了android中的异步消息机制。

      Looper.prepare();
      Looper.loop();

通过 thread.getLooper();得到 实例化的looper 并作为参数实例化ServiceHandler()

    private volatile Looper mServiceLooper;
    private volatile ServiceHandler mServiceHandler;


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

        @Override
        public void handleMessage(Message msg) {
        //这里就是我们IntnetService 中覆写onHandleIntent 的逻辑
        //执行完毕调用stopSelf()自动退出
            onHandleIntent((Intent)msg.obj);
            stopSelf(msg.arg1);
        }
    }

有了looper,实例化了handler ,总得有个sendMessage吧。
在onStart中

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

流程总结
就是每次调用onStartCommand的时候 ,onStartCommand继续调用onStart ,通过mServiceHandler发送一个消息,消息中包含我们的intent。然后在该mServiceHandler的handleMessage中去回调onHandleIntent(intent);

以上是关于IntentService 源码分析的主要内容,如果未能解决你的问题,请参考以下文章

IntentService源码分析

IntentService源码分析

IntentService使用以及源码分析

IntentService源码分析

Android IntentService源码理解 及 HandlerThread构建消息循环机制分析

源码分析Service和IntentService的区别