Application的生命周期和上下文的应用场景
Application是什么?
Application和Activity,Service一样,是Android框架的一个系统组件,当Android程序启动时系统会创建一Application 对象,用来存储系统的一些信息。
通常我们是不需要指定一个Application的,这时系统会自动帮我们创建,如果需要创建自己的Application,也很简单。
创建一个类AppApplication继承Application并在AndroidManifest的application标签中进行注册(只需要给application 标签增加个name属性把自己的Application的名字写入即可)。
Android系统会为每个程序运行时创建一个Application类的对象且仅创建一个
(打开微信安卓系统会为微信创建一个Application对象,再打开微博安卓系统又会为微博创建一个Application对象),
所以Application可以说是单例 (singleton)模式的一个类.
且Application对象的生命周期是整个程序中最长的,它的生命周期就等于这个程序的生命周期。因为它是全局的单例 的,所以在不同的Activity,Service中获得的Application对象都是同一个对象。
所以可以通过Application来进行一些,数据传递,数据共享,数据缓存等操作
Application的应用
通过Application传递数据
假如有一个Activity A, 跳转到 Activity B ,并需要传递一些数据,通常的作法是Intent.putExtra()让Intent携带,或者有 一个Bundle把信息加入Bundle让Intent推荐Bundle对象,实现传递。但这样作有一个问题在于,Intent和Bundle所能携 带的数据类型都是一些基本的数据类型,如果想实现复杂的数据传递就比较麻烦了,通常需要实现Serializable或者
Parcellable接口。这其实是Android的一种IPC数据传递的方法。如果我们的两个Activity在同一个进程当中为什么还要
这么麻烦呢,只要把需要传递的对象的引用传递过去就可以了。
基本思路是这样的。在Application中创建一个HashMap ,以字符串为索引,Object为value这样我们的HashMap就可 以存储任何类型的对象了。
在Activity A中把需要传递的对象放入这个HashMap,然后通过Intent或者其它途经再把这索引的字符串传递给Activity B ,Activity B 就可以根据这个字符串在HashMap中取出这个对象了。只要再向下转个型 ,就实现对象的传递。
Application数据共享
多个组件之间数据共享。举例:两个Activity之间数据共享
Application 对同一个应用程序是唯一的,所以可以使用Application进行数据共享。
Application数据缓存
我一般会习惯在Application中建立两个HashMap一个用于数据的传递,一个用于缓存一些数据。
比如有一个Activity需要从网站获取一些数据,获取完之后我们就可以把这个数据cache到Application当中,
当页面设置到其它Activity再回来的时候,就可以直接使用缓存好的数据了。但如果需要cache一些大量的数据,
最好是cache一些 (软引用)SoftReference ,并把这些数据cache到本地rom上或者sd卡上。
如果在application中的缓存不存在,从本地缓存查找,如果本地缓存的数据也不存在再从网络上获取。
易导致的错误
使用Application如果保存了一些不该保存的对象很容易导致内存泄漏。
如果在Application的onCreate中执行比较耗时的操作,将直接影响程序的启动时间。
一些清理工作不能依靠onTerminate完成,因为android会尽量让你的程序一直运行,所以很有可能onTerminate()方法 不会被调用。
Application的生命周期
1、onCreate() 程序创建的时候执行
2、onTerminate() 程序终止的时候执行
在模拟环境下执行。当终止应用程序对象时调用,不保证一定被调用,
当程序是被内核终止以便为其他应用程序释放资源,那么将不会提醒,
并且不调用应用程序Application对象的onTerminate方法而直接终止进程。
3、onLowMemory() 低内存的时候执行
好的应用程序一般会在这个方法里面释放一些不必要的资源来应付当后台程序已经终止,
前台应用程序内存还不够时的情况。
4、onConfigurationChanged(Configuration newConfig) 配置改变时触发这个方法。
5、onTrimMemory(int level)程序在进行内存清理时执行
生命周期演示
package com.example.apptext;
import android.app.Application;
import android.content.res.Configuration;
import android.util.Log;
public class MyApp extends Application {
private static final String TAG = "MyApp";
@Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "onCreate: ");
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Log.i(TAG, "onConfigurationChanged: ");
}
@Override
public void onLowMemory() {
super.onLowMemory();
Log.i(TAG, "onLowMemory: ");
}
@Override
public void onTerminate() {
super.onTerminate();
Log.i(TAG, "onTerminate: ");
}
@Override
public void onTrimMemory(int level) {
super.onTrimMemory(level);
Log.i(TAG, "onTrimMemory: ");
}
}
记得在清单文件中配置
android:name=".MyApp"
保活进阶
application 被杀死的情况分析:
为了决定在内存较低的时候杀掉哪个进程, Android会根据运行在这些进程内的组件及他们的状态把进程划分成一个”重 要程度层次”.
其重要的程度按以下规则排序:
1、前端进程可以是一个持有运行在屏幕最前端并与用户交互的Activity的进程(onResume方法被调用时),
也可以是持有一个正在运行的IntentReceiver(也就是说他正在执行自己的onReceiveIntent方法)的进程.
在系统中, 只会有少数这样的进程, 并且除非内存已经低到不够这些进程运行, 否则系统不会主动杀掉这些进程.
这时, 设备通常已经达到了需要内存整理的状态, 所以杀掉这些进程是为了不让用户界面停止响应.
2、可视进程是持有一个被用户可见, 但没有显示在最前端 (onPause方法被调用时) 的Activity的进程.
举例来说, 这种进程通常出现在一个前端Activity以一个对话框出现并保持前一个Activity可见时.
这种进程被系统认为是极其重要的, 并且通常不会被杀掉, 除非为了保持所有前端进程正常运行不得不杀掉这些 可见进程.
3、服务进程是持有一个Service的进程, 该Service是由startService()方法启动的, 尽管这些进程用户不能直接看到,
但是通常他们做的工作用户是十分关注的(例如, 在后台播放mp3或是在后台下载上传文件), 所以, 除非为了保 持所有的前端进程和可视进程正常运行外,系统是不会杀掉服务进程的.
4、后台进程是持有一个不再被用户可见的Activity(onStop()方法被调用时)的进程. 这些进程不会直接影响用户体验. 加入这些进程已经完整的,正确的完成了自己的生命周期(访问Activity查看更多细节), 系统会在为前三种进程释 放内存时随时杀掉这些后台进程. 通常会有很多的后台进程在运行, 所以这些进程被存放在一个LRU列表中, 以 保证在低内存的时候, 最近 一个被用户看到的进程会被最后杀掉.
5、空进程是没有持有任何活动应用组件的进程. 保留这种进程的唯一理由是为了提供一种缓存机制, 缩短他的应用下 次运行时的启动时间. 就其本身而言, 系统杀掉这些进程的目的是为了在这些空进程和底层的核心缓存之间平衡 整个系统的资源.
利用 Activity 提升权限
利用 Notification 提升权限
参看我们用服务发广播的例子
利用系统广播拉活
参照广播的例子
利用第三方应用广播拉活
以后说
利用系统Service机制拉活
即service中onStartCommand方法设置flags = START_STICKY;或者onDestroy中重新启动service。
利用 JobScheduler 机制拉活
利用账号同步机制拉活
阿里系,百度系,腾讯系.(手机变慢了…)