1. 程式人生 > >android守護程序,進入後臺或異常後再次啟動app

android守護程序,進入後臺或異常後再次啟動app

當前做的app要求開機啟動,並且退出後或異常閃退時也要重新開啟app。下面說一下進入後臺後或閃退後重啟進入前臺方法

方法1、缺點:出現異常閃退時,不會重啟,因為沒來及進onActivityStopped

private int mFinalCount;

    /**
     * 在application中呼叫,進入一個activity時執行onActivityStarted,離開一個activity時執行onActivityStopped
     */
    private void ActivitiesLifeCallbacks()
    {
        registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
            @Override
            public void onActivityCreated(Activity activity, Bundle bundle) {

            }

            @Override
            public void onActivityStarted(Activity activity) {
                mFinalCount++;
                //如果mFinalCount ==1,說明是從後臺到前臺
                Log.e("onActivityStarted", mFinalCount +"");
                if (mFinalCount == 1){
                    //說明從後臺回到了前臺
                }
            }

            @Override
            public void onActivityResumed(Activity activity) {

            }

            @Override
            public void onActivityPaused(Activity activity) {

            }

            @Override
            public void onActivityStopped(Activity activity) {
                mFinalCount--;

                //如果mFinalCount ==0,說明是前臺到後臺
                Log.i("onActivityStopped", mFinalCount +"");
                if (mFinalCount == 0){
                    //說明從前臺回到了後臺
                    try {
                        //此處需加延時幾秒,否則按home鍵後回不到前臺
                        Thread.sleep(10000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    toFront();
                }
            }

            @Override
            public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {

            }

            @Override
            public void onActivityDestroyed(Activity activity) {

            }
        });
    }

    /**
     * 由後臺進入前臺
     */
    private void toFront()
    {
        //獲取ActivityManager
        ActivityManager mAm = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
        //獲得當前執行的task
        List<ActivityManager.RunningTaskInfo> taskList = mAm.getRunningTasks(100);
        for (ActivityManager.RunningTaskInfo rti : taskList) {
            //找到當前應用的task,並啟動task的棧頂activity,達到程式切換到前臺
            if (rti.topActivity.getPackageName().equals(getPackageName())) {
                mAm.moveTaskToFront(rti.id, 0);
                return;
            }
        }
        //若沒有找到執行的task,使用者結束了task或被系統釋放,則重新啟動mainactivity
        Intent resultIntent = new Intent(this, SplashActivity.class);
        resultIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
        startActivity(resultIntent);
    }

方法2、缺點需要建立service,以及執行緒,暫用大量CPU時間;切換至後臺執行時會有延遲。不過沒多大影響,而且閃退時可以重啟,目前用這個

import android.app.ActivityManager;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.util.Log;

import com.rb.esc.activity.SplashActivity;

import java.util.List;

/**
 * 監聽前後臺
 * Created by Administrator on 2018/3/3.
 */

public class AppService extends Service implements Runnable
{
    public static boolean isOnForeground = true;

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();

        new Thread(this).start();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void run() {
        while(true){
            boolean isOnForegroundNew = isRunningOnForeground(this);

            if(isOnForegroundNew != isOnForeground){
                toFront();
            }
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    public static boolean isRunningOnForeground(Context context){

        ActivityManager acm = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        if(acm != null){
            List<ActivityManager.RunningAppProcessInfo> runApps = acm.getRunningAppProcesses();
            if(runApps != null && !runApps.isEmpty()){
                for(ActivityManager.RunningAppProcessInfo app : runApps){
                    if(app.processName.equals(context.getPackageName())){
                        if(app.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND){
                            return true;
                        }
                    }
                }
            }
        }
        return false;
    }

    private void toFront()
    {
        //獲取ActivityManager
        ActivityManager mAm = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
        //獲得當前執行的task
        List<ActivityManager.RunningTaskInfo> taskList = mAm.getRunningTasks(100);
        for (ActivityManager.RunningTaskInfo rti : taskList) {
            //找到當前應用的task,並啟動task的棧頂activity,達到程式切換到前臺
            if (rti.topActivity.getPackageName().equals(getPackageName())) {
                mAm.moveTaskToFront(rti.id, 0);
                return;
            }
        }
        //若沒有找到執行的task,使用者結束了task或被系統釋放,則重新啟動mainactivity
        Intent resultIntent = new Intent(this, SplashActivity.class);
        resultIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
        startActivity(resultIntent);

    }
}

xml中

<service android:name=".service.AppService"
            android:enabled="true"
            android:exported="true"></service>

啟動時

Intent intent = new Intent(this, AppService.class);
        startService(intent);