Android Application的生命周期

导读

Application是什么

Application和Activity、Service一样是Android框架的一个系统组件,当Android程序启动时系统会创建一个 Application对象,用来存储系统的一些信息。
Application的生命周期等于这个程序的生命周期,又因为Application是全局的单例的,所以在不同的Activity,Service中获得的对象都是同一个对象。所以通过Application来进行一些数据传递、数据共享、数据缓存等操作。

一般写Demo是不需要指定一个Application的,这时系统会自动帮我们创建;而实际项目中基本上都是需要创建自己的Application的,创建一个类继承 Application并在AndroidManifest清单文件中的Application标签中进行注册(只需要给Application标签增加个name属性把自己的 Application的名字定入即可)。android系统会为每个程序运行时创建一个Application类的对象且仅创建一个,所以Application可以说是单例 (singleton)模式的一个类。

Application生命周期

  1. onConfigurationChanged( ) :在配置被改变时触发 。
  2. onCreate() :在程序创建时创建。
  3. onLowMemory() :内存不够时触发。
  4. onTerminate() :当终止程序时调用 但是不能保证一定调用
  5. onTrimMemory() :在内存清理时触发
public class App extends Application {
    @Override
    public void onCreate() {
        // 程序创建的时候执行
        Log.d(TAG, "onCreate");
        super.onCreate();
    }
    @Override
    public void onTerminate() {
        // 程序终止的时候执行
        Log.d(TAG, "onTerminate");
        super.onTerminate();
    }
    @Override
    public void onLowMemory() {
        // 低内存的时候执行
        Log.d(TAG, "onLowMemory");
        super.onLowMemory();
    }
    @Override
    public void onTrimMemory(int level) {
        // 程序在内存清理的时候执行
        Log.d(TAG, "onTrimMemory");
        super.onTrimMemory(level);
    }
    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        Log.d(TAG, "onConfigurationChanged");
        super.onConfigurationChanged(newConfig);
    }
}

使用Application传递数据

在android中通常会使用Intent(Bundle)进行数据通信,但一般为简单数据类型,如数据类型相对复杂(如对象)则需要实现 Serializable或者Parcelable接口,其实可以使用Application传递复杂数据。

基本思路是这样的。在Application中创建一个HashMap ,以字符串为key,Object为value这样我们的HashMap就可以存储任何类型的对象了

使用Application数据缓存

既然可以在Application中使用HashMap 进行传递数据,自然是可以进行一些缓存动作了,不过笔者基本没有这样操作过,同时需要注意内存泄漏。

Application的Context

  • Context是一个应用程序环境的信息,即上下文。
  • 该类是一个抽象(abstract class)类,Android提供了该抽象类的具体实现类(后面我们会讲到是ContextIml类)。
  • 通过它我们可以获取应用程序的资源和类,也包括一些应用级别操作,例如:启动一个Activity,发送广播,接受Intent信息 等


    Context

可以看到Activity、Service、Application都是Context的子类。
也就是说,Android系统的角度来理解:Context是一个场景,代表与操作系统的交互的一种过程。从程序的角度上来理解:Context是个抽象类,而Activity、Service、Application等都是该类的一个实现。

Application的oncreate方法会执行几次,会不会多次执行?

通常情况下,App默认开启一个进程,进程名就是AndroidManifest.xml文件中我们项目的包名,所有的基本组件都是在这个进程中进行,Application的onCreate方法会被执行一次。但是如果我们工程涉及到多进程,那么就会出现Application的onCreate方法被多次执行情况。

解决oncreate方法多次被调用:

1、定义获取进程的方法

    private String getProcessName(Context context) {
        try {
            ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
            List<ActivityManager.RunningAppProcessInfo> runningApps = am.getRunningAppProcesses();
            if (runningApps == null) {
                return null;
            }
            for (ActivityManager.RunningAppProcessInfo proInfo : runningApps) {
                if (proInfo.pid == android.os.Process.myPid()) {
                    if (proInfo.processName != null) {
                        return proInfo.processName;
                    }
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

2、在onCreate方法中进行比对

 @Override
    public void onCreate() {
        super.onCreate();
        String processName = getProcessName(this);
        if (processName!= null) {
            String pkName = this.getPackageName();
            //只有主进程,才执行后续逻辑
            if(processName.equals(pkName)==false) {
                return;
            }
        }

使用Application避免一些内存泄漏(Memory Leak)

在Java中内存泄漏是指某个(某些)对象已经不在被使用应该被GC回收,但有一个对象持有这个对象的引用而阻止这个对象被回收。

比如在项目中经常用到单例模式,而很多单例是需要传递Context的,由于sInstance是一个static且强引用的,若此时传递Context的是xxxActivity.this,那么这个xxxActivity就不会被内存回收,就会造成内存泄漏。

解决办法就是Context传递context.getApplicationContext()

ps 经常导致内存泄漏核心原因分析(跳转连接)

以下内容等待被编辑到指定位置
ps 经常导致内存泄漏核心原因分析(跳转连接)

keeping a long-lived reference to a Context

上述是常见的内存泄漏的提示,即持有一个context的对象,从而GC不能回收,为什么会有这样的情况呢

  • 一个View的作用域超出了所在的Activity的作用域,比如一个static的View或者把一个View cache到了application
  • 某些与View关联的Drawable的作用域超出了Activity的作用域.
  • Runnable对象:比如在一个Activity中启用了一个新线程去执行一个任务,在这期间这个Activity被系统回收了, 但Runnalbe的 任务还没有执行完毕并持有Activity的引用而泄漏,但这种泄漏一般来泄漏一段时间,只有Runnalbe的线程执行完闭,这个 Activity又可以被正常回收了。
  • 内存类的对象作用域超出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到本地文件。以免内存使用量超标。
    记得数据传递完成之后,把存放在application的HashMap中的数据remove掉,以免发生内存的泄漏。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,723评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,003评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,512评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,825评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,874评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,841评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,812评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,582评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,033评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,309评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,450评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,158评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,789评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,409评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,609评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,440评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,357评论 2 352

推荐阅读更多精彩内容