Android-Application详解

栏目: Android · 发布时间: 5年前

内容简介:在学习一个SDK的时候,遇到了英语基础好的可以去参考官方文档

在学习一个SDK的时候,遇到了 Application 类的相关知识,其实之前也有学习过 Application 类的一些知识,但是日常开发中使用频率不高,忘得差不多了.现在重新来总结下 Application 的使用

英语基础好的可以去参考官方文档

官方文档

下面是官网对Application类的简介

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.

大概意思就是Application是用来维护全局应用状态的基类.可以通过自己创建子类并且在 Manifest.xml 文件中通过 name 属性来标记,用来实现自定义的功能.Application类将会在 任何类之前 实例化

继承关系

  • Application 类继承自 ContextWarpper

下面是示意图

Android-Application详解

特点

  • 单例模式:每个App都 有且只有一个 Application的实例对象(多进程APP除外),可以通过继承Application子类来进行自定义,如果没有自定义的话,APP会在打开是自动创建一个默认的实例对象.

  • 生命周期:APP开启时就会开始实例化Application对象,Application实例的生命周期是最长的,拥有和APP一样长的生命周期

  • 获取方式:如果没有自定义Application的话,同样可以获取到Application对象,使用 Activity.getApplication() 或者 Context.getApplicationContext() 方法都可以获取到对象.

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    //这两种方法都可以获取到实例对象
    val application = application
    val otherApplication = applicationContext
}
复制代码
  • 全局实例 :在不同的组件中(如:Activity,Service),都可以获取Application对象,并且都会是同一个对象

方法介绍

onCreate()

  • 调用时间:

    当应用打开时,创建应用程序时调用此方法.

Tip:这不是 Activity 的onCreate(),默认是空实现.

  • 使用方式:

    可以用来初始化数据一些全局变量,对象,也可以用来做一些环境的配置.

  • 演示:

class MyApplication: Application() {
    var whatever = "Whatever"
    
    override fun onCreate() {
        super.onCreate()
        whatever = "Hello"
        //Do something...
    }
}
复制代码

注册ComponentCallback2

  • 简单说明:

    上面的示意图中其实还显示了,Application类是实现了 ComponentCallback2 接口的,这个接口里面有三个可以覆写的方法,可以通过 registerComponentCallbacks() 方法来进行注册,也可以使用 unregisterComponentCallbacks() 来注销.

  • 使用:

override fun onCreate() {
        super.onCreate()
    
        registerComponentCallbacks(object : ComponentCallbacks2 {
            override fun onLowMemory() {

            }

            override fun onConfigurationChanged(newConfig: Configuration?) {

            }

            override fun onTrimMemory(level: Int) {

            }
        })
    }
复制代码

onLowMemory()

这是上面 ComponentCallback2 接口中的方法,用于在Android4.0之前的内存检测,开发者可以在这个回调方法中做一些优化,防止被系统杀进程.目前用这个方法的情景并不多见,除非开发者想向下兼容的比较深.目前可以用 onTrimMemory() 替代

  • 调用时间:监听到系统内存很低的时刻
registerComponentCallbacks(object : ComponentCallbacks2 {
            override fun onLowMemory() {
				//Do something...
            }
        })
复制代码

onTrimMemoey()

这个方法目前用来替代上面的 onLowMemory() 方法.方法会传入一个level的Int参数,这是一个目前系统通知给App的一个内存不足等级,越高越严重.不同的等级系统会对App做出不同的操作.

内存不足级别 意义
TRIM_MEMORY_RUNNING_MODERATE 等级5:应用可以正常在前台运行,但是系统已经要开始杀后台进程了
TRIM_MEMORY_RUNNING_LOW 等级10:应用可以正常在前台运行,但是系统通知释放资源,不然会影响速度
TRIM_MEMORY_RUNNING_CRITICAL 等级15:前台运行,但是大部分后台被杀死,此时必须释放内存,不然此应用进程也会被杀死
TRIM_MEMORY_UI_HIDDEN 等级20:系统会将该应用的UI资源收回,转为后台
TRIM_MEMORY_BACKGROUND 等级40:此时应用处于LRU缓存列表的最近位置,需要立刻释放容易恢复的资源
TRIM_MEMORY_MODERATE 等级60:此时应用处于LRU缓存列表的中间位置,有被杀死进程的危险
TRIM_MEMORY_COMPLETE 等级80:非常危险的等级,应用处于缓存列表最边缘,即将被杀死
  • 系统杀进程规则:

    系统会按照LRU Cache列表由低到高杀进程,会优先杀占用内存较高的应用,也就是应用占用内存较小的话,被杀死的概率会降低.

  • 使用方法:

override fun onTrimMemory(level: Int) {
    if (level in TRIM_MEMORY_RUNNING_MODERATE..(TRIM_MEMORY_RUNNING_LOW - 1)){
        //Do something...
    }else if (level >= TRIM_MEMORY_RUNNING_LOW){
		//Do something...
    }
}
复制代码

