Android 内存被回收后直接重启APP

做Android开发的小朋友一定会遇到程序退到后台,遇到内存被回收,导致数据为空,这时候启动APP就会出现空指针问题。

那么,我们该怎么解决这个问题呢?其实很简单,当内存被回收后,我们可以直接重启APP,重新走一遍APP启动的流程,这样数据就会重新加载一遍,避免了数据为空的问题。

首先,我们先定义一个AppStatusManager管理生命周期类

/**
 * APP状态跟踪器常量码
 */
public class AppStatusConstant {
    public static final int STATUS_FORCE_KILLED = -1; //应用放在后台被强杀了
    public static final int STATUS_KICK_OUT = 1;//TOKEN失效或者被踢下线
    public static final int STATUS_NORMAL = 2;  //APP正常态
    public static final int STATUS_LOGOUT = 3;//用户注销登录
    public static final int STATUS_OFFLINE = 4;//未登录状态
    public static final int STATUS_ONLINE = 5;//登录状态

    //intent到MainActivity 区分跳转目的
    public static final String KEY_HOME_ACTION = "key_home_action";//返回到主页面

    public static final int ACTION_BACK_TO_HOME = 11; //默认值
    public static final int ACTION_RESTART_APP = 12;//重启APP
    public static final int ACTION_KICK_OUT = 13;//被踢出
    public static final int ACTION_LOGOUT = 14;//退出登录
}
public class AppStatusManager implements Application.ActivityLifecycleCallbacks {

    public int mAppStatus = AppStatusConstant.STATUS_FORCE_KILLED;
    public static AppStatusManager mAppStatusManager;
    private Application application;
    private boolean isForground;//是否前台
    private int activeCount;//Activity运行个数


    private AppStatusManager(Application application) {
        this.application = application;
        application.registerActivityLifecycleCallbacks(this);
    }

    public static void init(Application application) {
        if (mAppStatusManager == null) {
            mAppStatusManager = new AppStatusManager(application);
        }
    }

    public static AppStatusManager getInstance() {
        return mAppStatusManager;
    }

    /**
     * 获取APP状态
     */
    public int getAppStatus() {
        return mAppStatus;
    }

    /**
     * 设置APP状态
     */
    public void setAppStatus(int appStatus) {
        this.mAppStatus = appStatus;
    }

    /**
     * 是否前台显示
     */
    public boolean isForground() {
        return isForground;
    }

    @Override
    public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
    }

    @Override
    public void onActivityStarted(Activity activity) {
        activeCount++;
    }

    @Override
    public void onActivityResumed(Activity activity) {
        isForground = true;
    }

    @Override
    public void onActivityPaused(Activity activity) {
    }

    @Override
    public void onActivityStopped(Activity activity) {
        activeCount--;
        if (activeCount == 0) {
            isForground = false;
        }
    }

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

    @Override
    public void onActivityDestroyed(Activity activity) {
    }
}
public class BaseApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        AppStatusManager.init(this);
    }
}

然后定义个TrackerActivity基类,监听内存回收问题


public abstract class TrackerActivity extends AppCompatActivity {
    private String TAG = "TAG";

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        switch (AppStatusManager.getInstance().getAppStatus()) {
            case AppStatusConstant.STATUS_FORCE_KILLED:
                Log.e(TAG, "STATUS_FORCE_KILLED");
                /*处理APP被强杀*/
                protectApp();
                break;
            case AppStatusConstant.STATUS_KICK_OUT:
                /*处理APP被退出登录*/
                Log.e(TAG, "STATUS_KICK_OUT");
                break;
            case AppStatusConstant.STATUS_NORMAL:
                /*APP正常状态*/
                Log.e(TAG, "STATUS_NORMAL");
                setUpContentView();
                setUpData();
                break;
        }
    }
    
    /**
     * 设置布局
     */
    protected abstract void setUpContentView();

    /**
     * 设置数据
     */
    protected abstract void setUpData();

    /**
     * 处理APP被强杀
     */
    protected void protectApp() {
        /*跳转主界面处理*/
        Intent intent = new Intent(this, MainActivity.class);
        intent.putExtra(AppStatusConstant.KEY_HOME_ACTION, AppStatusConstant.ACTION_RESTART_APP);
        startActivity(intent);
    }
}

接下来,我们只用在实现SplashActivity MainActivity SecondActivity ,就行了

SplashActivity


public class SplashActivity extends TrackerActivity {
    private MyHandler mHandler = new MyHandler(this);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        //设置默认状态
        AppStatusManager.getInstance().setAppStatus(AppStatusConstant.STATUS_NORMAL);
        super.onCreate(savedInstanceState);
    }

    @Override
    protected void setUpContentView() {
        setContentView(R.layout.activity_splash);
    }

    @Override
    protected void setUpData() {
        if (mHandler != null) {
            mHandler.sendEmptyMessageDelayed(0, 2000);
        }
    }

    private static class MyHandler extends Handler {
        private WeakReference<Context> reference;

        public MyHandler(Context context) {
            reference = new WeakReference<>(context);
        }

        @Override
        public void handleMessage(Message msg) {
            SplashActivity activity = (SplashActivity) reference.get();
            if (activity != null) {
                activity.startActivity(new Intent(activity, MainActivity.class));
                activity.finish();
            }
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mHandler != null) {
            mHandler.removeCallbacksAndMessages(null);
            mHandler = null;
        }
    }
}

MainActivity

public class MainActivity extends TrackerActivity {

    @Override
    protected void setUpContentView() {
        setContentView(R.layout.activity_main);
    }

    @Override
    protected void setUpData() {
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        int action = intent.getIntExtra(AppStatusConstant.KEY_HOME_ACTION, AppStatusConstant.ACTION_BACK_TO_HOME);
        switch (action) {
            case AppStatusConstant.ACTION_RESTART_APP:
                protectApp();
                break;
            case AppStatusConstant.ACTION_BACK_TO_HOME:
                break;
            default:
                break;
        }
    }

    @Override
    protected void protectApp() {
        /*跳转引导页,重启APP*/
        startActivity(new Intent(this, SplashActivity.class));
        finish();
    }

    public void toSecondActivity(View view) {
        startActivity(new Intent(this, SecondActivity.class));
    }
}

SecondActivity


public class SecondActivity extends TrackerActivity {
    
    @Override
    protected void setUpContentView() {
        setContentView(R.layout.activity_second);
    }

    @Override
    protected void setUpData() {
    }

    public void toThirdActivity(View view) {
        startActivity(new Intent(this, ThirdActivity.class));
    }

大功告成!!! 让我们看看具体显示流程吧

在这里插入图片描述

流程: SplashActivity -> MainActivity -> SecondActivity -> ThirdActivity -> APP被强杀,内存被回收,APP就会重启,重走流程 -> SplashActivity -> MainActivity

github

猜你喜欢

转载自blog.csdn.net/qq_14876133/article/details/82801579
今日推荐