http://www.cnmsdn.com/html/201109/1316080337ID10097.html

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

  Data caching in Application

  我一般会习惯在application中建立两个HashMap一个用于数据的传递,一个用于缓 存一些数据。比如有一个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会重新调用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间传递数据

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

  如果有什么疑问,发现bug或者有更好的想法或者建议,或者附件无法下载。请发邮件至arthurbrown@163.com


-----------------------------------------------------------------------------------------------------------------------------------------------------------------

Android应用程序开发中,有的时候我们在应用程序的任何一个地方都需要访问一个全局变量,也就是在任何一个Activity中都可以访问的变量。它不会因为Activity的生命周期结束而消失。要实现应用程序级的变量,我们可以通过Application这个类来实现。


首先,我们新建一个类HelloApplication继承Android.app.Application类,然后在我们的类中增加一些变量。如下所示:
  1. public class HelloApplication extends Application {
  2. private int globalVariable=1;

  3. public int getGlobalVariable() {
  4. return globalVariable;
  5. }

  6. public void setGlobalVariable(int globalVariable) {
  7. this.globalVariable = globalVariable;
  8. }
  9. }
复制代码 然后在应用程序配置文件AndroidManifest.xml中进行相应的配置,如下图所示:

附件: 你需要登录才可以下载或查看附件。没有帐号?注册

完成之后,我们在应用程序的任何一个Activity中可以通过如下方法访问我们的变量:
  1. ((HelloApplication)getApplication()).setGlobalVariable(10);
  2. int valiable=((HelloApplication)getApplication()).getGlobalVariable();
复制代码 怎么样? 是不是很简单?

Application对象只有在应用程序中所有Activity都destroy时才会destrory,所有我们可以在任何一个Activity中访问它。

那么为什么我们不能使用static 变量来存放全局变量呢?如下所示:
  1. public class DataStoreClass {
  2. private static int globalVariable=1;

  3. public static int getGlobalVariable() {
  4. return globalVariable;
  5. }

  6. public static void setGlobalVariable(int newGlobalVariable) {
  7. globalVariable = newGlobalVariable;
  8. }
  9. }
复制代码 通过这种方式,DataStoreClass类可能会像Activity一样在某些时候被android系统强行销毁。所以在应用程序运行期间,DataStoreClass的值可能会丢失,或得到一些您不想要的值。(文/ideasandroid)

更多相关文章

  1. android上如何写配置文件
  2. Android中sqllite存储海量数据解决办法
  3. Android(安卓)SQLiteOpenHelper的使用心得
  4. Android写入配置信息
  5. Android页面之间进行数据回传
  6. Android之数据存储笔记
  7. android开发学习笔记(一)分别通过GET和POST请求从服务器端获取数
  8. Android联系人自动过滤并显示“新建联系人”
  9. Android(安卓)实现 Launcher

随机推荐

  1. 【Android 基础】TextView的属性详解
  2. Android调试之Logcat
  3. Android中用shape做渐变,边框,圆角等效果
  4. android webview自定义标签!(实现打电话的
  5. [置顶] Android屏幕适配全攻略
  6. Android Gradle编译学习日记之二(使用 Gra
  7. Android -- 多线程下载
  8. [转]Android(安卓)adb不是内部或外部命令
  9. Android 设置软键盘搜索键以及监听搜索键
  10. Android的SQLite使用介绍