Application 问题总结 - bei1999/work GitHub Wiki

前言

实际开发项目中经常遇到关于application 的问题,总结一下吧

Issues

Application onCreate()方法被反复调用?

理论上认为android 系统中application 是一个单例(一点不假!)然而在项目中存在多进程时候,单例范围只能在本进程中,比如推送,地图等进程有时候会初始化application ,so需要判断下执行的进程名字。

        if (!AppUtils.getCurProcessName(this).equals(getPackageName())) {
            return;
        }

极光推送收到通知时,经常要各种跳转。那么一大堆问题来了:收到通知时,应用是否打开?应用打开了是否处于前台(有没有按Home键之类的)?处于栈顶的Activity是否是你要跳转的Activity?栈顶的Activity是否又是登录页面等等…下面带大家看看如何有效使用ActivityLifecycleCallbacks来解决这一系列问题。

public class JPushReceiver extends BroadcastReceiver{

        private Context context;
        private ActivityLifecycleCallbacks activityLifecycleCallbacks;

        @Override
        public void onReceive(Context context, Intent intent) {
            this.context = context;
            MyApplication application = (MyApplication) context.getApplicationContext();
            activityLifecycleCallbacks = application.activityLifecycleCallbacks;
//            如果应用处于前台做某些操作(一般此时,收到通知和点击通知栏做相同的操作)
            if (activityLifecycleCallbacks.isFront()) {
                if (activityLifecycleCallbacks.current() instanceof SomeActivity) {
//                    如果当前Activity是要跳转的Activity,做某些操作,一般不跳转,可用EventBus
                    、、、
                } else {
//                    否则执行跳转或其他相关操作等
                   、、、
                }
                、、、
            }else  if ("cn.jpush.android.intent.NOTIFICATION_OPENED".equals(intent.getAction())){
//                应用处于不可见状态,一般点击通知栏是跳转到某个页面
                、、、
            }
        }
}

除了上面的需求,关于app 所有的activity 的状态都可以获取和管理,比如说BaseActivity的方式或者每打开一个Activity把当前的引用加入到集合中的方式更优雅

/**
     * 注册ActivityListener
     */
    private void registerActivityListener() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
            registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
                @Override
                public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
                    if (null == mActivitys) {
                        return;
                    }
                    mActivitys.add(activity);
                }

                @Override
                public void onActivityStarted(Activity activity) {
                    Log.d("bei", "register-onActivityStarted");
                }

                @Override
                public void onActivityResumed(Activity activity) {
                    Log.d("bei", "register-onActivityResumed");
                }

                @Override
                public void onActivityPaused(Activity activity) {
                    Log.d("bei", "register-onActivityPaused");
                }

                @Override
                public void onActivityStopped(Activity activity) {
                }

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

                @Override
                public void onActivityDestroyed(Activity activity) {
                    if (null == activity && mActivitys.isEmpty()) {
                        return;
                    }
                    if (mActivitys.contains(activity)) {
                        mActivitys.remove(activity);
                    }
                }
            });
        }
    }

crash 捕获

使用过线上的bug 管理,本地写入文件方式的管理,最近发现个异常补货的工具包,适合在开发模式下进行直观的bug activity 日志显示,方便测试与开发沟通

        /**crash异常捕获*/
        if (BuildConfig.DEBUG) {
            CustomActivityOnCrash.install(this);
        }

gradle 导入

    compile 'cat.ereza:customactivityoncrash:1.5.0' //crash catch

这个gradle 包目前已经更新了,可以定制写页面参数,感兴趣的可以看看

项目地址