onConfigurationChanged()

  • 作用:

    监听APP的一些配置信息的改变事件(比如屏幕旋转)

  • 调用时间:

    当配置信息改变的时候会回调此方法

  • 配置信息:

    配置信息也就是 Manifest.xml 文件中 Activityandroid:configChanges 属性的值,在该属性中填入 android:configChanges="keyboardHidden|orientation|screenSize" 可以让屏幕旋转时不重启,而是执行 onConfigurationChanged() 方法

  • 使用方法:

registerComponentCallbacks(object : ComponentCallbacks2 {
    override fun onConfigurationChanged(newConfig: Configuration?) {
		//Do something
    }
}
复制代码

ActivityLifecycleCallbacks()

这是一个接口,可以通过 registerActivityLifecycleCallbacks()unregisterActivityLifecycleCallbacks() 来注册/注销对所有Activity生命周期的监听,当Activity的生命周期发生改变的时候,就会调用接口里的方法.

  • 使用方法
registerActivityLifecycleCallbacks(object : ActivityLifecycleCallbacks {
            override fun onActivityPaused(activity: Activity?) {

            }

            override fun onActivityResumed(activity: Activity?) {

            }

            override fun onActivityStarted(activity: Activity?) {

            }

            override fun onActivityDestroyed(activity: Activity?) {

            }

            override fun onActivitySaveInstanceState(activity: Activity?, outState: Bundle?) {

            }

            override fun onActivityStopped(activity: Activity?) {

            }

            override fun onActivityCreated(activity: Activity?, savedInstanceState: Bundle?) {

            }
        })
复制代码

这个主要就是对不同的生命周期进行监听,这里就不往里面写操作代码了.有兴趣的可以自己在里面加Log测试.

onTerminate()

在程序结束的时候会调用,只是用于仿真机的测试,真机上不会调用,没什么好说的.

registerOnProvideAssistDataListener()&unregisterOnProvideAssistDataListener()

这两个方法看名字是需要可以注册准备语音助手的数据的监听器,需要传入 OnProvideAssistDataListener 接口对象,接口里只有一个onProvideAssistData(Activity activity,Bundle data)的方法,看官网的介绍是当用户启动语音助手时会构建一个Intent.ACTION_ASSIST.而且会附加用户请求帮助时的用户位置信息和上下文.

Android-Application详解

看网上的说法是国外的手机调用语音助手是会调用这个方法,我猜测应该不是国外手机,而是谷歌的语音助手,我用OxygenOS系统测试了一下,发现确实在呼出谷歌助手的时候调用了方法,Bundle不是空的,但是我也没找到里面的信息,应该是我的方法不对,我目前还没探究出这个方法要怎么用.如果有知道的大牛麻烦指导一下

  • 我的测试 :
registerOnProvideAssistDataListener { activity, data ->
         if (data == null) {
             Log.d("日志", "Bundle为空")
         } else {
             var string = "Bundle{"
             for (item in data.keySet()) {
                 string += " $item => ${data.get(item)};"
             }
             string += "}Bundle"
             Log.d("日志",string)
             Log.d("日志","data is:$ACTION_ASSIST + $EXTRA_ASSIST_PACKAGE + $EXTRA_ASSIST_CONTEXT")
             startActivity(object :Intent(ACTION_ASSIST){})
         }
}
复制代码
  • 测试结果 :
日志: Bundle{}Bundle
日志: data is:android.intent.action.ASSIST + android.intent.extra.ASSIST_PACKAGE + android.intent.extra.ASSIST_CONTEXT
复制代码

自定义Application

介绍完上面的方法,现在总算要开始自定义 Application 类了,其实自定义Application类步骤并不多,下面来介绍一下.

  • 创建继承自Application类的子类

    这个就没什么说的了,直接看代码吧

class MyApplication : Application() {

    override fun onCreate() {
        super.onCreate()
		//DO something...
    }
}
复制代码
  • 进入Manifest配置自定义类
<application
         android:name=".MyApplication"            
</application>
复制代码
  • 获取Application类的实例

    获取实例的方法上面已经讲到了,这里就不赘述了.

作用

一般来说是不需要自定义Application类的,但是如果需要实现下面的功能,可以自定义Application类

  • 初始化部分资源(全局对象,全局共享变量,方法等)
  • 对内存占用进行优化
  • 监听APP配置信息和所有Activity的生命周期

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

微交互

微交互

塞弗 (Dan Saffer) / 李松峰 / 人民邮电出版社 / 2013-11-1 / 35.00元

平庸的产品与伟大的产品差就差在细节上。作者Dan Saffer将通过这本书展示怎么设计微交互,即位于功能之内或周边的那些交互细节。你的手机怎么静音?你怎么知道有新邮件了?怎么修改应用的设置?诸如此类的交互细节,既可以毁掉一个产品,也可以成就一个产品。高效而有趣的微交互 ,涉及触发器、规则、循环和模式,还有反馈。透过书中生动、真实的设备及应用示例,读者将理解微交互对于塑造产品个性、赋予产品卖点的重要......一起来看看 《微交互》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

MD5 加密
MD5 加密

MD5 加密工具