android service,服務的正確姿勢
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(1).get(0).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。
相關文章
- 開發函式計算的正確姿勢——OCR 服務函式
- Android 執行緒的正確使用姿勢Android執行緒
- Redis的正確使用姿勢Redis
- Postman 正確使用姿勢Postman
- git commit 的正確姿勢GitMIT
- 玩轉 Ceph 的正確姿勢
- 開啟Git的正確姿勢Git
- laravel 使用 es 的正確姿勢Laravel
- java關流的正確姿勢Java
- 使用快取的正確姿勢快取
- Fragment commit 的正確姿勢FragmentMIT
- 從 Android 靜音看正確的查bug的姿勢?Android
- 解讀mysql的索引和事務的正確姿勢MySql索引
- Android Studio 專案匯入的正確姿勢Android
- 原始碼|使用FutureTask的正確姿勢原始碼
- 相容iphone x劉海的正確姿勢iPhone
- npm run dev 的正確使用姿勢NPMdev
- 限制UITextField字數的正確姿勢UI
- 使用 Java 8 Optional 的正確姿勢Java
- 解鎖 Redis 鎖的正確姿勢Redis
- MySQL 5.6建索引的正確姿勢MySql索引
- Python 操作 MySQL 的正確姿勢PythonMySql
- 解鎖redis鎖的正確姿勢Redis
- 演算法分析的正確姿勢演算法
- Android 效能優化(十一)之正確的非同步姿勢Android優化非同步
- Java日誌正確使用姿勢Java
- 掌握Redis分散式鎖的正確姿勢Redis分散式
- Pwn掉智慧手錶的正確姿勢
- Spring Boot使用AOP的正確姿勢Spring Boot
- Flutter 錯誤捕獲的正確姿勢Flutter
- 使用 react Context API 的正確姿勢ReactContextAPI
- 實現Flutter彈窗的正確姿勢..Flutter
- 區塊鏈的正確開啟姿勢區塊鏈
- Git Bash 提交程式碼的正確姿勢Git
- 學習Linux命令的正確姿勢Linux
- Python開發遊戲的正確姿勢Python開發遊戲
- Git和GitHub的正確開啟姿勢Github
- 論獲取快取值的正確姿勢快取