1. 程式人生 > >利用IntentService與Service重啟APP應用

利用IntentService與Service重啟APP應用

專案開發過程中需要實現重啟App的功能

GitHub地址

方式一:利用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是可以在後臺執行長時間(長生命週期)
    而又不與使用者產生UI互動(沒有使用者介面)的操作。

  • 注意事項:
    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) 區別