利用IntentService與Service重啟APP應用
阿新 • • 發佈:2018-12-24
專案開發過程中需要實現重啟App的功能
方式一:利用IntentService實現APP重啟,用完即走
IntentService
IntentService,可以看做是Service和HandlerThread的結合體,在完成了使命之後會自動停止,適合需要在工作執行緒處理UI無關任務的場景。
- IntentService 是繼承自 Service 並處理非同步請求的一個類,在 IntentService 內有一個工作執行緒來處理耗時操作。
- 當任務執行完後,IntentService 會自動停止,不需要我們去手動結束。
- 如果啟動 IntentService 多次,那麼每一個耗時操作會以工作佇列的方式在 IntentService 的 onHandleIntent 回撥方法中執行,依次去執行,使用序列的方式,執行完自動結束。
下面看實現類程式碼
public class RestartIntentService extends IntentService { private static long stopDelayed = 2000; private Handler mHandler; private String PackageName; public RestartIntentService(){ super("RestartIntentService"); mHandler = new Handler(); } public static void start(Context context,long Delayed) { Intent intent = new Intent(context, RestartIntentService.class); intent.putExtra("PackageName",context.getPackageName()); intent.putExtra("Delayed",Delayed); context.startService(intent); } @Nullable @Override public IBinder onBind(Intent intent) { return null; } @Override protected void onHandleIntent(@Nullable Intent intent) { stopDelayed = intent.getLongExtra("Delayed",2000); PackageName = intent.getStringExtra("PackageName"); mHandler.postDelayed(() -> { Intent launchIntent = getPackageManager().getLaunchIntentForPackage(PackageName); startActivity(launchIntent); LogUtil.d("重啟APP成功,包名:"+PackageName); },stopDelayed); } /** * 重啟APP * @param context˛ */ public static void restartAPP(Context context){ start(context,1500); } @Override public void onDestroy() { super.onDestroy(); if (mHandler!=null){ mHandler = null; } } }
然後在AndroidManifest.xml清單檔案註冊,並新增在獨立程序中(不新增系統殺死後無法重啟Syetem.exit(0) )
<service android:name=".RestartIntentService"
android:process=":restart"/>
呼叫
RestartIntentService.restartAPP(this);
方式二:利用Service服務重啟,方式跟IntentService差不多,但這種需要在操作完時自行把服務殺死
Service四大元件之一
- 定義、特點:
Service是可以在後臺執行長時間(長生命週期)
- 注意事項:
1、只能在後臺執行,即便使用者切換了其他應用,啟動的Service仍可在後臺執行。
2、可以和其他元件進行Service繫結並與之互動,甚至是跨程序通訊(IPC)。
3、不能執行在一個獨立的程序當中,而是依賴與建立服務時所在的應用元件程序。
4、服務不會自動開啟執行緒,我們需要在服務的內部手動建立子執行緒,並在這裡執行具體的任務。
- 應用場景舉例:
音樂播放:播放多媒體的時候使用者啟動了其他Activity,此時要在後臺繼續播放。
記錄檢測:比如檢測SD卡上檔案的變化;在後臺記錄你的地理資訊位置的改變等。
其他操作:網路請求、執行檔案讀寫操作或者與 content provider互動。
-
型別:
本地服務與遠端服務本地服務依附在主程序上,在一定程度上節約了資源。本地服務因為是在同一程序,因此不需要IPC,也不需要AIDL。相應bindService會方便很多。缺點是主程序被kill後,服務變會終止。
遠端服務是獨立的程序,對應程序名格式為所在包名加上你指定的android:process字串。由於是獨立的程序,因此在Activity所在程序被kill的是偶,該服務依然在執行。缺點是該服務是獨立的程序,會佔用一定資源,並且使用AIDL進行IPC稍微麻煩一點。本文第六部分將會簡單的講述這一程序間通訊方式。
對於startService來說,不管是本地服務還是遠端服務,我們需要做的工作都一樣簡單
下面看實現程式碼
/*
* Description:該服務只用來讓APP重啟,重啟完即自我自殺,服務需在獨立程序
*/
public class KillSelfService extends Service {
private static long stopDelayed = 2000;
private Handler mHandler;
private String PackageName;
public KillSelfService(){
mHandler = new Handler();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
stopDelayed = intent.getLongExtra("Delayed",2000);
PackageName = intent.getStringExtra("PackageName");
mHandler.postDelayed(() -> {
Intent launchIntent = getPackageManager().getLaunchIntentForPackage(PackageName);
startActivity(launchIntent);
LogUtil.d("重啟APP服務成功");
KillSelfService.this.stopSelf();
},stopDelayed);
return super.onStartCommand(intent, flags, startId);
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
/*
* Description:此工具類用來重啟APP,只是單純的重啟,不做任何處理。
*/
public class RestartAPPTool {
/**
* 重啟APP服務
* @param context
* @param Delayed 延遲多少秒
*/
public static void restartApp(Context context,long Delayed){
Intent intent = new Intent(context,KillSelfService.class);
intent.putExtra("PackageName",context.getPackageName());
intent.putExtra("Delayed",Delayed);
LogUtil.d("啟動重啟KillSelfService服務");
context.startService(intent);
}
/**
* 重啟APP
* @param context˛
*/
public static void restartAPP(Context context){
restartApp(context,1500);
}
}
在AndroidManifest.xml清單檔案註冊
<service android:name=".KillSelfService"
android:process=":restart"/>
Activity中呼叫
RestartAPPTool.restartAPP(this);
參考:
android比較便捷的重啟APP的方法
android Process.killProcess 和 System.exit(0) 區別