请把我忽略 發表於 2019-9-28 02:31:00

Android开发--IntentService的用法,你错过了什么

<div class="article-header-box">
<div class="article-header">
<div class="article-title-box">
<h1 class="title-article">Android开发--IntentService的用法,你错过了什么</h1>
</div>
<div class="article-info-box">
<div class="article-bar-top"><span class="time"><span class="time">。</span></span></div>
</div>
</div>
</div>
<div id="article_content" class="article_content clearfix">
<div class="article-copyright">
<div class="article-source-link2222">本文链接:https://blog.csdn.net/smbroe/article/details/45009721</div>
</div>
<div id="content_views" class="markdown_views">
<p>IntentService是Android中提供的后台服务类,我们在外部组件中通过Intent向IntentService发送请求命令,之后IntentService逐个执行命令队列里的命令,接收到首个命令时,IntentService就开始启动并开始一条后台线程执行首个命令,接着队列里的命令将会被顺序执行,最后执行完队列的所有命令后,服务也随即停止并被销毁。</p>
<h2 id="与service的不同">与Service的不同</h2>
<ol>
<li>Service中的程序仍然运行于主线程中,而在IntentService中的程序运行在我们的异步后台线程中。在接触到IntentService之前,我在项目中大多是自己写一个Service,在Service中自己写一个后台线程去处理相关事务,而这些工作Android其实早已经帮我们封装的很好。</li>
<li>在Service中当我的后台服务执行完毕之后需要在外部组件中调用stopService方法销毁服务,而IntentService并不需要,它会在工作执行完毕后自动销毁。</li>
</ol>
<h2 id="intentservice的用法">IntentService的用法</h2>
<p>1.编写自己的Service类继承IntentService,并重写其中的onHandleIntent(Intent)方法,该方法是IntentService的一个抽象方法,用来处理我们通过startService方法开启的服务,传入参数Intent就是开启服务的Intent。在这里我重写了一个MyService类去处理后台事务,每一次调用对count加1,并打印log。</p>
<pre name="code" class="prettyprint"><code class="hljs java has-numbering"><span class="hljs-keyword">package com.example.intentservicetest;

<span class="hljs-keyword">import android.app.IntentService;
<span class="hljs-keyword">import android.content.Intent;
<span class="hljs-keyword">import android.util.Log;

<span class="hljs-keyword">public <span class="hljs-class"><span class="hljs-keyword">class <span class="hljs-title">MyService <span class="hljs-keyword">extends <span class="hljs-title">IntentService {

    <span class="hljs-keyword">private <span class="hljs-keyword">static <span class="hljs-keyword">final String TAG = MyService.class.getSimpleName();

    <span class="hljs-keyword">private <span class="hljs-keyword">int count = <span class="hljs-number">0;

    <span class="hljs-keyword">public <span class="hljs-title">MyService() {
      <span class="hljs-keyword">super(TAG);
      <span class="hljs-comment">// TODO Auto-generated constructor stub
    }

    <span class="hljs-annotation">@Override
    <span class="hljs-keyword">protected <span class="hljs-keyword">void <span class="hljs-title">onHandleIntent(Intent intent) {
      <span class="hljs-comment">// TODO Auto-generated method stub
      <span class="hljs-comment">//在这里添加我们要执行的代码,Intent中可以保存我们所需的数据,
      <span class="hljs-comment">//每一次通过Intent发送的命令将被顺序执行
      count ++;
      Log.w(TAG, <span class="hljs-string">"count::" + count);
    }
}</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<p>2.注册我们的服务:接下来在AndroidManifest文件中的Application标签下添加我们的服务。</p>
<pre name="code" class="prettyprint"><code class="hljs xml has-numbering"><span class="hljs-tag">&lt;<span class="hljs-title">service <span class="hljs-attribute">android:name=<span class="hljs-value">"com.example.intentservicetest.MyService" /&gt;</span></span></span></span></code></pre>
<ul class="pre-numbering">
<li>1</li>
</ul>
<p>3.在外部组件中开启服务:在这里我们在Activity中利用Intent循环10次开启服务。</p>
<pre name="code" class="prettyprint"><code class="hljs d has-numbering"><span class="hljs-keyword">for (<span class="hljs-keyword">int i = <span class="hljs-number">0; i &lt; <span class="hljs-number">10; i++) {
      Intent intent = <span class="hljs-keyword">new Intent(MainActivity.<span class="hljs-keyword">this, MyService.<span class="hljs-keyword">class);
      startService(intent);
}</span></span></span></span></span></span></span></code></pre>
<p>4.结果输出:<br><img src="https://img-blog.csdn.net/20150412141604001"></p>
<p>可以看到在MyService中是按照顺序执行我们的请求命令的。</p>
<h2 id="原理分析">原理分析</h2>
<p>1.生命周期函数:<br>IntentService同样是继承于Service的,它也拥有相同的生命周期函数;</p>
<ul>
<li>onCreate:服务创建时调用;</li>
<li>onStartCommand(Intent, int, int)方法:在Service源码可以看到onStart方法是在该方法中被调用的。每次组件通过startService方法启动服务时调用一次,两个int型参数,一个是组标识符,一个是启动ID,组标识符用来表示当前Intent发送是一次重新发送还是一次从没成功过的发送。每次调用onStartCommand方法时启动ID都不同,启动ID也用来区分不同的命令;</li>
<li>onDestroy方法:在服务停止时调用。</li>



