Android(安卓)的 Application 初始化
目录(?)[-]
- Application类在项目开发中的使用
- Application类或Context类的误用情况
- 不能用Application缓存数据
- 错误的获取全局Context对象的方式
- 在控件的构造方法中获取Context或者做其他视图操作
[java] view plain copy print ?
自己独立开发项目之后,才发现对Application类并不十分了解,现在开始直接搭建一个新的项目,才踩过这个坑。
1.Context类
Android是用Java语言来编写和,然而Android却需要一个完整的Android工程环境,在这个环境下,我们熟悉的Activity、Service、ContentPrivoder等系统组件才能有自己各自的上下文环境,也就是Context。Context是维持Android应用的核心功能类,是整个Android系统交互的核心。
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的全局初始化工作,比如图片加载框架的全局配置信息设置。
[java] view plain copy print ?- public class MyApplication extends Application {
- private static MyApplication myApplication;
- @Override
- public void onCreate() {
- super.onCreate();
- myApplication = this;
- }
- public static MyApplication getInstance(){
- return myApplication;
- }
- }
然后千万不要忘了在Android项目的Manifest文件中指定Application的实现类,不然系统会创建一个默认的Application类。
[java] view plain copy print ?
- android:name=".MyApplication"
- android:allowBackup="true"
- android:icon="@mipmap/ic_launcher"
- android:label="@string/app_name"
- android:roundIcon="@mipmap/ic_launcher_round"
- android:supportsRtl="true"
- android:theme="@style/AppTheme">
- ".view.MainActivity">
-
- "android.intent.action.MAIN" />
-
"android.intent.category.LAUNCHER" />
3. Application类或Context类的误用情况
1. 不能用Application缓存数据!!!
因为Application会因为进入background后内存不足被系统干掉,进入后系统会重现创建一个Application类,而导致缓存在Application类里的数据全部初始化而丢失。
2. 错误的获取全局Context对象的方式
[java] view plain copy print ?
- 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类在项目开发中的使用
- Application类或Context类的误用情况
- 不能用Application缓存数据
- 错误的获取全局Context对象的方式
- 在控件的构造方法中获取Context或者做其他视图操作
[java] view plain copy print ?
自己独立开发项目之后,才发现对Application类并不十分了解,现在开始直接搭建一个新的项目,才踩过这个坑。
1.Context类
Android是用Java语言来编写和,然而Android却需要一个完整的Android工程环境,在这个环境下,我们熟悉的Activity、Service、ContentPrivoder等系统组件才能有自己各自的上下文环境,也就是Context。Context是维持Android应用的核心功能类,是整个Android系统交互的核心。
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的全局初始化工作,比如图片加载框架的全局配置信息设置。
[java] view plain copy print ?- public class MyApplication extends Application {
- private static MyApplication myApplication;
- @Override
- public void onCreate() {
- super.onCreate();
- myApplication = this;
- }
- public static MyApplication getInstance(){
- return myApplication;
- }
- }
然后千万不要忘了在Android项目的Manifest文件中指定Application的实现类,不然系统会创建一个默认的Application类。
[java] view plain copy print ?
- android:name=".MyApplication"
- android:allowBackup="true"
- android:icon="@mipmap/ic_launcher"
- android:label="@string/app_name"
- android:roundIcon="@mipmap/ic_launcher_round"
- android:supportsRtl="true"
- android:theme="@style/AppTheme">
- ".view.MainActivity">
-
- "android.intent.action.MAIN" />
-
"android.intent.category.LAUNCHER" />
3. Application类或Context类的误用情况
1. 不能用Application缓存数据!!!
因为Application会因为进入background后内存不足被系统干掉,进入后系统会重现创建一个Application类,而导致缓存在Application类里的数据全部初始化而丢失。
2. 错误的获取全局Context对象的方式
[java] view plain copy print ?
- 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类在项目开发中的使用
- Application类或Context类的误用情况
- 不能用Application缓存数据
- 错误的获取全局Context对象的方式
- 在控件的构造方法中获取Context或者做其他视图操作
[java] view plain copy print ?
自己独立开发项目之后,才发现对Application类并不十分了解,现在开始直接搭建一个新的项目,才踩过这个坑。
1.Context类
Android是用Java语言来编写和,然而Android却需要一个完整的Android工程环境,在这个环境下,我们熟悉的Activity、Service、ContentPrivoder等系统组件才能有自己各自的上下文环境,也就是Context。Context是维持Android应用的核心功能类,是整个Android系统交互的核心。
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的全局初始化工作,比如图片加载框架的全局配置信息设置。
[java] view plain copy print ?- public class MyApplication extends Application {
- private static MyApplication myApplication;
- @Override
- public void onCreate() {
- super.onCreate();
- myApplication = this;
- }
- public static MyApplication getInstance(){
- return myApplication;
- }
- }
然后千万不要忘了在Android项目的Manifest文件中指定Application的实现类,不然系统会创建一个默认的Application类。
[java] view plain copy print ?
- android:name=".MyApplication"
- android:allowBackup="true"
- android:icon="@mipmap/ic_launcher"
- android:label="@string/app_name"
- android:roundIcon="@mipmap/ic_launcher_round"
- android:supportsRtl="true"
- android:theme="@style/AppTheme">
- ".view.MainActivity">
-
- "android.intent.action.MAIN" />
-
"android.intent.category.LAUNCHER" />
3. Application类或Context类的误用情况
1. 不能用Application缓存数据!!!
因为Application会因为进入background后内存不足被系统干掉,进入后系统会重现创建一个Application类,而导致缓存在Application类里的数据全部初始化而丢失。
2. 错误的获取全局Context对象的方式
[java] view plain copy print ?
- 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中方法的执行顺序如下图所示:
更多相关文章
- android 启动 service 的两种方法
- Android属性动画之ObjectAnimator控制
- delphi xe5 android iny绿色版+最新SDK/NDK安装方法
- 阿拉伯语系处理方法
- 给 Android(安卓)开发者的 Flutter 指南
- Android的APK文件的反编译方法
- APP字体大小,不随系统的字体大小变化而变化的方法
- Android中的内部类引起的内存泄露
- android Fragments详解二:创建Fragment