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);

时间: 2024-10-10 15:37:51

IntentService 源码分析的相关文章

Android IntentService 源码分析

IntentService简介: IntentService是一个通过Context.startService(Intent)启动可以处理异步请求的Service,使用时你只需要继承IntentService和重写其中的onHandleIntent(Intent)方法接收一个Intent对象,该服务会在异步任务完成时自动停止服务. 所有的请求的处理都在IntentService内部工作线程中完成,它们会顺序执行任务(但不会阻塞主线程的执行),某一时刻只能执行一个异步请求. IntnetServi

IntentService源码分析

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 { pub

IntentService使用以及源码分析

一 概述 我们知道,在Android开发中,遇到耗时的任务操作时,都是放到子线程去做,或者放到Service中去做,在Service中开一个子线程来执行耗时操作. 那么,在Service里面我们需要自己管理Service的生命周期,何时开启何时关闭,还是很麻烦的,还好Android给我们提供了一个这样的类,叫做IntentService 那么IntentService是做什么用的呢? IntentService: 是继承于Service的一个类,用来处理异步请求.可以直接通过startServi

Android HandlerThread 源码分析

HandlerThread 简介: 我们知道Thread线程是一次性消费品,当Thread线程执行完一个耗时的任务之后,线程就会被自动销毁了.如果此时我又有一 个耗时任务需要执行,我们不得不重新创建线程去执行该耗时任务.然而,这样就存在一个性能问题:多次创建和销毁线程是很耗 系统资源的.为了解这种问题,我们可以自己构建一个循环线程Looper Thread,当有耗时任务投放到该循环线程中时,线程执行耗 时任务,执行完之后循环线程处于等待状态,直到下一个新的耗时任务被投放进来.这样一来就避免了多次

IntentService源码详解

IntentService可以做什么: 如果你有一个任务,分成n个子任务,需要它们按照顺序完成.如果需要放到一个服务中完成,那么IntentService就会使最好的选择. IntentService是什么: IntentService是一个Service(看起来像废话,但是我第一眼看到这个名字,首先注意的是Intent啊.),所以如果自定义一个IntentService的话,一定要在AndroidManifest.xml里面声明. 从上面的"可以做什么"我们大概可以猜测一下Inten

TeamTalk源码分析之login_server

login_server是TeamTalk的登录服务器,负责分配一个负载较小的MsgServer给客户端使用,按照新版TeamTalk完整部署教程来配置的话,login_server的服务端口就是8080,客户端登录服务器地址配置如下(这里是win版本客户端): 1.login_server启动流程 login_server的启动是从login_server.cpp中的main函数开始的,login_server.cpp所在工程路径为server\src\login_server.下表是logi

Android触摸屏事件派发机制详解与源码分析二(ViewGroup篇)

1 背景 还记得前一篇<Android触摸屏事件派发机制详解与源码分析一(View篇)>中关于透过源码继续进阶实例验证模块中存在的点击Button却触发了LinearLayout的事件疑惑吗?当时说了,在那一篇咱们只讨论View的触摸事件派发机制,这个疑惑留在了这一篇解释,也就是ViewGroup的事件派发机制. PS:阅读本篇前建议先查看前一篇<Android触摸屏事件派发机制详解与源码分析一(View篇)>,这一篇承接上一篇. 关于View与ViewGroup的区别在前一篇的A

HashMap与TreeMap源码分析

1. 引言     在红黑树--算法导论(15)中学习了红黑树的原理.本来打算自己来试着实现一下,然而在看了JDK(1.8.0)TreeMap的源码后恍然发现原来它就是利用红黑树实现的(很惭愧学了Java这么久,也写过一些小项目,也使用过TreeMap无数次,但到现在才明白它的实现原理).因此本着"不要重复造轮子"的思想,就用这篇博客来记录分析TreeMap源码的过程,也顺便瞅一瞅HashMap. 2. 继承结构 (1) 继承结构 下面是HashMap与TreeMap的继承结构: pu

Linux内核源码分析--内核启动之(5)Image内核启动(rest_init函数)(Linux-3.0 ARMv7)【转】

原文地址:Linux内核源码分析--内核启动之(5)Image内核启动(rest_init函数)(Linux-3.0 ARMv7) 作者:tekkamanninja 转自:http://blog.chinaunix.net/uid-25909619-id-4938395.html 前面粗略分析start_kernel函数,此函数中基本上是对内存管理和各子系统的数据结构初始化.在内核初始化函数start_kernel执行到最后,就是调用rest_init函数,这个函数的主要使命就是创建并启动内核线