一、Application简介
Application是什么?
Application和Activity、Service一样,是Android框架的一个系统组件,当Android程序启动时系统会创建一个Application对象,用来存储系统的一些信息。
通常我们是不需要指定一个Application的,这时系统会自动帮我们创建,如果需要创建自己的Application,也很简单。创建一个类appApplication继承Application并在Android Manifest的application标签中进行注册(只需要给application标签增加个name属性把自己的Application的名字写入即可)。
Android系统会为每个程序运行时创建一个Application类的对象且仅创建一个,所以Application可以说是单例(singleton)模式的一个类。且Application对象的生命周期是整个程序中最长的,它的生命周期就等于这个程序的生命周期。因为它是全局的单例,所以在不同的Activity,Service中获得的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数据缓存
一个Activity需要从网站获取一些数据,获取完之后我们就可以把这个数据cache到Application当中,当页面设置到其它Activity再回来的时候,就可以直接使用缓存好的数据了。但如果需要cache一些大量的数据,最好是cache一些软引用(softReference),并吧这些数据cache到本地rom上或者sd卡上。如果在application中的缓存不存在,从本地缓存查找,如果本地缓存的数据也不存在再从网络上获取。
易导致的错误
使用Application如果保存了一些不该保存的对象很容易导致内存泄漏。如果在Application的onCreate中执行比较耗时的操作,将直接影响程序的启动时间。一些清理工作不能依靠onTerminate完成,因为Android会尽量让你的程序一直运行,所以很有可能onTerminate()方法不会被调用。
二、Application的生命周期
1、onCreate()程序创建的时候执行
2、onTerminate()程序终止的时候执行
在模拟环境下执行,当终止应用程序对象时调用,不保证一定被调用,当程序是被内核终止以便为其它程序释放资源,那么将不会提醒,并且不调用应用程序Application对象的onTermiante方法而直接终止进程。
3、onLowMemory()低内存的时候执行
好的应用程序一般会在这个方法里面释放一些不必要的资源来应付当后台程序已经终止,前台应用程序内存还不够时的情况。
4、onConfigurationChanged(Configuration newConfig)配置改变时触发这个方法。
5、onTrimMemory(int level)程序在进行内存清理时执行
三、Application被杀死的情况分析
Android会根据运行再这些进程内的组件及他们的状态把进程划分成一个“重要度层次”,进而决定在内存较低的时候杀掉那个进程。其重要的程度按以下规则排序:
- 前端进程
前端进程就是目前显示在屏幕上和用户交互的进程,在系统中前端进程数量很少,比如用户正在使用微信聊天,微信APP此时为前端进程。而这种进程是对用户体验的影响最大,只有系统的内存稀少到不足以维持和用户的基本交互时才会销毁前端进程。因此这种进程的重要性时最高的。
- 可视进程
可视进程是一个被用户可见,但没有显示在最前端(onPause方法被调用时)的Activity的进程。比如在微信聊天时候,输入文字时的搜狗输入法。这种进程被系统认为是极其重要的,并且通常不会被杀掉,除非为了保持所有前端进程正常运行不得不杀掉这些可见进程。
- 服务进程
这是一个包含Service的进程,该Service是由startService()方法启动的,尽管这些进程用户不能直接看到,比如在后台播放MP3或是在后台下载上传文件。因此系统保持他们运行,除非没有足够内存来保证所有的前端进程和可视进程。
- 后台进程
要说明的是,Android里的后台进程是调用了OnStop()的,可以理解成用户暂时没有和这个进程交互的愿望,所以在这里后台进程有点“待销毁”的意思。
- 空进程
是没有持有任何活动应用组件的进程,保留这种进程的唯一理由是为了提供一种缓存机制,缩短他的应用下次运行时的启动时间。系统杀掉这些进程,是为了在这些空进程和底层的核心缓存之间平衡整个系统的资源。