zoukankan      html  css  js  c++  java
  • Android-理解IntentService

    1.先来了解下什么是IntentService,intentService是继承Service的抽象类,我们知道Service本身是不会开启新线程的,如要则需要在onStartCommand中新建Thread.

    那么IntentService,我们来看一下他的onCreate方法.我们知道,android是用handler来实现其他线程和主线程的通信的,handler顾名思义就是一个投递者,我们可以把它理解成快递员,在其他线程和主线程之间交互信息。

    那么交互的信息肯定要打包好呀,否则路上不方便送货啊,那么我们把交互信息打包成message,就是消息序列。那么问题又来了,快递员送的包太多了,需要接收时候检查送货地址啊送货信息啊,这些操作没有送的那么方便,主线程不能把精力放在接收包上呀(否则ANR),所以我们的主线程新建了一个流水线,也就是Looper,来接收handler送来的message,这样主线程需要message的时候直接来looper取信息就好啦。

      其实四大组件的信息包都在主线程looper内,包括activity,service,broadcast,contentprovider.主线程轮询这些包,所以这些包内都不能使用太耗时的操作呀,不然下面的包就要等待啦,looper流水线就要爆仓啦。

    service本身是木有线程的,那么耗时的操作我们放哪呢,以前我们只好在onstartcommand中新建线程来执行,现在有了对service的包装类IntentServic.它会新建线程,并完成自身线程looper的创建,(只有UI线程才有自有looper,其他线程想要的话需要自己创建哦),并完成和UI线程异步通信的操作,并在完成操作后destroy自身,是不是很方便?对于下载这种异步操作用IntentService太合适了,还不用回收的。(我们也可以自己来实现这个IntentService哦)

    public abstract class IntentService extends Service 
     1    @Override
     2     public void onCreate() {
     3         // TODO: It would be nice to have an option to hold a partial wakelock
     4         // during processing, and to have a static startService(Context, Intent)
     5         // method that would launch the service & hand off a wakelock.
     6 
     7         super.onCreate();
     8         HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
     9         thread.start();
    10 
    11         mServiceLooper = thread.getLooper();
    12         mServiceHandler = new ServiceHandler(mServiceLooper);
    13     }

    2.我们来看一下怎么使用PendingIntent,其实其他方法很Service一模一样,只是多了一个onHandleIntent,处理的是当启动intent到来时的耗时操作哦。我们在onHandleIntent里面执行耗时操作等待10s,不会ANR。

    (注意只能在onHandleIntent里面执行超时操作,否则和service效果一样)生命周期也和service很相似。只是在onstart之后多了onHandleIntent操作。这里我们可以看到线程ThreadId。activity和intentService的线程id

    不同,这也验证了IntentService确实会新建异步线程。(启动方式和service一模一样,也是onstart或者onbind)

     protected abstract void onHandleIntent(Intent intent);

    06-04 16:49:57.993 30428-30428/com.alipay E/AM_MEMORYIPROCESS﹕ --> Activity id: 1
    06-04 16:49:58.003 30428-30428/com.alipay E/AM_MEMORYIPROCESS﹕ --> onResume
    06-04 16:49:58.013 30428-30428/com.alipay E/IntentService1﹕ --> onCreate
    06-04 16:49:58.013 30428-30428/com.alipay E/IntentService1﹕ --> onStartCommand
    06-04 16:49:58.013 30428-30428/com.alipay E/IntentService1﹕ --> onStart
    06-04 16:49:58.013 30428-30445/com.alipay E/IntentService1﹕ --> onHandleIntent
    06-04 16:49:58.013 30428-30445/com.alipay E/IntentService1﹕ --> IntentService1 id: 2829
    06-04 16:49:58.013 30428-30445/com.alipay E/IntentService1﹕ --> systime:1433407798024
    06-04 16:51:38.013 30428-30428/com.alipay E/IntentService1﹕ --> onDestroy

    3.特别有意思的是,同一个IntentService只会新建一个线程,很类似主线程,我们startIntentService两次,可以看出工作线程是一个队列,对一个任务完成之后才会执行下一项操作。验证intentservice进程号一致;

    06-04 17:17:42.073 31126-31126/com.alipay E/AM_MEMORYIPROCESS﹕ --> Activity id: 1
    06-04 17:17:42.083 31126-31126/com.alipay E/AM_MEMORYIPROCESS﹕ --> onResume
    06-04 17:17:42.103 31126-31126/com.alipay E/IntentService1﹕ --> onCreate
    06-04 17:17:42.103 31126-31126/com.alipay E/IntentService1﹕ --> onStartCommand
    06-04 17:17:42.103 31126-31126/com.alipay E/IntentService1﹕ --> onStart
    06-04 17:17:42.103 31126-31143/com.alipay E/IntentService1﹕ --> onHandleIntent
    06-04 17:17:42.103 31126-31126/com.alipay E/IntentService1﹕ --> onStartCommand
    06-04 17:17:42.103 31126-31143/com.alipay E/IntentService1﹕ --> IntentService1 id: 2850
    06-04 17:17:42.103 31126-31126/com.alipay E/IntentService1﹕ --> onStart
    06-04 17:17:42.113 31126-31143/com.alipay E/IntentService1﹕ --> systime:1433409462118
    06-04 17:19:22.113 31126-31143/com.alipay E/IntentService1﹕ --> onHandleIntent
    06-04 17:19:22.113 31126-31143/com.alipay E/IntentService1﹕ --> IntentService1 id: 2850
    06-04 17:19:22.113 31126-31143/com.alipay E/IntentService1﹕ --> systime:1433409562119

    那么我们再来看不同的IntentService.每一个不同的IntentService都会新建一个线程,线程之间是独立的(公用资源需要考虑线程同步的问题)。我们可以看到IntentService的线程优先级和主UI线程的优先级一样,都是默认优先级5.(android线程优先级0~10,linux-19~20)

    创建太多IntentService最好改变线程优先级,否则UI线程抢占不到太多cpu资源。

    Intent intent=new Intent(this, IntentService1.class);
    startService(intent);
    startService(intent);
    startService(new Intent(this, IntentService2.class));

    06-04 17:29:28.633 31602-31602/com.alipay E/AM_MEMORYIPROCESS﹕ --> Activity id: 1 ,Activity priority: 5
    06-04 17:29:28.673 31602-31602/com.alipay E/AM_MEMORYIPROCESS﹕ --> onResume
    06-04 17:29:28.693 31602-31602/com.alipay E/IntentService1﹕ --> onCreate
    06-04 17:29:28.693 31602-31602/com.alipay E/IntentService1﹕ --> onStartCommand
    06-04 17:29:28.693 31602-31602/com.alipay E/IntentService1﹕ --> onStart
    06-04 17:29:28.693 31602-31618/com.alipay E/IntentService1﹕ --> onHandleIntent
    06-04 17:29:28.693 31602-31618/com.alipay E/IntentService1﹕ --> IntentService1 id: 2862,Threadpriotiry: 5
    06-04 17:29:28.693 31602-31618/com.alipay E/IntentService1﹕ --> systime:1433410168699
    06-04 17:29:28.693 31602-31602/com.alipay E/IntentService1﹕ --> onStartCommand
    06-04 17:29:28.693 31602-31602/com.alipay E/IntentService1﹕ --> onStart
    06-04 17:29:28.703 31602-31602/com.alipay E/IntentService2﹕ --> onCreate
    06-04 17:29:28.703 31602-31602/com.alipay E/IntentService2﹕ --> onStartCommand
    06-04 17:29:28.703 31602-31602/com.alipay E/IntentService2﹕ --> onStart
    06-04 17:29:28.703 31602-31627/com.alipay E/IntentService2﹕ --> onHandleIntent
    06-04 17:29:28.703 31602-31627/com.alipay E/IntentService2﹕ --> IntentService1 id: 2871,Threadpriotiry: 5
    06-04 17:29:28.713 31602-31627/com.alipay E/IntentService2﹕ --> systime:1433410168715
    06-04 17:31:08.693 31602-31618/com.alipay E/IntentService1﹕ --> onHandleIntent
    06-04 17:31:08.693 31602-31618/com.alipay E/IntentService1﹕ --> IntentService1 id: 2862,Threadpriotiry: 5
    06-04 17:31:08.693 31602-31618/com.alipay E/IntentService1﹕ --> systime:1433410268701
    06-04 17:31:08.713 31602-31602/com.alipay E/IntentService2﹕ --> onDestroy
    06-04 17:32:48.693 31602-31602/com.alipay E/IntentService1﹕ --> onDestroy

     4.需要注意一点 IntentService的构造函数为无参构造。重载super的是为此IntentService的线程命名。

    /**
    * Creates an IntentService. Invoked by your subclass's constructor.
    *
    * @param name Used to name the worker thread, important only for debugging.
    */
    public IntentService1() {
    super("IntentService_1");
    }
  • 相关阅读:
    CSS盒子模型
    getContextPath、getServletPath、getRequestURI、request.getRealPath的区别
    MYSQL中的CASE WHEN END AS
    单点登录的精华总结
    git&github
    June 21st 2017 Week 25th Wednesday
    June 20th 2017 Week 25th Tuesday
    June 19th 2017 Week 25th Monday
    June 18th 2017 Week 25th Sunday
    June 17th 2017 Week 24th Saturday
  • 原文地址:https://www.cnblogs.com/hxy0107/p/4552486.html
Copyright © 2011-2022 走看看