Android IntentService解析
Android IntentService解析
在開發(fā)安卓應(yīng)用程序時,除非你指定,否則絕大部分執(zhí)行動作都運(yùn)行UI線程中。這種機(jī)制會引發(fā)一些問題,因為耗時操作會妨礙用戶交互行為。這會讓用戶感到懊惱,甚至引發(fā)ANR錯誤。幸運(yùn)的是,Android框架提供了一些類,它幫助我們把這些耗時的操作到轉(zhuǎn)移到后臺線程中去了。個人覺得最有用的是IntentService類了,但I(xiàn)ntentServce也有它的幾個局限性:
1. 它不能和用戶界面直接交互,你必須把執(zhí)行的結(jié)果發(fā)送到Activity中
2. 發(fā)送給IntentService的請求是有序的。如果IntentService正在處理任務(wù)A,而你又發(fā)送了一個任務(wù)B請求,此時IntentService只有等到執(zhí)行完任務(wù)A后才會執(zhí)行任務(wù)B。
3. IntentService中正在運(yùn)行的操作不能被中斷。
盡管IntentService有些局限性,但執(zhí)行簡單的后臺操作是一個比較好的選擇,下面為大家講述如何使用IntentService。
創(chuàng)建一個IntenService
創(chuàng)建一個IntentService非常簡單,只要寫一個繼承IntentService的類即可,并實現(xiàn)構(gòu)造方法以及onHandleIntent(Intent workIntent)抽象方法即可。
public class RSSPullService extends IntentService {/*** A constructor is required, and must call the super IntentService(String)* constructor with a name for the worker thread.*/public RSSPullService () {super("HelloRSSPullService");}@Overrideprotected void onHandleIntent(Intent workIntent) {// Gets data from the incoming IntentString dataString = workIntent.getDataString();...// Do work here, based on the contents of dataString. ...} }因為onHandleIntent(Intent workIntent)方法運(yùn)行在后臺一個線程中,你可以把耗時的任務(wù)轉(zhuǎn)到此處而不必?fù)?dān)心它會阻塞UI線程。任務(wù)做完后它會自動停止服務(wù)。
注冊IntentService
僅僅創(chuàng)建了IntentService依然無法使用,你需要在清單文件中去注冊它。
<applicationandroid:icon="@drawable/icon"android:label="@string/app_name">...<!--Because android:exported is set to "false",the service is only available to this app.--><serviceandroid:name=".RSSPullService"android:exported="false"/>... <application/>現(xiàn)在你寫的IntentService類就可以使用了,那么怎樣使用呢?很簡單,你可以通過一個顯式意圖去啟動IntentService,你可以在意圖中添加相關(guān)的數(shù)據(jù)以支持你的業(yè)務(wù)邏輯。
/** Creates a new Intent to start the RSSPullService* IntentService. Passes a URI in the* Intent's "data" field.*/ mServiceIntent = new Intent(getActivity(), RSSPullService.class); mServiceIntent.setData(Uri.parse(dataUrl));// Starts the IntentService getActivity().startService(mServiceIntent);一旦你調(diào)用了startService(),IntentService就會執(zhí)行onHandleIntent(),任務(wù)結(jié)束后服務(wù)也就自動停止。
在IntentService中發(fā)送廣播
那么耗時的任務(wù)數(shù)據(jù)狀態(tài)通過怎樣的形式才能呈現(xiàn)給用戶呢?一種方式是你可以通過發(fā)送廣播來實現(xiàn)。通過廣播將任務(wù)產(chǎn)生的狀態(tài)數(shù)據(jù)發(fā)送到廣播接收器,在接收器中可以將數(shù)據(jù)呈現(xiàn)到UI上。
public final class Constants {...// Defines a custom Intent actionpublic static final String BROADCAST_ACTION ="com.example.android.threadsample.BROADCAST";...// Defines the key for the status "extra" in an Intentpublic static final String EXTENDED_DATA_STATUS ="com.example.android.threadsample.STATUS";... } public class RSSPullService extends IntentService { .../** Creates a new Intent containing a Uri object* BROADCAST_ACTION is a custom Intent action*/Intent localIntent =new Intent(Constants.BROADCAST_ACTION)// Puts the status into the Intent.putExtra(Constants.EXTENDED_DATA_STATUS, status);// Broadcasts the Intent to receivers in this app.LocalBroadcastManager.getInstance(this).sendBroadcast(localIntent); ... }接受廣播發(fā)送過來的數(shù)據(jù)
為了接受廣播發(fā)送過來的數(shù)據(jù),你需要創(chuàng)建一個類,該類繼承BroadcastReceiver類,并實現(xiàn)onReceive()方法。
// Broadcast receiver for receiving status updates from the IntentService private class ResponseReceiver extends BroadcastReceiver {// Prevents instantiationprivate DownloadStateReceiver() {}// Called when the BroadcastReceiver gets an Intent it's registered to receive@public void onReceive(Context context, Intent intent) { .../** Handle Intents here.* you can display data to UI*/ ...} }廣播接收器一旦定義好后,你可以定義過濾器以區(qū)分動作事件
// Class that displays photos public class DisplayActivity extends FragmentActivity {...public void onCreate(Bundle stateBundle) {...super.onCreate(stateBundle);...// The filter's action is BROADCAST_ACTIONIntentFilter mStatusIntentFilter = new IntentFilter(Constants.BROADCAST_ACTION);// Adds a data filter for the HTTP schememStatusIntentFilter.addDataScheme("http");...要保證廣播接收器能夠接受到消息,必須對其進(jìn)行注冊,一般在Activity中onCreate()中對其進(jìn)行注冊,在onDestory()中注銷。
// Class that displays photos public class DisplayActivity extends FragmentActivity {...public void onCreate(Bundle stateBundle) {...super.onCreate(stateBundle);...// The filter's action is BROADCAST_ACTIONIntentFilter mStatusIntentFilter = new IntentFilter(Constants.BROADCAST_ACTION);// Adds a data filter for the HTTP schememStatusIntentFilter.addDataScheme("http");// Instantiates a new DownloadStateReceiverDownloadStateReceiver mDownloadStateReceiver =new DownloadStateReceiver();// Registers the DownloadStateReceiver and its intent filtersLocalBroadcastManager.getInstance(this).registerReceiver(mDownloadStateReceiver,mStatusIntentFilter);}public void onDestory(){super.onDestory();LocalBroadcastManager.getInstance(this).unregisterReceiver(mDownloadStateReceiver);}LocalBroadcastManager發(fā)送的廣播只能在程序內(nèi)被接受因此它能夠有效減低信息泄露。
總結(jié)
以上是生活随笔為你收集整理的Android IntentService解析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android 优化电池使用时间——根据
- 下一篇: Android 使用RadioButto