关于Android Application类的一些认识_认识andriod的application-程序员宅基地

技术标签: 技术笔记  技术杂谈  

在学习别人的代码时候,发现有一个Application类,趁机了解一下~

下面是看到的几篇比较好的文章。转载过来学习学习~


第一篇:Android Application的作用

What is Application

Application和Actovotu,Service一样是android框架的一个系统组件,当android程序启动时系统会创建一个 application对象,用来存储系统的一些信息。通常我们是不需要指定一个Application的,这时系统会自动帮我们创建,如果需要创建自己 的Application,也很简单创建一个类继承 Application并在manifest的application标签中进行注册(只需要给Application标签增加个name属性把自己的 Application的名字定入即可)。

android系统会为每个程序运行时创建一个Application类的对象且仅创建一个,所以Application可以说是单例 (singleton)模式的一个类.且application对象的生命周期是整个程序中最长的,它的生命周期就等于这个程序的生命周期。因为它是全局 的单例的,所以在不同的Activity,Service中获得的对象都是同一个对象。所以通过Application来进行一些,数据传递,数据共享 等,数据缓存等操作。

 

Data passing between components using Application

假如有一个Activity A, 跳转到 Activity B ,并需要推荐一些数据,通常的作法是Intent.putExtra() 让Intent携带,或者有一个Bundle把信息加入Bundle让Intent推荐Bundle对象,实现传递。但这样作有一个问题在 于,Intent和Bundle所能携带的数据类型都是一些基本的数据类型,如果想实现复杂的数据传递就比较麻烦了,通常需要实现 Serializable或者Parcellable接口。这其实是Android的一种IPC数据传递的方法。如果我们的两个Activity在同一个 进程当中为什么还要这么麻烦呢,只要把需要传递的对象的引用传递过去就可以了。

基本思路是这样的。在Application中创建一个HashMap<String,Object> ,以字符串为索引,Object为value这样我们的HashMap就可以存储任何类型的对象了。在Activity A中把需要传递的对象放入这个HashMap,然后通过Intent或者其它途经再把这人索引的字符串传递给Activity B ,Activity B 就可以根据这个字符串在HashMap中取出这个对象了。只要再向下转个型 ,就实现了对象的传递。

Data caching in Application

我一般会习惯在application中建立两个HashMap<String,Object>一个用于数据的传递,一个用于缓 存一些数据。比如有一个Activity需要从网站获取一些数据,获取完之后我们就可以把这个数据cache到Application 当中,当页面设置到其它Activity再回来的时候,就可以直接使用缓存好的数据了。但如果需要cache一些大量的数据,最好是cache一些 (软引用)SoftReference ,并把这些数据cache到本地rom上或者sd卡上。如果在application中的缓存不存在,从本地缓存查找,如果本地缓存的数据也不存在再从网 络上获取。

PitFalls

使用Application如果保存了一些不该保存的对象很容易导致内存泄漏。如果在Application的oncreate中执行比较 耗时的操作,将直接影响的程序的启动时间。不些清理工作不能依靠onTerminate完成,因为android会尽量让你的程序一直运行,所以很有可能 onTerminate不会被调用。

MemoryLeak

在Java中内存泄漏是只,某个(某些)对象已经不在被使用应该被gc所回收,但有一个对象持有这个对象的引用而阻止这个对象被回收。比如我 们通常会这样创建一个View TextView tv = new TextView(this);这里的this通常都是Activity。所以这个TextView就持有着这个Activity的引用。下面看张图 (Google IO 2011 ppt中抄得)

Android笔记 <wbr>Application对象的使用-数据传递以及内存泄漏问题

通常情况下,当用户转动手机的时候,android会重新调用OnCreate()方法生成一个新的Activity,原来的 Activity应该被GC所回收。但如果有个对象比如一个View的作用域超过了这个Activity(比如有一个static对象或者我们把这个 View的引用放到了Application当中),这时候原来的Activity将不能被GC所回收,Activity本身又持有很多对象的引用,所以 整个Activity的内存被泄漏了。

经常导致内存泄漏的一些原因:

keeping a long-lived reference to a Context.持有一个context的对象,从而gc不能回收。

1,一个View,的作用域超出了所在的Activity的作用域,比如一个static的View或者 把一个View cache到了application当中 etc

