• 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");
    }
  • 相关阅读:
    docker安装 与 基本配置
    linux 挂载windows ntfs 分区 -- centos 安装ntfs-3g
    Linux find 用法示例
    linux之sed用法
    js -ajax 学习
    搭建SSH框架整合Struts2和Spring时,使用@Autowired注解无法自动注入
    Hibernate学习之属性级别注解
    Hibernate学习之类级别注解
    org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]
    Hibernate学习之二级缓存
  • 原文地址:https://www.cnblogs.com/hxy0107/p/4552486.html
Copyright © 2020-2023  润新知