摘要:用戶可以手動添加自啟動應用,添加后的應用中如果回調返回值是或,當用戶在小米手機上長按鍵結束后,接下來未來的某個時間內,當系統內存足夠可用時,依然可以按照上述規定重啟。
Android Service
Service通常總是稱之為“后臺服務”,其中“后臺”一詞是相對于前臺而言的,具體是指其本身的運行并不依賴于用戶可視的UI界面,因此,從實際業務需求上來理解,Service的適用場景應該具備以下條件:
并不依賴于用戶可視的UI界面(當然,這一條其實也不是絕對的,如前臺Service就是與Notification界面結合使用的)
具有較長時間的運行特性
基礎知識定義:Android中的計算型組件
作用:提供需要在后臺長期運行的服務(如復雜計算、下載等等)
特點:長生命周期的、沒有用戶界面、在后臺運行
定義Service下面代碼片段顯示的是一個最基本的Started Service的自定義方式:
public class MyService extends Service { public static final String TAG = "MyService"; @Override public IBinder onBind(Intent intent) { return null; } @Override public void onCreate() { super.onCreate(); Log.w(TAG, "in onCreate"); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.w(TAG, "in onStartCommand"); Log.w(TAG, "MyService:" + this); String name = intent.getStringExtra("name"); Log.w(TAG, "name:" + name); return START_STICKY; } @Override public void onDestroy() { super.onDestroy(); Log.w(TAG, "in onDestroy"); } }
onBind(...)函數是Service基類中的唯一抽象方法,子類都必須重寫實現,此函數的返回值是針對Bound Service類型的Service才有用的,在Started Service類型中,此函數直接返回 null 即可。
onCreate(...)、onStartCommand(...)和onDestroy()都是Started Service相應生命周期階段的回調函數。
一般而言,從Service的啟動方式上,可以將Service分為Started Service和Bound Service。無論哪種具體的Service啟動類型,都是通過繼承Service基類自定義而來。在使用Service時,要想系統能夠找到此自定義Service,無論哪種類型,都需要在AndroidManifest.xml中聲明,語法格式如下:
android:exported=["true" | "false"] android:icon="drawable resource" android:isolatedProcess=["true" | "false"] android:label="string resource" android:name="string" android:permission="string" android:process="string" > . . .
android:exported——能否接收其他App的發出的信息,這個屬性默認值有點意思,其默認值是由有無intent-filter決定的,如果有intent-filter,默認值為true,否則為false。(receiver/activity/service中的此屬性默認值遵循此規則)同時,需要注意的是,這個值的設定是以application或者application user id為界的,而非進程為界(一個應用中可能含有多個進程)
android:name ——對應Service類名
android:permission ——是權限聲明
android:process ——詳情
Started Service相對比較簡單,通過context.startService(Intent serviceIntent)啟動Service,context.stopService(Intent serviceIntent)停止此Service。當然,在Service內部,也可以通過stopSelf(...)方式停止其本身。
以下是代碼測試片段:
public class MainActivity extends Activity { public static final String TAG = "MainActivity"; private Button startServiceBtn; private Button stopServideBtn; private Intent serviceIntent; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); startServiceBtn = (Button) findViewById(R.id.start_service); stopServideBtn = (Button) findViewById(R.id.stop_service); startServiceBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { serviceIntent = new Intent(MainActivity.this, MyService.class); startService(serviceIntent); } }); stopServideBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { stopService(serviceIntent); } }); } @Override protected void onDestroy() { super.onDestroy(); Log.w(TAG, "in onDestroy"); } }調用流程
當Client調用startService(Intent serviceIntent)后,如果MyService是第一次啟動,首先會執行 onCreate()回調,然后再執行onStartCommand(Intent intent, int flags, int startId),當Client再次調用startService(Intent serviceIntent),將只執行onStartCommand(Intent intent, int flags, int startId),因為此時Service已經創建了,無需執行onCreate()回調。無論多少次的startService,只需要一次stopService()即可將此Service終止,執行onDestroy()函數(其實很好理解,因為onDestroy()與onCreate()回調是相對的)
onStartCommand方法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。
START_STICKY_COMPATIBILITY :此值一般不會使用,所以注意前面三種情形就好。
以上的描述中,”當Service因為內存不足而被系統kill后“一定要非常注意,因為此函數的返回值設定只是針對此種情況才有意義的,換言之,當認為的kill掉Service進程,此函數返回值無論怎么設定,接下來未來的某個時間內,即使系統內存足夠可用,Service也不會重啟。
小米手機針對此處做了變更:
另外,需要注意的是,小米手機針對此處做了一定的修改。在“自啟動管理”中有一個自啟動應用列表,默認情況下,只有少應用(如微信、QQ、YY、360等)默認是可以自啟動的,其他應用默認都是禁止的。用戶可以手動添加自啟動應用,添加后的應用中如果Started Service onStartCommand(...)回調返回值是START_STICKY或START_REDELIVER_INTENT,當用戶在小米手機上長按Home鍵結束App后,接下來未來的某個時間內,當系統內存足夠可用時,Service依然可以按照上述規定重啟。當然,如果用戶在 設置 >> 應用 >> 強制kill掉App進程,此時Service是不會重啟的。
注:以上實驗結論基于小米2S親測。
官方教程
郭霖(Service教程)
Service生命周期圖解
Android總結篇系列:Android Service
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/66412.html
摘要:只能執行單一操作,無法返回結果給調用方,常用于網絡下載上傳文件,播放音樂等。綁定模式此模式通過綁定組件等調用啟動此服務隨綁定組件的消亡而解除綁定。 showImg(https://segmentfault.com/img/remote/1460000019975019?w=157&h=54); 極力推薦文章:歡迎收藏Android 干貨分享 showImg(https://segme...
摘要:靜態注冊廣播的方法動態注冊廣播在中動態注冊廣播,通常格式如下動態注冊廣播動態注冊監聽滅屏點亮屏幕的廣播在廣播中動態注冊廣播請注意一定要使用,防止為空,引起空指針異常。綁定模式此模式通過綁定組件等調用啟動此服務隨綁定組件的消亡而解除綁定。 showImg(https://segmentfault.com/img/remote/1460000019975019?w=157&h=54); 極...
閱讀 3806·2023-04-26 02:07
閱讀 3680·2021-10-27 14:14
閱讀 2868·2021-10-14 09:49
閱讀 1634·2019-08-30 15:43
閱讀 2626·2019-08-29 18:33
閱讀 2378·2019-08-29 17:01
閱讀 922·2019-08-29 15:11
閱讀 597·2019-08-29 11:06