美文网首页DevelopAndroid技巧集Android developing tips
在Android开发中怎样使用Application类

在Android开发中怎样使用Application类

作者: 蝉翅的空响 | 来源:发表于2016-09-05 16:07 被阅读12895次

    ---- 在Android开发中怎样使用Application类

    自己独立开发项目才发现以前对Application类并不是十分了解,现在开始直接搭建一个新项目的框架才重新踩过这个坑。

    1. Context类型

    Android是用Java语言来编写和,然而Android却需要一个完整的Android工程环境,在这个环境下,我们熟悉的Activity、Service、ContentPrivoder等系统组件才能有自己各自的上下文环境,也就是Context。Context是维持Android应用的核心功能类,是整个Android系统交互的核心。

    context继承图

    Context的继承结构从图中可以看到,直系子类有两个,一个是ContextWrapper,一个是ContextImpl。那么从名字上就可以看出,ContextWrapper是上下文功能的封装类,而ContextImpl则是上下文功能的实现类。而ContextWrapper又有三个直接的子类,ContextThemeWrapper、Service和Application。其中,ContextThemeWrapper是一个带主题的封装类,而它有一个直接子类就是Activity。

    在这里我们至少看到了几个所比较熟悉的面孔,Activity、Service、还有Application。由此,其实我们就已经可以得出结论了,Context一共有三种类型,分别是Application、Activity和Service。这三个类虽然分别各种承担着不同的作用,但它们都属于Context的一种,而它们具体Context的功能则是由ContextImpl类去实现的。

    一种比较特殊的情况是Dialog要求在Activity的Context中弹出,而一些全局的例如网络终端的Dialog需要什么特殊权限。

    2. Application类在项目开发中的使用

    首先在项目目录下一个Java类继承Application类,实现是onCreate()方法。这个类可以做APP的全局初始化工作,比如图片加载框架的全局配置信息设置。

    public class AndroidApplication extends Application {
    
        private static AndroidApplication instance;
    
        @Override
        public void onCreate() {
            super.onCreate();
            instance = this;
        }
    
        public static AndroidApplication getInstance(){
            return instance;
        }
    }
    

    然后千万不要忘了在Android项目的Manifest文件中指定Application的实现类,不然系统会创建一个默认的Application类。

    <application
            android:name=".AndroidApplication"
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:supportsRtl="true"
            android:theme="@style/AppTheme">
            <activity android:name=".MainActivity">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN"/>
    
                    <category android:name="android.intent.category.LAUNCHER"/>
                </intent-filter>
            </activity>
        </application>
    
    

    3. Application类或Context类的误用情况

    1. 不能用Application缓存数据!!!

    因为Application会因为进入background后内存不足被系统干掉,进入后系统会重现创建一个Application类,而导致缓存在Application类里的数据全部初始化而丢失。

    2. 错误的获取全局Context对象的方式

    public class AnddroidApplication extends Application {  
          
        private static AnddroidApplication app;  
          
        public static AnddroidApplication getInstance() {
            if (app == null) {  
                app = new AnddroidApplication();  
            }  
            return app;  
        }  
          
    } 
    
    

    上面这种方式如果是单纯的Java工程可能没有问题,但是在Android里这样说大错特错的。因为Application是系统组件,系统组件实例是要由系统去创建的,如果我们这里直接创建一个,不过是简单的Java对象而已,不具备任何Context能力,也无法进行任何Context操作。标准的写法就本文的第一段示意代码那样。

    3. 在控件的构造方法中获取Context或者做其他视图操作

    写过Android的同学应该知道自己或者看别人dome都很少或者基本看不到在控件构造函数内进行初始化,获取参数等这些操作吧!是的,这样做是很容易出难以发现的Bug的。具体原因是在ContextWrapper类的源码中,他有一个attachBaseContext()方法,这个方法会将传入的一个Context参数赋值给mBase对象,之后mBase对象就有值了。而我们又知道,所有Context的方法都是调用这个mBase对象的同名方法,那么也就是说如果在mBase对象还没赋值的情况下就去调用Context中的任何一个方法时,就会出现空指针异常,上面的代码就是这种情况。Application中方法的执行顺序如下图所示:

    Application方法执行顺序

    相关文章

      网友评论

      • edf360af8784:你好,我遇到一个问题,接入了华为SDK后,发布的APK在安卓7.0可以正常运行,但是在安卓6.0跟8.0上,安装成功后,点击图标无反应,个人查不到不相应的原因,想请您帮忙提点一下,是不是您文章提到Application没指定,所以运行不起来。方便的话希望您加一下我企鹅397831334,请不要担心,仅限于这次问题的交流,不会有多余的打扰,拜托
      • 90cca7ae0cad:笔者写的第一点就有误,Aplication属于系统的一个基本组件,生命周期是这个应用的生命周期,比service生命周期还长。当Alication被系统杀死后整个应用程序都已经退出了。可以做数据缓存,仅仅是缓存,如果是需要持久化还需要将数据保存到本地。请及时更新说明,谢谢
        蝉翅的空响:@伊米_a42f 是可以做的,但是为了程序的稳定性容错还是要做持久化处理,建议写成一个单例放在内存缓冲并做持久化操作
      • 55596c0b1141: 被static修饰的成员变量和成员方法独立于该类的任何对象。static对象可以在它的任何对象创建之前访问.
        第一种写法会遇到instance为空的情况
        蝉翅的空响:是的,考虑到Android中到Application类在应用线程存活到状态下总是有实例的,所以理论上是可行到,如果遇到可以给我看下也改正下自己到理解:smile:
      • f3f4672ef98e:有处笔误 app = new MyApplication(); 应该是 app = new AnddroidApplication();
        不过本文帮到我了 谢谢作者:smile:
        06aff8f89281:大神,这样子获取Context一定不为空吗? 我这样子写会遇到空指针问题
        f3f4672ef98e: @蝉翅的空响 😀
        蝉翅的空响:能帮到你就很开心了,已经更正了。谢谢提醒了:smile:

      本文标题:在Android开发中怎样使用Application类

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