美文网首页Android TV
Android Application的生命周期

Android Application的生命周期

作者: 彭空空 | 来源:发表于2019-09-27 15:57 被阅读0次

    导读

    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掉,以免发生内存的泄漏。

    相关文章

      网友评论

        本文标题:Android Application的生命周期

        本文链接:https://www.haomeiwen.com/subject/gqiouctx.html