編輯:關於Android編程
IntentService是Android中提供的後台服務類,我們在外部組件中通過Intent向IntentService發送請求命令,之後IntentService逐個執行命令隊列裡的命令,接收到首個命令時,IntentService就開始啟動並開始一條後台線程執行首個命令,接著隊列裡的命令將會被順序執行,最後執行完隊列的所有命令後,服務也隨即停止並被銷毀。
1.編寫自己的Service類繼承IntentService,並重寫其中的onHandleIntent(Intent)方法,該方法是IntentService的一個抽象方法,用來處理我們通過startService方法開啟的服務,傳入參數Intent就是開啟服務的Intent。在這裡我重寫了一個MyService類去處理後台事務,每一次調用對count加1,並打印log。
package com.example.intentservicetest;
import android.app.IntentService;
import android.content.Intent;
import android.util.Log;
public class MyService extends IntentService {
private static final String TAG = MyService.class.getSimpleName();
private int count = 0;
public MyService() {
super(TAG);
// TODO Auto-generated constructor stub
}
@Override
protected void onHandleIntent(Intent intent) {
// TODO Auto-generated method stub
//在這裡添加我們要執行的代碼,Intent中可以保存我們所需的數據,
//每一次通過Intent發送的命令將被順序執行
count ++;
Log.w(TAG, "count::" + count);
}
}
2.注冊我們的服務:接下來在AndroidManifest文件中的Application標簽下添加我們的服務。
3.在外部組件中開啟服務:在這裡我們在Activity中利用Intent循環10次開啟服務。
for (int i = 0; i < 10; i++) {
Intent intent = new Intent(MainActivity.this, MyService.class);
startService(intent);
}
4.結果輸出:
可以看到在MyService中是按照順序執行我們的請求命令的。<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxoMiBpZD0="原理分析"> 原理分析
1.生命周期函數:
IntentService同樣是繼承於Service的,它也擁有相同的生命周期函數;
2.onCreate方法:首先讓我們看看IntentService源碼中的onCreate方法,
@Override
public void onCreate() {
super.onCreate();
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
可以看到:在IntentService的onCreate方法中開啟了一個異步線程HandlerThread來處理我們的請求,並利用Looper和Handler來管理我們的請求命令隊列。關於HandlerThread的用法可以參考以下博文:Android源碼分析–Handler和Looper機制詳解 。
3.如何停止服務
看到了onCreate方法我們就可以明白了,IntentService是如何開啟異步線程以及如何管理命令隊列的,那麼我們之前曾提到:當後台服務處理結束後,我們並不需要再調用stopService方法銷毀服務,IntentService會自動銷毀,它是如何做到的呢?然我們看看ServiceHandler:
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
onHandleIntent((Intent)msg.obj);
stopSelf(msg.arg1);
}
}
在Handler中我們處理完每一個命令都會調用stopSelf(int)方法來停止服務:該方法需要來自onStartCommand方法中的啟動ID,只有在接收到最新的啟動ID時才會停止服務,就是說,我們的IntentService直到命令隊列中的所有命令被執行完後才會停止服務。
在源碼中我們可以發現,該方法改變了boolean變量mRedelivery的值,而mRedelivery得值關系到onStartCommand的返回變量:
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
onStart(intent, startId);
return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}
可以看到,mRedelivery不同,會返回兩個不同的標志START_REDELIVER_INTENT 和START_NOT_STICKY,那麼他們有什麼不同呢?
區別就在於如果系統在服務完成之前關閉它,則兩種類型就表現出不同了:
non-sticky服務會在自己認為任務完成時停止,若一個Service為non-sticky服務則應該在onStartCommand方法中返回START_REDELIVER_INTENT或START_NOT_STICKY標志。
sticky服務會持續存在,直到外部組件調用Context.stopService方法。sticky服務返回標志位START_STICKY。
注意:IntentService不應該處理長時間運行的服務(如音樂播放),長時間運行的服務應該由sticky服務完成。
listview實現上拉加載以及下拉刷新的方式有很多。下面是我寫的一種自定義的布局,復用性也比較的強。首先就是繼承的listview的自定義view。 &nbs
在Android開發中,我們經常會遇到這樣一種情況:在UI界面上進行某項操作後要執行一段很耗時的代碼,比如我們在界面上點擊了一個”下載“按鈕,那麼
本教程為大家分享了Android日歷庫的使用方法,供大家參考,具體內容如下MainActivity.java代碼:package siso.weekv;import an
隨著Android應用增多,功能越來越復雜,布局也越來越豐富了,而這些也成為了阻礙一個應用流暢運行,因此,對復雜的功能進行性能優化是創造高質量應用的基礎,本