Android學習筆記二十五.Service組件入門(三)使用IntentService

來源:互聯網
上載者:User

標籤:android開發

使用IntentService 1.Service缺陷    由於Service本身存在以下兩個問題:    (1)Service不會專門啟動一條單獨的進程,Service與他所在應用位於同一進程中;    (2)Service也不是專門一條新的線程,如果我們在Service中直接處理耗時的任務,那麼就會導致應用程式出現假性"卡死"。如果我們需要在Service處理耗時任務,也可以在Service的onCreate()方法中啟動一條新線程來處理該耗時任務(如上例)。但是,問題來了,啟動Service的Activity可能隨時被使用者退出,如果在子線程還沒有結束的情況下,Activity已經被使用者退出了,此時那些子線程所在的進程就變成了空進程(即沒有任何活動組件的進程),系統需要記憶體時可能會優先終止該進程。如果宿主進程被終止,那麼該進程內的所有子線程也會被終止,這樣就可能導致子線程無法執行完成。 2.IntentService原理    IntetnService是Service的子類,它不是普通的Service,通過IntentService恰好彌補了Service上述的兩個不足。IntentService主要使用隊列來管理請求Intent,每當用戶端代碼通過Intent請求啟動IntentService時,IntentService會將該Intent排入佇列中,然後開啟一條新的worker線程來處理該Intent。對於非同步startService()請求,IntentService會按次序依次處理隊列中的Intent,該線程保證同一時刻只處理一個Intent。由於IntentService使用新的worker線程處理Intent請求,因此IntentService不會阻塞主線程,所有IntentService自己就可以處理耗時任務了。 3.IntentService使用特徵(1)IntentService會建立單獨的worker線程來處理所有的Intent請求;(2)IntentService會建立單獨的worker線程來處理onHandleIntent()方法實現的代碼,因此開發人員無需處理多線問題;(3)當所有請求處理完成後,IntentService會自動停止,因此開發人員無須調用StopSelf()方法來停止該Service。(4)為Service的onBind()方法提供了預設實現,預設實現的onBind()方法返回null;(5)為Service的onStartCommand()方法提供了預設實現,該實現會將請求Intent添加到隊列中。注釋:擴充IntentService實現Service無須重寫onBind()、onStartCommand()方法,只要重寫onHandleIntent()方法即可。 4.源碼實戰實現:分別啟動普通Service和IntentService,且同時處理耗時任務,對比兩者效果。(1)\src\com\example\android_intentservice\ServiceAndIntentService.java實現:通過兩個按鈕分別啟動普通Service和IntentService
package com.example.android_intentservice;import android.app.Activity;import android.content.Intent;import android.os.Bundle;import android.view.View;public class ServiceAndIntentService extends Activity { @Override protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.main); } //1.啟動普通Service按鈕方法 public void startService(View source) {  Intent intent = new Intent(this,MyService.class);//建立需要啟動的service的Intent  startService(intent); //啟動Intent指定的Service } //2.啟動IntentService按鈕方法 public void startIntentService(View source) {  Intent intent = new Intent(this,MyIntentService.class);  startService(intent); }}
(2)\res\layout\main.xml實現:設定Button屬性android:onClick,為按鈕綁定回應程式法   
 ......  <Button      android:onClick="startService"      android:layout_width="wrap_content"      android:layout_height="wrap_content"      android:text="啟動普通Service" />  <Button          android:onClick="startIntentService"          android:layout_width="186dp"          android:layout_height="wrap_content"          android:text="啟動IntentService" />
(3)\src\com\example\android_intentservice\MyService.java實現:實現一個普通Service執行耗時任務(20s),觀察是否導致ANR異常(Application Not Responding)
package com.example.android_intentservice;import android.app.Service;import android.content.Intent;import android.os.IBinder;public class MyService extends Service { @Override public IBinder onBind(Intent intent) {  return null; } //當啟動Service,調用該方法執行相應代碼 @Override public int onStartCommand(Intent intent, int flags, int startId) {  long endTime = System.currentTimeMillis()+20*1000;  System.out.println("onStart");  while(System.currentTimeMillis()<endTime)  {   synchronized(this)   {    try    {     wait(endTime-System.currentTimeMillis());    }catch(Exception e)    {    }   }  }  System.out.println("---普通Service耗時任務執行完成---");  return START_STICKY; } }
(4)\src\com\example\android_intentservice\MyIntentService.java實現:實現一個IntentService執行耗時任務(20s),觀察是否導致ANR異常
package com.example.android_intentservice;import android.app.IntentService;import android.content.Intent;public class MyIntentService extends IntentService { public MyIntentService() {  super("MyIntentService"); } //IntentService會使用單獨的線程來執行方法的代碼 @Override protected void onHandleIntent(Intent intent) {  //該方法內可以執行任何耗時任務,比如下載檔案等,此處只是讓線程暫停20s  long endTime = System.currentTimeMillis()+20*1000;  System.out.println("onStart");  while(System.currentTimeMillis()<endTime)  {   synchronized(this)   {    try    {     wait(endTime-System.currentTimeMillis());    }catch(Exception e)    {    }   }  }  System.out.println("---IntentService耗時任務執行完成---"); }}


(5)AndroidManifest.xml實現:在工程檔案中為MyService、MyIntentService配置<service../>資訊  
  <application        android:allowBackup="true"        android:icon="@drawable/ic_launcher"        android:label="@string/app_name"        android:theme="@style/AppTheme" >        <activity          ..........        </activity>        <!--配置service-->        <service android:name=".MyService"/>        <service android:name=".MyIntentService"/>    </application>

效果示範:a.當點擊"啟動普通service"時的效果
b.連續點擊7次"啟動IntentService"的效果

升華筆記:1.普通Service是在onStartCommand()方法內執行耗時任務;IntentService在onHandleIntent()方法內執行耗時任務;2.普通Service在沒有建立一個新線程的情況下,其執行耗時任務主要是在應用程式的主線程中完成的,由於普通Service的執行會阻塞主線程,因此啟動該Service執行耗時任務會導致程式出現ANR異常;3.IntentService主要使用隊列來管理請求Intent,每當用戶端代碼通過Intent請求啟動IntentService時,IntentService會將該Intent排入佇列中,然後開啟一條新的worker線程來處理該Intent。由於IntentService會使用單獨的線程來完成該耗時任務,因此啟動MyIntentService不會阻塞前台線程,程式介面就不會失去響應。
參考:http://wear.techbrood.com/reference/android/app/Service.html

Android學習筆記二十五.Service組件入門(三)使用IntentService

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.