2,某些与View关联的Drawable的作用域超出了Activity的作用域。

3,Runnable对象:比如在一个Activity中启用了一个新线程去执行一个任务,在这期间这个Activity被系统回收了, 但Runnalbe的任务还没有执行完毕并持有Activity的引用而泄漏,但这种泄漏一般来泄漏一段时间,只有Runnalbe的线程执行完闭,这个 Activity又可以被正常回收了。

4,内存类的对象作用域超出Activity的范围:比如定义了一个内存类来存储数据,又把这个内存类的对象传给了其它Activity 或者Service等。因为内部类的对象会持有当前类的引用,所以也就持有了Context的引用。解决方法是如果不需要当前的引用把内部类写成 static或者,把内部类抽取出来变成一个单独的类,或者把避免内部对象作用域超出Activity的作用域。

out Of Memery Error 在android中每一个程序所分到的内存大小是有限的,如果超过了这个数就会报Out Of Memory Error。android给程序分配的内存大小与手机硬件有关,以下是一些手机的数据:

G1:16M Droid:24 Nexus One:32M Xoom:48Ms

所以尽量把程序中的一些大的数据cache到本地文件。以免内存使用量超标。

Snippets

1,通过Application在两个Activity间传递数据

Android笔记 <wbr>Application对象的使用-数据传递以及内存泄漏问题  Android笔记 <wbr>Application对象的使用-数据传递以及内存泄漏问题

记得数据传递完成之后,把存放在application的HashMap中的数据remove掉,以免发生内存的泄漏。

 

 

其实我们开发的每个android应用程序就是一个Appliction,定义这个类往往是在AndroidManifes.xml中用到。例如:

 

<application android:icon="@drawable/icon"
      android:label="@string/app_name"
      android:name=".MyApplication">
 
这里定义了我们整个应用程序的属性,例如名称和图标。
我们可以自定义Appliction,例如:
public class MyApplication extends Application {
  }
就是这儿,将我们以前一直用的默认Application给他设置成我们自己做的MyApplication
MyApplication类的作用是为了放一些全局的和一些上下文都要用到变量和方法之类的。


谈谈你对Application类的理解

其实说对什么的理解,就是考察你对这个东西会不会用,重点是有没有什么坑!


首先,Application在一个Dalvik虚拟机里面只会存在一个实例,所以你不要傻傻的去弄什么单例模式,来静态获取Application了,你把Application构造函数设置成privete都不可能实现(我年轻的时候就这么傻傻的试过,想着如果可以通过Singleton.getInstance()就能获取到Application对象,多爽呀~)。

那么为什么强调说是一个Dalvik虚拟机,而不是说一个App呢?

因为一个App有可能有多个Dalvik虚拟机,也就是传说中的多进程模式。在这种模式下,每一个Dalvik都会存在一个Application实例,他们之间没有关系,在A进程Application里面保存的数据不能在B进程的Application获取,因为他们根本不是一个对象,而且被隔离在了两个进程里面,所以这里强调是一个Dalvik虚拟机,而不是一个App。


其次,Application的实质是一个Context,它继承自ContextWrapper。

    android.content.Context
       ↳  android.content.ContextWrapper
        ↳ android.app.Application     

ContextWrapper是什么玩意?就是对Context的一个包装而已。

Application有两个子类,一个是MultiDexApplication,如果你遇到了"65535"问题,可以选择继承自他,完成多Dex打包配置的相关工作。

另外一个是在TDD(测试用例驱动)开发模式中使用Moke进行测试的时候用到的,可以来代替Application的Moke类MockApplication。


在应用启动的时候,会首先调用Application.attach(),当然,这个方法是隐藏的,开发者能接触到的第一个被调用的方法其实是Application.onCreate(),我们通常会在这个方法里面完成各种初始化,比如图片加载库、Http请求库的默认配置初始化操作等等。但是最好别在这个方法里面进行太多耗时操作,因为这会影响App的启动速度,所以对于不必要的操作可以使用异步操作、懒加载、延时加载等策略来减少对UI线程的影响。


除此之外,由于在Context中可以通过getApplicationContext()获取到Application对象,或者是通过Activity.getApplication()Service.getApplication()获取到Application,所以可以在Application保存全局的数据,供所有的Activity或者是Service使用。

