欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Application

程序员文章站 2022-05-22 13:31:57
一、概念理解 Base class for maintaining global application state. You can provide your own implementation by creating a subclass and specifying the fully-qu ......

一、概念理解

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是维持全局应用状态的基类,单例模式,且先于其他任意组件被创建。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为后台,否则即是前台。