Android Service總結05 之IntentService
| 版本 |
版本說明 |
發布時間 |
發布人 |
| V1.0 |
添加了IntentService的介紹和示例 |
2013-03-17 |
Skywang |
|
|
|
|
|
1 IntentService介紹
IntentService繼承與Service,它最大的特點是對服務請求逐個進行處理。當我們要提供的服務不需要同時處理多個請求的時候,可以選擇繼承IntentService。
IntentService有以下特點:
(1) 它創建了一個獨立的工作線程來處理所有的通過onStartCommand()傳遞給服務的intents。
(2) 創建了一個工作隊列,來逐個發送intent給onHandleIntent()。
(3) 不需要主動調用stopSelft()來結束服務。因為,在所有的intent被處理完后,系統會自動關閉服務。
(4) 默認實現的onBind()返回null
(5) 默認實現的onStartCommand()的目的是將intent插入到工作隊列中。
繼承IntentService的類至少要實現兩個函數:構造函數和onHandleIntent()函數。要覆蓋IntentService的其它函數時,注意要通過super調用父類的對應的函數。
2 IntentService示例
示例說明:編寫一個activity,包含2個按鈕和1個進度條,2個按鈕分別是開始按鈕、結束按鈕。點擊“開始”按鈕:進度條開始加載;“開始”變成“重啟”按鈕;顯示“結束”按鈕(默認情況,“結束”按鈕是隱藏狀態)。
IntentService的示例包括2個類:
IntentServiceSub.java —— 繼承IntentService,並新建一個線程,用於每隔200ms將一個數字+2,並通過廣播發送出去。
IntentServiceTest.java —— 啟動IntentServiceSub服務,接收它發送的廣播,並根據廣播中的數字值來更新進度條。
IntentServiceSub.java的內容如下:
package com.test; import android.app.IntentService; import android.content.Intent; import android.util.Log; import java.lang.Thread; /** * @desc IntentService的實現類:每隔200ms將一個數字+2並通過廣播發送出去 * @author skywang * */ public class IntentServiceSub extends IntentService { private static final String TAG = "skywang-->IntentServiceTest"; // 發送的廣播對應的action private static final String COUNT_ACTION = "com.test.COUNT_ACTION"; // 線程:用來實現每隔200ms發送廣播 private static CountThread mCountThread = null; // 數字的索引 private static int index = 0; public IntentServiceSub() { super("IntentServiceSub"); Log.d(TAG, "create IntentServiceSub"); } @Override public void onCreate() { Log.d(TAG, "onCreate"); super.onCreate(); } @Override public void onDestroy() { Log.d(TAG, "onDestroy"); super.onDestroy(); } @Override protected void onHandleIntent(Intent intent) { Log.d(TAG, "onHandleIntent"); // 非首次運行IntentServiceSub服務時,執行下面操作 // 目的是將index設為0 if ( mCountThread != null) { index = 0; return; } // 首次運行IntentServiceSub時,創建並啟動線程 mCountThread = new CountThread(); mCountThread.start(); } private class CountThread extends Thread { @Override public void run() { index = 0; try { while (true) { // 將數字+2, index += 2; // 將index通過廣播發送出去 Intent intent = new Intent(COUNT_ACTION); intent.putExtra("count", index); sendBroadcast(intent); // Log.d(TAG, "CountThread index:"+index); // 若數字>=100 則退出 if (index >= 100) { if ( mCountThread != null) mCountThread = null; return ; } // 200ms this.sleep(200); } } catch (InterruptedException e) { e.printStackTrace(); } } } }
IntentServiceTest.java的內容如下:
package com.test; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ProgressBar; import android.content.Intent; import android.content.IntentFilter; import android.content.Context; import android.content.BroadcastReceiver; import android.util.Log; /** * @desc 創建一個activity,包含2個按鈕(開始/結束)和1個ProgressBar * 點擊“開始”按鈕,顯示“結束”按鈕,並啟動ProgressBar。 * 點擊“結束”按鈕,結束ProgressBar的進度更新 * @author skywang * */ public class IntentServiceTest extends Activity { /** Called when the activity is first created. */ private static final String TAG = "skywang-->IntentServiceTest"; private static final String COUNT_ACTION = "com.test.COUNT_ACTION"; private CurrentReceiver mReceiver; private Button mStart = null; private Button mStop = null; private Intent mIntent = null; private Intent mServiceIntent = new Intent("com.test.subService"); private ProgressBar mProgressBar = null; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.intent_service_test); mStart = (Button) findViewById(R.id.start); mStart.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View arg0) { Log.d(TAG, "click start button"); // 顯示“結束”按鈕 mStop.setVisibility(View.VISIBLE); // 將“開始”按鈕更名為“重啟”按鈕 mStart.setText(R.string.text_restart); // 啟動服務,用來更新進度 if (mServiceIntent == null) mServiceIntent = new Intent("com.test.subService"); startService(mServiceIntent); } }); mStop = (Button) findViewById(R.id.stop); mStop.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View arg0) { Log.d(TAG, "click stop button"); if (mServiceIntent != null) { // 結束服務。 // 注意:實際上這里並沒有起效果。因為IntentService的特性所致。 // IntentService的聲明周期特別段,在startService()啟動后,立即結束;所以, // 再調用stopService()實際上並沒有起作用,因為服務已經結束! stopService(mServiceIntent); mServiceIntent = null; } } }); mStop.setVisibility(View.INVISIBLE); mProgressBar = (ProgressBar) findViewById(R.id.pbar_def); // 隱藏進度條 mProgressBar.setVisibility(View.INVISIBLE); // 動態注冊監聽COUNT_ACTION廣播 mReceiver = new CurrentReceiver(); IntentFilter filter = new IntentFilter(); filter.addAction(COUNT_ACTION); this.registerReceiver(mReceiver, filter); } @Override public void onDestroy(){ super.onDestroy(); if(mIntent != null) stopService(mIntent); if(mReceiver != null) this.unregisterReceiver(mReceiver); } /** * @desc 更新進度條 * @param index */ private void updateProgressBar(int index) { int max = mProgressBar.getMax(); if (index < max) { // 顯示進度條 mProgressBar.setVisibility(View.VISIBLE); mProgressBar.setProgress(index); } else { // 隱藏進度條 mProgressBar.setVisibility(View.INVISIBLE); // 隱藏“結束”按鈕 mStop.setVisibility(View.INVISIBLE); // 將“重啟”按鈕更名為“開始”按鈕 mStart.setText(R.string.text_start); } // Log.d(TAG, "progress : "+mProgressBar.getProgress()+" , max : "+max); } /** * @desc 廣播:監聽COUNT_ACTION,獲取索引值,並根據索引值來更新進度條 * @author skywang * */ private class CurrentReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (COUNT_ACTION.equals(action)) { int index = intent.getIntExtra("count", 0); updateProgressBar(index); } } } }
layout文件intent_service_test.xml的內容如下:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" > <LinearLayout android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content" > <Button android:id="@+id/start" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/text_start" /> <Button android:id="@+id/stop" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/text_stop" /> </LinearLayout> <ProgressBar android:id="@+id/pbar_def" android:layout_width="match_parent" android:layout_height="wrap_content" style="@android:style/Widget.ProgressBar.Horizontal" android:max="100" android:progress="0" /> </LinearLayout>
manifest代碼如下:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.test" android:versionCode="1" android:versionName="1.0"> <uses-sdk android:minSdkVersion="8" /> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".IntentServiceTest" android:screenOrientation="portrait" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <service android:name=".IntentServiceSub"> <intent-filter> <action android:name="com.test.subService" /> </intent-filter> </service> </application> </manifest>
點擊下載:示例源代碼
程序截圖如下:

更多service內容:
2 Android Service總結02 service介紹
3 Android Service總結03 之被啟動的服務 -- Started Service
4 Android Service總結04 之被綁定的服務 -- Bound Service
5 Android Service總結05 之IntentService
參考文獻:
1,Android API文檔: http://developer.android.com/guide/components/services.html