PS:使用上面的三种方法获取到的都是同一个Application对象,getApplicationContext()是在Context的实现类ContextImpl中具体实现的,而getApplication()则是在Activity和Service中单独实现的,所以他们的作用域不同,但是获取到的都是同一个Application对象,因为一个Dalvik虚拟机只有一个Application对象。

但是这里存在着一个坑,那就是在低内存情况下,Application有可能被销毁,从而导致保存在Application里面的数据信息丢失,最后程序错乱,甚至是Crash。

所以当你想在Application保存数据的时候,请做好为空判断,或者是选择其他方式保存你的数据信息。


另外,在Application中存在着几个有用的方法,比如onLowMemory()和onTrimMemory(),在这两个方法里面,我们可以实现自己的内存回收逻辑,比如关闭数据库连接、移除图片内存缓存等操作来降低内存消耗,从而降低被系统回收的风险。


最后,就是要注意Application的生命周期,他和Dalvik虚拟机生命周期一样长,所以在进行单例或者是静态变量的初始化操作时,一定要用Application作为Context进行初始化,否则会造成内存泄露的发生。使用Dialog的时候一般使用Activity作为Context,但是也可以使用Application作为上下文,前提是你必须设置Window类型为TYPE_SYSTEM_DIALOG,并且申请相关权限。这个时候弹出的Dialog是属于整个Application的,弹出这个Dialog的Activity销毁时也不会回收Dialog,只有在Application销毁时,这个Dialog才会自动消失。

更多参考资料



版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Goo_x/article/details/50837828

智能推荐

CorelDRAW Graphics Suite2024最新永久免费版功能强大的图形设计软件-程序员宅基地

文章浏览阅读801次,点赞7次,收藏11次。CorelDRAW Graphics Suite是一款功能强大的图形设计软件套件,它提供了丰富的绘图工具、编辑功能和设计资源,适用于从专业设计师到普通用户的广泛群体。以下是CorelDRAW Graphics Suite的一些主要功能特点:

python建立一个http请求_python构造一个http请求-程序员宅基地

文章浏览阅读761次。我们经常会用python来进行抓包,模拟登陆等等, 势必要构造http请求包。http的request通常有4个方法get,post,put,delete,分别对应于查询,更新,添加,删除。我们经常用到的也就get,post。1.用python构造get#build request for accessed urlhomeReq = urllib.request.Request(url = csd..._python 如何自定义http包

基于stm32的脉搏血氧仪设计_简易脉搏血氧仪电路设计实验-程序员宅基地

文章浏览阅读2.4k次,点赞2次,收藏23次。外部事件的响应在中断里面完成,事件的处理还是回到轮询系统中完成,中断在这里我们称为前台,main 函数 里面的无限循环我们称为后台,在顺序执行后台程序的时候,如果有中断来临,那么中断会打断后台程序的正常执行流,转而去执行中断服务程序,在中断服务程序里面标记事件,如果事件要处理的事情很简短,则可在中断服务程序里面处理,如果事件要处理的事情比较多,则返回到后台程序里面处理。每个任务都是独立的,互不干扰的所以相比前后台系统,多任务系统的事件响应也是在中断中完成的,但是事件的处理是在任务中完成的。_简易脉搏血氧仪电路设计实验

iOS 字符串中动态改变小数点个数_ios stringwithformat 小数自动-程序员宅基地

文章浏览阅读1.3k次。//联系人:石虎 QQ: 1224614774 昵称:嗡嘛呢叭咪哄一、动态改变小数点个数- (void)viewDidLoad { [super viewDidLoad]; NSInteger pointNum = 7; CGFloat num = 3.23323000000; _ios stringwithformat 小数自动

development/tools/idegen/idegen.sh  Couldn‘t find host out directory. Make sure ANDROID_HOST_OUT is_development/tools/idegen/idegen.sh失败-程序员宅基地

文章浏览阅读936次。执行$:development/tools/idegen/idegen.sh  Couldn't find host out directory. Make sure ANDROID_HOST_OUT is $:~/rom-space$ export ANDROID_HOST_OUT=out/host/$:~/rom-space$ development/tools/idegen/idegen.shRead excludes: 3msTraversed tree: 16592ms$:~/ro_development/tools/idegen/idegen.sh失败