</ul>
<p>2.onCreate方法:首先让我们看看IntentService源码中的onCreate方法,</p>
<pre name="code" class="prettyprint"><code class="hljs java has-numbering">    <span class="hljs-annotation">@Override
    <span class="hljs-keyword">public <span class="hljs-keyword">void <span class="hljs-title">onCreate() {
      <span class="hljs-keyword">super.onCreate();

      HandlerThread thread = <span class="hljs-keyword">new HandlerThread(<span class="hljs-string">"IntentService[" + mName + <span class="hljs-string">"]");
      thread.start();

      mServiceLooper = thread.getLooper();
      mServiceHandler = <span class="hljs-keyword">new ServiceHandler(mServiceLooper);
}</span></span></span></span></span></span></span></span></span></code></pre>
<p>可以看到:在IntentService的onCreate方法中开启了一个异步线程HandlerThread来处理我们的请求,并利用Looper和Handler来管理我们的请求命令队列。关于HandlerThread的用法可以参考以下博文:Android源码分析–Handler和Looper机制详解&nbsp;。</p>
<p>3.如何停止服务<br>看到了onCreate方法我们就可以明白了,IntentService是如何开启异步线程以及如何管理命令队列的,那么我们之前曾提到:当后台服务处理结束后,我们并不需要再调用stopService方法销毁服务,IntentService会自动销毁,它是如何做到的呢?然我们看看ServiceHandler:</p>
<pre name="code" class="prettyprint"><code class="hljs java has-numbering"><span class="hljs-keyword">private <span class="hljs-keyword">final <span class="hljs-class"><span class="hljs-keyword">class <span class="hljs-title">ServiceHandler <span class="hljs-keyword">extends <span class="hljs-title">Handler {
      <span class="hljs-keyword">public <span class="hljs-title">ServiceHandler(Looper looper) {
            <span class="hljs-keyword">super(looper);
      }

      <span class="hljs-annotation">@Override
      <span class="hljs-keyword">public <span class="hljs-keyword">void <span class="hljs-title">handleMessage(Message msg) {
            onHandleIntent((Intent)msg.obj);
            stopSelf(msg.arg1);
      }
    }</span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<p>在Handler中我们处理完每一个命令都会调用stopSelf(int)方法来停止服务:该方法需要来自onStartCommand方法中的启动ID,只有在接收到最新的启动ID时才会停止服务,就是说,我们的IntentService直到命令队列中的所有命令被执行完后才会停止服务。</p>
<h2 id="setintentredelivery方法">setIntentRedelivery方法</h2>
<p>在源码中我们可以发现,该方法改变了boolean变量mRedelivery的值,而mRedelivery得值关系到onStartCommand的返回变量:</p>
<pre name="code" class="prettyprint"><code class="hljs java has-numbering"><span class="hljs-annotation">@Override
<span class="hljs-keyword">public <span class="hljs-keyword">int <span class="hljs-title">onStartCommand(Intent intent, <span class="hljs-keyword">int flags, <span class="hljs-keyword">int startId) {
    onStart(intent, startId);
    <span class="hljs-keyword">return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}</span></span></span></span></span></span></span></code></pre>
<p>可以看到,mRedelivery不同,会返回两个不同的标志START_REDELIVER_INTENT 和START_NOT_STICKY,那么他们有什么不同呢?<br>区别就在于如果系统在服务完成之前关闭它,则两种类型就表现出不同了:</p>
<ul>
<li>START_NOT_STICKY型服务会直接被关闭,而START_REDELIVER_INTENT 型服务会在可用资源不再吃紧的时候尝试再次启动服务。</li>
<li>由此我们可以发现,当我们的操作不是十分重要的时候,我们可以选择START_NOT_STICKY,这也是IntentService的默认选项,当我们认为操作十分重要时,则应该选择START_REDELIVER_INTENT 型服务。</li>



</ul>
<h2 id="non-sticky服务和sticky服务">non-sticky服务和sticky服务</h2>
<p>non-sticky服务会在自己认为任务完成时停止,若一个Service为non-sticky服务则应该在onStartCommand方法中返回START_REDELIVER_INTENT或START_NOT_STICKY标志。<br>sticky服务会持续存在,直到外部组件调用Context.stopService方法。sticky服务返回标志位START_STICKY。</p>
<p>注意:IntentService不应该处理长时间运行的服务(如音乐播放),长时间运行的服务应该由sticky服务完成。</p>
<hr>
<h1>常用软件开发学习资料目录(详见我爱分享资源论坛):&nbsp;&nbsp;</h1>
<h1>1.经典编程电子书收藏&nbsp;&nbsp;</h1>
<h1>2.C&amp;C++编程学习资料收藏&nbsp;&nbsp;&nbsp;</h1>
<h1>3.算法及数据结构(有关c,c++,java)&nbsp;&nbsp;&nbsp;</h1>
<h1>4.Java开发学习资料收藏&nbsp; &nbsp; &nbsp;&nbsp;</h1>
<h1>5.Android开发学习资料收藏&nbsp;&nbsp;</h1>
<h1>6.Python开发学习资料收藏&nbsp;&nbsp;</h1>
<h1>7.大数据,机器学习,人工智能资料收藏</h1>
<h1>8.Docker资料收藏</h1>



</div>



</div><br><br>
来源:https://www.cnblogs.com/it-tsz/p/11601265.html
頁: [1]
查看完整版本: Android开发--IntentService的用法,你错过了什么