当前位置: 移动技术网 > 移动技术>移动开发>Android > Application

Application

2019年05月11日  | 移动技术网移动技术  | 我要评论

一、概念理解

base class for maintaining global application state. you can provide your own implementation by creating a subclass and specifying the fully-qualified name of this subclass as the "android:name" attribute in your androidmanifest.xml's <application> tag. the application class, or your subclass of the application class, is instantiated before any other class when the process for your application/package is created.

note: there is normally no need to subclass application. in most situations, static singletons can provide the same functionality in a more modular way. if your singleton needs a global context (for example to register broadcast receivers), include context.getapplicationcontext() as a context argument when invoking your singleton's getinstance() method.

application是维持全局应用状态的基类,单例模式,且先于其他任意组件被创建。application组件被设计的初衷是对整体应用级别管理负责,对其正确使用应该避免两个极端

  1. 过度使用——将application当做单例工具类,耦合太多非应用级别的工具方法或业务逻辑,造成application类臃肿
  2. 从不使用——因不熟悉而不敢使用或忘记使用,不使用没有错,但有时适当使用会减少代码重复,提升性能,且其自身扩展方法也会为某些特殊业务提供思路

application实际上继承自context,继承来的方法不必多说,也不是重点。既然有必要子类化,那它也必然会扩展自己的方法来实现其特有功能,也就是和应用管理相关方法。下面将重点介绍这些方法。


二、application实战应用

application的应用管理相关功能可以从其维护的三个list来分析:

    private arraylist<componentcallbacks> mcomponentcallbacks = new arraylist<componentcallbacks>();//系统配置变更、内存管理
    private arraylist<activitylifecyclecallbacks> mactivitylifecyclecallbacks = new arraylist<activitylifecyclecallbacks>();//activity生命周期管理
    private arraylist<onprovideassistdatalistener> massistcallbacks = null; //协助数据

(1)componentcallbacks/componentcallbacks2

用于系统配置变化、内存紧张时获得回调。该接口并非只有application实现,activity和service等其他组件都有实现。而且还可以自定义实现接口,通过api注册。

    void onconfigurationchanged(configuration newconfig);//系统状态配置如横竖屏、语言等变化时回调
    void onlowmemory();//后台进程被杀后回调
    void ontrimmemory(@trimmemorylevel int level);//根据不同内存状态来回调

其中onlowmemory和ontrimmemory的区别:

  1. onlowmemory被回调时,已经没有后台进程;而ontrimmemory被回调时,还有后台进程。
  2. onlowmemory是在最后一个后台进程被杀时调用,一般情况是low memory killer 杀进程后触发;ontrimmemory的触发更频繁,每次计算进程优先级时,只要满足条件,都会触发。
  3. 通过一键清理后,onlowmemory不会被触发,而ontrimmemory会被触发一次。

(2)activitylifecyclecallbacks

该接口用于对应用所有activity的生命周期做集中回调管理,是application独有扩展功能。注册该接口后每个activity的生命周期发生变化后都会获得回调,可以很方便的做记录和管理。

        public interface activitylifecyclecallbacks {
            void onactivitycreated(activity activity, bundle savedinstancestate);
            void onactivitystarted(activity activity);
            void onactivityresumed(activity activity);
            void onactivitypaused(activity activity);
            void onactivitystopped(activity activity);
            void onactivitysaveinstancestate(activity activity, bundle outstate);
            void onactivitydestroyed(activity activity);
        }

实现原理也比较简单,以onactivitycreated为例, 在application中有如下方法两个方法

    //注册回调
    public void registeractivitylifecyclecallbacks(activitylifecyclecallbacks callback)
    //分发回调
    /* package */ void dispatchactivitycreated(activity activity, bundle savedinstancestate)

通过registeractivitylifecyclecallbacks方法注册回调,查看activity源码,当oncreate时,再通过dispatchactivitycreated方法分发给各回调。

    protected void oncreate(@nullable bundle savedinstancestate) {
        ...
        getapplication().dispatchactivitycreated(this, savedinstancestate);
        ...
    }

在实际应用中,通过注册registeractivitylifecyclecallbacks回调,可以对activity的状态和数量做更精准的监控。

应用一:限制activity实例数量

比如,我们要限制activitydetail页面的数量不超过max_activity_detail_num,可以在onactivitycreated回调方法中做如下处理(这是activity启动模式无法做到的)

    public static stack<activitydetail> store;   
    @override 
    public void onactivitycreated(activity activity, bundle bundle) {
        if (activity instanceof activitydetail) {
            if (store.size() >= max_activity_detail_num) {
                store.peek().finish(); //移除栈底并finish,保证不超过指定数量 
            }
            tore.add((activitydetail) activity);
        }
    }

应用二:控制相同内容的activity只有一个实例

比如,要展示商品a的activitydetail实例已经存在,就没必要再创建一个展示相同内容的activitydetail。

系统级应用可以调用如下方法(需要android.permission.stop_app_switches权限)

    for(activitydetail activitydetail : store){ 
        if(id.equalsignorecase(activitydetail.getid())){ //当前商品id相同证明已有相同页面
             activitymanager am = (activitymanager) getappcontext().getsystemservice(activity.activity_service); 
             am.movetasktofront(activitydetail.gettaskid(), activitymanager.move_task_no_user_action); 
             return true;
        }
    }

非系统级应用只能finish掉已经存在的页面,重新打开一个新的页面

    for(activitydetail activitydetail : store){ 
        if(id.equalsignorecase(activitydetail.getid())){ //当前商品id相同证明已有相同页面
             activitydetail.finish();
             return true;
        }
    }

应用三:判断app前后台状态

每当一个activity切到前台时都会执行onstart,切到后台时都会执行onstop,所以只需要在onactivitystarted和onactivitystopped回调中做一个简单的计数器即可

          mactivitycount = 0;        
          registeractivitylifecyclecallbacks(new activitylifecyclecallbacks() {
                            ... 
                @override
                public void onactivitystarted(activity activity) {
                    log.d(tag,"onactivitystarted");
                    mactivitycount++;
                }
     
                @override
                public void onactivitystopped(activity activity) {
                    log.d(tag,"onactivitystopped");
                    mactivitycount--;
                }
                            ...
            });

当mactivitycount == 0时app为后台,否则即是前台。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网