IntentService源码解析

IntentService 介绍

IntentService是一个专门处理后台异步任务的服务。官方的介绍是

IntentService is a base class for {@link Service}s that handle asynchronous
requests (expressed as {@link Intent}s) on demand. Clients send requests
through {@link android.content.Context#startService(Intent)} calls; the
service is started as needed, handles each Intent in turn using a worker
thread, and stops itself when it runs out of work.

This “work queue processor” pattern is commonly used to offload tasks
from an application’s main thread. The IntentService class exists to
simplify this pattern and take care of the mechanics. To use it, extend
IntentService and implement {@link #onHandleIntent(Intent)}. IntentService
will receive the Intents, launch a worker thread, and stop the service as
appropriate.

All requests are handled on a single worker thread – they may take as
long as necessary (and will not block the application’s main loop), but
only one request will be processed at a time.

翻译过来大概的意思是
IntentService是一个继承Service专门用于处理异步请求的的类,客户端只需要 通过startService发送请求,在IntentService的start方法中去处理Intent在一个工作线程中,在工作完成以后,他会自己停止自己。
这种工作队列的模式通常用于在主线程执行分流任务。Intentservice的存在可以简化这种模式而关注核心问题。使用它需要继承IntentService 实现一个onHandleIntent。Intentservice将接受意图、开启工作线程并在适当的时候停止service。
所有的请求都在一个单独的线程处理–他们可能采取只要有必要(不阻塞应用程序的主线程),但只有一个请求,将一次处理。

翻译的太垃圾了,莫见怪,如果你有更好的翻译请告诉我谢谢,非常感谢。从上面这段话其实我们已经大概知道了IntentService是如何工作和使用的。
下面我们看看源码是不是这样

IntentService 源码

看源码前请一定要先看看Handler源码HandlerThread源码介绍

public abstract class IntentService extends Service {
    private volatile Looper mServiceLooper;
    private volatile ServiceHandler mServiceHandler;
    private String mName;
    private boolean mRedelivery;

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

        @Override
        public void handleMessage(Message msg) {
            // 因为是HandlerThread 在它的run方法中开启了一个无限循环,不停的从MessageQueue中取出消息并调用dispachMessage处理消息

            // 在线程中处理发送过来的Intent消息
            onHandleIntent((Intent)msg.obj);
            stopSelf(msg.arg1);// 执行完以后,自己停止自己
        }
    }

    public IntentService(String name) {
        super();
        mName = name;
    }

    //设置当前服务被意外关闭后是否重新
    //如果设置为 true,onStartCommand() 方法将返回 Service.START_REDELIVER_INTENT,这样当
    //当前进程在 onHandleIntent() 方法返回前销毁时,会重启进程,重新使用之前的 Intent 启动这个服务
    //(如果有多个 Intent,只会使用最后的一个)
    //如果设置为 false,onStartCommand() 方法返回 Service.START_NOT_STICKY,当进程销毁后也不重启服务
    public void setIntentRedelivery(boolean enabled) {
        mRedelivery = enabled;
    }

    @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();
        // 在onCreate方法中创建了一个handlerThread子线程
        HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
        thread.start();

        //获取到线程的Looper对象,创建一个线程的handler
        mServiceLooper = thread.getLooper();
        mServiceHandler = new ServiceHandler(mServiceLooper);
    }

    @Override
    public void onStart(@Nullable Intent intent, int startId) {
        // 获取到service的intent 然后往子线程的messageQueue对象中添加Message消息
        Message msg = mServiceHandler.obtainMessage();
        msg.arg1 = startId;
        msg.obj = intent;
        mServiceHandler.sendMessage(msg);
    }

    /**
     * You should not override this method for your IntentService. Instead,
     * override {@link #onHandleIntent}, which the system calls when the IntentService
     * receives a start request.
     * @see android.app.Service#onStartCommand
     */
    @Override
    public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
        onStart(intent, startId);
        return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
    }

    @Override
    public void onDestroy() {
        mServiceLooper.quit();
    }

    /**
     * Unless you provide binding for your service, you don't need to implement this
     * method, because the default implementation returns null.
     * @see android.app.Service#onBind
     */
    @Override
    @Nullable
    public IBinder onBind(Intent intent) {
        return null;
    }

    @WorkerThread
    protected abstract void onHandleIntent(@Nullable Intent intent);
}

IntentService使用

1、定义IntentService

public class DownloadIntentService extends IntentService {
    private static final String TAG = "DownloadIntentService";

    public static final String DOWNLOAD_URL = "down_load_url";
    public static final int WHAT_DOWNLOAD_FINISHED = 1;
    public static final int WHAT_DOWNLOAD_STARTED = 2;
    public static Handler mUIHandler;

    public DownloadIntentService(){
        super(TAG);
    }
    public DownloadIntentService(String name) {
        super(name);
    }

    public static void setUIHandler(Handler handler){
        mUIHandler = handler;
    }

    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
        String download_url = intent.getStringExtra(DOWNLOAD_URL);
        if (mUIHandler != null){
            mUIHandler.sendMessage(mUIHandler.obtainMessage(WHAT_DOWNLOAD_STARTED));
        }
        //todo 下载图片的代码

        if (mUIHandler != null){
            mUIHandler.sendMessage(mUIHandler.obtainMessage(WHAT_DOWNLOAD_FINISHED));
        }

    }
}

2、注册Service

这一步很容易忘记

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.sourcecode" >
    <uses-permission android:name="android.permission.INTERNET"/>
    <application>
        <service android:name=".handler.DownloadIntentService"/>
    </application>
</manifest>

3、开启Service

DownloadIntentService.setUIHandler(new Handler(this));

Intent intent = new Intent(context,DownloadIntentService.class);
intent.putExtra(DownloadIntentService.DOWNLOAD_URL,"下载url");
context.startService(intent);

猜你喜欢

转载自blog.csdn.net/dingshuhong_/article/details/80178381