service,android四大元件之一,脫離UI在背景運作。特點和具體如何使用無需多言吧。
一,service是個什麼鬼
Service(服務)是一個沒有使用者界面的在背景運作執行耗時操作的應用元件。其他應用元件能夠啟動Service,并且當使用者切換到另外的應用場景,Service将持續在背景運作。另外,一個元件能夠綁定到一個service與之互動(IPC機制),例如,一個service可能會處理網絡操作,播放音樂,操作檔案I/O或者與内容提供者(content provider)互動,所有這些活動都是在背景進行。
Started Service生命周期及程序相關
1.onCreate(Client首次startService(..)) >> onStartCommand >> onStartCommand - optional … >> onDestroy(Client調用stopService(..))
注:onStartCommand(..)可以多次被調用,onDestroy()與onCreate()想比對,當使用者強制kill掉程序時,onDestroy()是不會執行的。
2.對于同一類型的Service,Service執行個體一次永遠隻存在一個,而不管Client是否是相同的元件,也不管Client是否處于相同的程序中。
3.Service通過startService(..)啟動Service後,此時Service的生命周期與Client本身的什麼周期是沒有任何關系的,隻有Client調用stopService(..)或Service本身調用stopSelf(..)才能停止此Service。當然,當使用者強制kill掉Service程序或系統因記憶體不足也可能kill掉此Service。
4.Client A 通過startService(..)啟動Service後,可以在其他Client(如Client B、Client C)通過調用stopService(..)結束此Service。
5.Client調用stopService(..)時,如果目前Service沒有啟動,也不會出現任何報錯或問題,也就是說,stopService(..)無需做目前Service是否有效的判斷。
6.startService(Intent serviceIntent),其中的intent既可以是顯式Intent,也可以是隐式Intent,當Client與Service同處于一個App時,一般推薦使用顯示Intent。當處于不同App時,隻能使用隐式Intent。
在AndroidManifest.xml檔案中注冊service。
<!--apk更新,自動備份,監測網絡狀态-->
<service android:name="com.x x.service.OairService">
<intent-filter>
<action android:name="com.x x.oairService.action"/>
</intent-filter>
</service>
service實作類,繼承Service。
/**
* DemoService 生命周期方法
* Created by duqian on 16/5/11.
*/
public class DemoService extends Service {
private Context context;
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
}
@Override
public void onCreate() {
super.onCreate();
context = getApplicationContext();
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public boolean onUnbind(Intent intent) {
return super.onUnbind(intent);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
}
二,service一些常用方法
開啟和停止service,要注意相容android 5.0以上版本,服務啟動要設定你應用的包名,否則會報錯,閃退。
/**
* service 工具類
* Created by duqian on 15/12/28.
*/
public class ServiceUtil {
private static final String TAG =ServiceUtil.class.getSimpleName();
//開啟服務:
public static void startService(Context context,Class clazz) {
boolean serviceRunning = SystemUtils.isServiceRunning(context, clazz);
if (serviceRunning){
forceStopService(context,clazz);//先停止再開啟:重新開機服務,防止服務失效。
}
Intent service = new Intent(context, clazz);
//Intent service = new Intent();
//service.setAction("com.oair.oairService.action");
service.setPackage(context.getPackageName());//這裡你需要設定你應用的包名,5.0新要求
context.startService(service);//多次調用startService并不會啟動多個service 而是會多次調用onStart
}
/**
* 停止service
* @param context
* @param clazz
*/
public static void stopService(Context context,Class clazz) {
boolean serviceRunning = SystemUtils.isServiceRunning(context, clazz);
if (serviceRunning){
forceStopService(context, clazz);
}
}
private static void forceStopService(Context context, Class clazz) {
Intent intent = new Intent(context, clazz);
intent.setPackage(context.getPackageName());//這裡你需要設定你應用的包名,5.0新要求
context.stopService(intent);
//LogUtils.debug(TAG,clazz.getSimpleName()+" is stopped");
}
/**
* service中檢測本應用是否為前台界面
* @param context
* @return
*/
public static boolean checkAppRunning(Context context) {
boolean isRunning = false;
ActivityManager activityManager = (ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);
ComponentName cn = activityManager.getRunningTasks().get().topActivity;
String topPackageName = cn.getPackageName();
String myPackageName = context.getPackageName();
if (topPackageName != null && topPackageName.equals(myPackageName)) {
//在這裡停止含有定時執行的服務,在停止之前需要先取消該定時器
isRunning = true;
//LogUtils.debug(TAG,"目前棧頂應用:" + topPackageName + ",myPackageName=" + myPackageName);
}else{
isRunning = false;
}
return isRunning;
}
}
三,service相關常識
startService 啟動的服務,主要用于啟動一個服務執行背景任務,不進行通信。停止服務使用stopService。
bindService 啟動的服務,要進行通信。停止服務使用unbindService。
startService 同時也 bindService 啟動的服務,停止服務應同時使用stopService與unbindService。
android中打造不死的service比較麻煩,因為非前台程序會被系統kill。
重點關注下onStartCommand(Intent intent, int flags, int startId)方法。
其中參數flags預設情況下是0,對應的常量名為START_STICKY_COMPATIBILITY。startId是一個唯一的整型,用于表示此次Client執行startService(…)的請求請求辨別,在多次startService(…)的情況下,呈現0,1,2….遞增。另外,此函數具有一個int型的傳回值,具體的可選值及含義如下:
START_NOT_STICKY:當Service因為記憶體不足而被系統kill後,接下來未來的某個時間内,即使系統記憶體足夠可用,系統也不會嘗試重新建立此Service。除非程式中Client明确再次調用startService(…)啟動此Service。
START_STICKY:當Service因為記憶體不足而被系統kill後,接下來未來的某個時間内,當系統記憶體足夠可用的情況下,系統将會嘗試重新建立此Service,一旦建立成功後将回調onStartCommand(…)方法,但其中的Intent将是null,pendingintent除外。
START_REDELIVER_INTENT:與START_STICKY唯一不同的是,回調onStartCommand(…)方法時,其中的Intent将是非空,将是最後一次調用startService(…)中的intent。
歡迎交流,杜工,Dusan,Q291902259。