英语文化研究-程序员宅基地

文章浏览阅读230次。世界主流媒体:华尔街日报纽约时报华盛顿邮报时代周刊美国新闻周刊泰晤士报今日美国BBC VOA1575词汇 英语语言学研究阅读500词 考的不是套路,是人的一种科学的思维模式英语语法大全: 词汇 语法 句子 短语 介词动词名词谓词主宾补..._英语文化的研究

随便推点

tv端h5_H5在三端开发遇到的问题(TV/PC/MOBILE)-程序员宅基地

文章浏览阅读1.1k次。项目简介公司最近开发会员体系项目,前端利用H5技术嵌入三端开发页面,TV端原生技术是C++,PC端原生技术是JAVA。传值问题Javascript与安卓/IOS进行交互。原生把方法暴露给window。前端只需要下window对象调用方法,进行传值即可。notice:function(token,uuid){var pattern = new RegExp('iPhone|iPad', 'ig');..._电视端app可以用h5写吗

python下mqtt服务器的搭建_转 【MQTT】在Windows下搭建MQTT服务器-程序员宅基地

文章浏览阅读498次。MQTT简介MQ 遥测传输 (MQTT) 是轻量级基于代理的发布/订阅的消息传输协议,设计思想是开放、简单、轻量、易于实现。这些特点使它适用于受限环境。该协议的特点有:使用发布/订阅消息模式,提供一对多的消息发布,解除应用程序耦合。对负载内容屏蔽的消息传输。使用 TCP/IP 提供网络连接。小型传输,开销很小(固定长度的头部是 2 字节),协议交换最小化,以降低网络流量。使用 Last Will ..._python window环境搭建 mqtt服务端

win10安装python详细过程_win10怎么正确安装python-程序员宅基地

文章浏览阅读10w+次,点赞53次,收藏173次。关于python的安装一切语言皆为工具接下来咱们就开始吧一切语言皆为工具既然你决定安装它,那就已经告知自己要掌握这门工具,但是有一定你一定要铭记于心那就是:python 是个工具时刻想着如何用它解决你的问题【哪怕是一个简单的想法】接下来咱们就开始吧下载安装软件包登录官网 :https://www.python.org/downloads/release/python-373..._win10怎么正确安装python

《物联网安全技术》期末复习总结_物联网安全技术期末-程序员宅基地

文章浏览阅读645次,点赞18次,收藏7次。外链图片转存中…(img-FsKGMBmt-1712872591998)][外链图片转存中…(img-lbxAiVwD-1712872591999)][外链图片转存中…(img-ZDKgmHSi-1712872591999)][外链图片转存中…(img-4IENRibI-1712872591999)][外链图片转存中…(img-laWlj5NB-1712872592000)][外链图片转存中…(img-dtiEALR7-1712872592000)]

机器学习(Machine Learning)&深度学习(Deep Learning)资料(Chapter 1)_根据自己的理解,阐述机器学习,深度学习的基本概念,并阐述学习常用的模型和方-程序员宅基地

文章浏览阅读1.2k次。https://github.com/ty4z2008/Qix/blob/master/dl.md注:机器学习资料篇目一共500条,篇目二开始更新希望转载的朋友,你可以不用联系我.但是一定要保留原文链接,因为这个项目还在继续也在不定期更新.希望看到文章的朋友能够学到更多.此外:某些资料在中国访问需要梯子.《Brief History of Machine L_根据自己的理解,阐述机器学习,深度学习的基本概念,并阐述学习常用的模型和方

一文看清:Java的核心技术是什么?_java核心技术学什么的-程序员宅基地

文章浏览阅读296次。随着互联网的发展,Java应用范围不断的扩大,可进行面向对象的应用开发;可视化、可操作化的软件开发;动态画面设计和调试;数据库操作连接设计等。由于国际厂商相继推出各种基于Java技术的应用服务器以及各种应用软件,带动了Java在金融、电信、制造等领域日益广泛的应用。Java应用这么广泛,人才需求与日俱增越多,想转行来学Java的人也越来越多。学好Java能够让程序员在大数据处理、分布式计算等方面有所发展,本文简单为大家介绍Java设计基本概述,并将其与C++进行对比介绍。让你快速了解Java_java核心技术学什么的