Android清单文件具体解释(三)----应用程序的根节点<application>
<application>节点是AndroidManifest.xml文件里必须持有的一个节点,它包括在<manifest>节点下。通过<application>节点的相关属性,我们能够声明Android应用程序的相关特性。这个节点包括全部应用程序组件的节点,包括Activity,服务,广播接收器和内容提供者。而且包括了一些可能影响全部组件的属性。这些属性中的当中一些又会作为默认值而被设置到应用程序组件的同样属性上,比方icon,label,permission,process,taskAffinity和allowTaskReparenting等,而其它的一些值则作为应用程序的总体被设置,而且不能被应用程序组件的属性覆盖,比方debuggable,enabled,description和allowClearUserData等。
1.<application>节点配置
一般来说。在生成Android应用程序的时候。默认的AndroidManifest.xml文件里就已经包括了一些默认的<application>节点,当中包括应用程序的基本属性。
如今我们就来看看<application>节点信息的全集,代码例如以下:
<application android:allowTaskReparenting=["true"|"false"]
android:backupAgent="string"
android:debuggable=["true"|"false"];
android:description="string resource"
android:enabled=["true"|"false"]
android:hasCode=["true"|"false"]
android:hardwareAccelerated=["true"|"false"]
android:icon="drawable reource"
android:killAfterRestore=["true"|"false"]
android:label="string resource"
android:logo="drawable resource"
android:manageSpaceActivity="string"
android:name="string"
android:permission="string"
android:persistent=["true"|"false"]
android:process="string"
android:restoreAnyVersion=["true"|"false"]
android:taskAffinity="string"
android:theme="resource or theme">
</application>
2.怎样实现Application类
首先要介绍的是android:name属性,它指的是Application类的子类,当应用程序进程被启动的时候,由android:name属性指定的类将会在全部应用程序组件(activity,服务,广播接收器,内容提供者)被实例化之前实例化。
普通情况下。应用程序无需指定这个属性,Android会实例化Android框架下的applicaiton类。
然而。在一些特殊的情况下。比方希望在应用程序组件启动之前就完毕一个初始化工作。或者在系统低内存的时候做一些特别的处理,就要考虑实现自己的Application类的一个子类。
在Android系统提供的系统应用中。就有一个实现了自己的Application实例。这个应用程序就是Launcher。
我们能够仿照它来实现一个自己的Application类。详细过程例如以下。
①创建一个叫做ApplicationTest的项目,而且在默认生成的MainActivity里的onCreate()方法中加入一行代码来输出一条日志。这样就能够看到Application创建时间,详细代码例如以下:
public class MainActivity extends Activity {
private static final String TAG="MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.e(TAG,"MainActivity is created");
}
}
②实现自己的MyApplication类,代码例如以下:
public class MyApplication extends Application {
private static final String TAG="MyApplication";
@Override
public void onCreate() {
super.onCreate();
Log.e(TAG,"MyApplication is created");
}
}
③将MyApplication加入到清单文件AndroidManifest.xml中<application>内android:name中
从图中能够看出来,Android先创建的MyApplication,最后才创建的MainActivity。
3.Application提供的函数及其使用方法
android.app.Application类提供了很多类似onCreate()的方法,它们会在不同的场景下被Android框架回调。与此同一时候,Application类还提供了一些监控的函数,用于监视本应用中组件的生命周期。例如以下表所看到的:
方法名称 | 返回值 | 注解 |
onConfigurationChanged(Configuration newConfig) | void | 假设组件正在执行时设备配置(包含语种,方向。网络等)发生改变,则由系统调用此方法通知应用程序 |
onCreate() | void | 当应用程序正在启动时,而且在创建不论什么其它应用程序对象之前。调用此方法。
因为花费在此功能上的时间直接影响了启动一个进程中首个Activity服务或者接收器的速度,所以尽可能快地运行(比如使用缓慢的初始化状态)。假设你重写了这种方法,须要确保调用super.onCreated() |
onLowMemory() | void | 当整个系统正在低内存执行时,而且希望应用程序缩减使用内存的时候,系统调用此方法通知应用程序。
但调用此方法的准确点未定义时,通常它将在全部后台进程已经终止的时间附近发生。 系统在从此方法中返回后执行垃圾回收操作。 |
onTerminate() | void | 此方法在仿真进程环境中使用,不在生产Android设备上调用。在生产Android设备上,能够通过简单地终止进程来移除进程。进行移除工作时,则不运行不论什么用户代码(包含此回调) |
onTrimMemory() | void | 回收内存的时候调用。比如,当它进入后台而且没有足够内存保持很多后台进程执行时。 |
监控回调接口 registerComponentCallbacks unregisterComponentCallbacks |
void void |
在应用程序中注冊一个ComponentCallbacks接口。
在Activity生命周期发生改变之前,通过此接口的各个方法通知应用程序。使用这个接口。我们能够在Activity生命周期发生改变之前做一些必要的处理 |
接下来。我们通过一些实例来说明怎样使用这些方法和接口
①使用onConfigurationChanged()方法监听系统配置更新
onConfigurationChanged()方法的函数原型例如以下:
public void onConfigurationChanged(Configuration newConfig){}当中newConfig參数表示新的设备配置
onConfigurationChanged()方法是一个回调接口。在设备配置发生变化时由Android系统调用。与此同一时候,Android系统会通过參数(newConfig)传给应用程序,由应用程序处理这个变化。
注意,不同于Activity,其它组件在一个配置改变时从不又一次启动。它们孙弱自己处理改变的结果。这里所述的“配置”例如以下表所看到的:
配置项 | 注解 |
fontScale | 表示当前的系统的字体缩放比例。它是基于像素密度缩放的。 注意。在使用用户模式编译出来的系统固件中,不包括改动此项配置的界面,仅仅能通过编程的方法去改变。 数据类型:浮点型 |
hardKeyBoardHidden | 指示硬键盘是否被隐藏起来。此配置项有3个取值。详细例如以下所看到的。 0.HARDKEYBOARDHIDDEN_UNDEFINED(Android无法识别的键盘状态) 1.HARDKEYBOARDHIDDEN_NO(硬键盘可用) 2.HARDKEYBOARDHIDDEN_YES(硬键盘被隐藏) 数据类型:整型 |
keyboard | 指示加入到设备上的是哪个种类的键盘,此配置项有下面4个取值 0.KEYBOARD_UNDEFINED(Android无法识别的键盘) 1.KEYBOARD_NOKEYS(无按键键盘) 2.KEYBOARD_QWERTY(打字机键盘) 3.KEYBOARD_12KEY(12键键盘) 数据类型:整型 |
keyboardHidden | 指示当前是否有键盘可用。假设在有硬键盘的Android设备中,硬键盘被收起,而仍有软键盘。则觉得键盘是可用的。这个字段有例如以下3个取值。 0.KEYBOARDHIDDEN_UNDEFINED(Android无法识别的键盘状态) 1.KEYBOARDHIDDEN_NO(仍有软键盘可见) 2.KEYBOARDHIDDEN_YES(全部的软键盘都被隐藏)。 数据类型:整型 |
locale | 定义了设备的语言环境。
它包括了国家以及语言信息。这些信息被包括在一个java.util.Locale类型的对象中 |
mcc | IMSI的移动国家码。假设是0,表示没有定义。 注意:IMSI是指国际移动用户识别码。它存储在我们的SIM卡中,其总长度不超过15位。 数据类型:整型 |
mnc | IMSI的移动网络号,假设是0表示没有定义 数据类型:整型 |
navigation | 指示当前设备可用的导航方式,它有例如以下5个取值。 0.NAVIGATION_UNDEFINED(没有定义的导航方式) 1.NAVIGATION_NONAV(无导航) 2.NAVIGATION_DPAD(面板导航方式) 3.NAVIGATION_TRACKBALL(轨迹球导航) 4.NAVIGATION_WHEEL(滚轮方式导航) 数据类型:整型 |
navigationHidden | 用于指示导航是否可用。有例如以下取值。 0.NAVIGATIONHIDDEN_UNDEFINED 1.NAVIGATIONHIDDEN_NO 2.NAVIGATIONHIDDEN_YES 数据类型:整型 |
orientation | 指示屏幕方向的标志,有例如以下4个取值。
0.ORIENTATION_UNDEFINED(没有定义的方法) |
screenHeightDp | 屏幕可用部分的高度 |
screenLayout | 指示屏幕的总体属性,它包含两个部分。 ⒈SCREENAYOUT_SIZE_MASK:标志屏幕大小的属性(比方大屏幕,小屏幕等),它有下面5个取值。 SCREENAYOUT_SIZE_UNDEFINED:没有定义(值:0) SCREENAYOUT_SIZE_SMALL:小屏幕(值:1,屏幕分辨率至少为320*426)。 SCREENAYOUT_SIZE_NORMAL:普通屏幕(值:2,屏幕分辨率至少为320*470) SCREENAYOUT_SIZE_LARGE:大屏幕(值:3,屏幕分辨率至少为480*640) SCREENAYOUT_SIZE_XLARGE:加大屏幕(值:4,屏幕分辨率至少为720*960) ⒉SCREENAYOUT_LONG_MASK:指示屏幕是否比通常情况上更高或者更宽,它有例如以下3个取值。 SCREENAYOUT_LONG_UNDEFINED:没有定义(十六进制值为0) SCREENAYOUT_LONG_YES:是(十六进制值为20) SCREENAYOUT_LONG_NO:否(十六进制值为10) |
screenWidthDp | 屏幕可用部分的宽度 |
smallestScreenWidthDp | 在正常操作中。应用程序将会看到最小的屏幕尺寸。
这是在竖屏和横屏中screenWidthDp和ScreenHeightDp的最小值。 |
touchscreen | 设备上触摸屏的种类。它支持例如以下取值。 0.TOUCHSCREEN_UNDEFINED(没有定义模式) 1.TOUCHSCREEN_NOTOUCH(无触屏模式) 2.TOUCHSCREEN_STYLUS(手写笔模式) 3.TOUCHSCREEN_FINGER(手指触屏模式) |
uiMode | UI模式的位掩码,眼下有两个字段。 ⒈UI_MODE_TYPE_MASK:定义了设备的整个UI模式,它支持例如以下取值。 UI_MODE_TYPE_UNDEFINED:未知模式 UI_MODE_TYPE_NORMAL:通常模式 UI_MODE_TYPE_DESK:带底座模式‘ UI_MODE_TYPE_CAR:车载模式 ⒉UI_MODE_NIGHT_MASK:定义了屏幕是否在一个特殊模式中。 它支持例如以下取值。 |
以下我们通过一个实例来说明当设备配置发生变化的时候。系统怎样通过onConfigurationChanged回调接口来通知应用程序的。
㈠为前面的应用程序加入一个名叫ConfigApplication的Application的子类,并实现onCreate()方法及onConfigurationChanged()方法。
在onCreate()方法中,我们会获取应用程序在创建之初所拥有的配置信息。而在onConfigurationChanged()方法中,则能够加入一些代码以便用日志的方式来实时体现配置更新。相关代码例如以下:
public class ConfigApplication extends Application {
private static final String TAG="ConfigApplication";
private Configuration mConfiguration;
@Override
public void onCreate() {
super.onCreate();
this.mConfiguration=getResources().getConfiguration();//获取配置信息
Log.e(TAG,"onCreate::infomation:orientation="+this.mConfiguration.orientation);
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
//打印更新后的配置信息
Log.e(TAG,"onConfigurationChanged:infomation:orientation="+newConfig.orientation);
}
}
㈡按前文所述,将ConfigApplication配置到AndroidManifest.xml文件里。
㈢设备执行应用程序,就能够看到例如以下的日志信息了。
对于日志,说明例如以下:
日志信息的第一行是初始状态下的方向配置。通过上图我们知道最初的方向值是1。
而依据前面的表。可知当前是竖屏方向。
日志信息的第五行是切换横屏后。Android系统回调了我们实现的onConfigurationChanged()方法,这时系统配置已经发生了改变,因此这里的日志打印了当前的屏幕方向是2。也是就横屏。
建议:因为基类onConfigurationChanged()方法中实现了对一些回调接口的调用。所以假设我们重写了这种方法。那么为了维持原Application类的行为,建议在重写的方法入口调用super.onConfigurationChanged(newConfig)。
②使用onCreate()完毕应用程序初始化
onCreate()方法的原型为:
public void onCreate(){}
如前面的表所看到的,onCreate()方法是一个回调接口。Android系统会在应用程序启动的时候,在不论什么应用程序组件(Activity,服务,广播接收器,内容提供者)被创建之前调用这个接口。
须要注意的是,这种方法的运行效率会直接影响到启动Activity。服务。广播接收器,或者内容提供者的性能,因此该方法应尽可能快地完毕。
最后。假设实现了这个回调接口。请前晚不要忘记调用super.onCreate(),否则应用程序会报错。
前面我们实现了Appplication类的子类------Configuration,而且也已经实现了自身的onCreate()方法。这里来做个小实验。让大家更清楚这些知识。
如今,在源码的onCreate()方法中增加一个大约20秒的等待。以此来模拟在onCreate()方法中做了过于繁重的工作而导致该方法长时间无法完毕的情况,改动后的代码例如以下:
public class ConfigApplication extends Application {
private static final String TAG="ConfigApplication";
private Configuration mConfiguration;
@Override
public void onCreate() {
super.onCreate();
this.mConfiguration=getResources().getConfiguration();//获取配置信息
Log.e(TAG,"onCreate::infomation:orientation="+this.mConfiguration.orientation);
SystemClock.sleep(20000);//沉睡20秒
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
//打印更新后的配置信息
Log.e(TAG,"onConfigurationChanged:infomation:orientation="+newConfig.orientation);
}
}
此时执行程序,程序就会崩溃,当然,在真实的设备上,是能够等待的,有的并不会造成崩溃,比方经在小米上測试50秒,程序并没有崩溃,而是等待下去,直到程序正常。
当这样会造成不好的用户体验。所以在以后开发过程中。要充分考虑到这些easy出错的情况。
③使用onLowMemory()回调方法监视低内存
该方法的原型为:
public void onLowMemory(){}
当整个系统在低内存执行时,将调用该方法。
好的应用程序会实现该方法来释放不论什么缓存或者其它不须要的资源。系统从该方法返回之后,将运行一个垃圾回收操作。
④使用registerActivityLifecycleCallbacks()注冊能够监视Activity生命周期的接口
registerActivityLifecycleCallbacks()方法的原型为:
public void registerActivityLifecycleCallbacks(Application.ActivityLifecycleCallbacks callback){}
在该方法中,參数callbacks表示Activity生命周期的接口。
从Android4.0以后,Android SDK为应用程序提供了一套完整的接口以便监视与本Application相关的Activity的生命周期(创建,启动以及暂停等),它的名字叫做ActivityLifecycleCallbacks。
仅仅要在Application中通过registerActivityLifecycleCallbacks()方法将接口注冊上。它就会通过ActivityLifecycleCallbacks提供应用程序中相关的Activity生命周期信息。下表列出了这些接口以及用途。
方法原型 | 參数说明 | 用途 |
abstract void onActivityCreated(Activity activity,Bundle savedInstanceState) | activity:创建的Activity实例 savedInstanceState:创建该Activity时所带的信息(一个Bundle实例) |
在应用程序创建Activity之前调用,用于通知接口实现者Activity将要被创建。 |
abstract void onActivityDestroyed(Activity activity) | activity:销毁的Activity实例 | 在应用程序销毁Activity之前调用,用于通知接口实现者Activity将要被销毁。 |
abstract void onActivityPaused(Activity activity) | activity:暂停的Activity实例 | 在应用程序暂停Activity之前调用,用于通知接口实现者Activity将要被暂停。 |
abstract void onActivityResumed(Activity activity) | activity:恢复的Activity实例 | 在应用程序正在恢复Activity之前调用,用于通知接口实现者Activity将要被恢复。 |
abstract void onActivitySaveInstanceState(Activity activity,Bundle outState) | activity:正在运行状态保存的的Activity实例 outState:须要保存的Activity状态 |
指示当前Activity正在保存自己的状态,这些状态包括在outState中。 |
abstract void onActivityStarted(Activity activity) | activity:启动的Activity实例 | 在应用程序正在启动Activity之前调用。用于通知接口实现者Activity将要被启动。 |
abstract void onActivityStopped(Activity activity) | activity:停止的Activity实例 | 在应用程序正在停止Activity之前调用,用于通知接口实现者Activity将要被停止。 |
特别提醒:从接口定义中,我们能够知道例如以下信息。
Ⅰ这些接口都是抽象的,因此当我们实现ActivityLifecycleCallbacks接口时,就必须实现这些方法,哪怕仅仅是空实现。
Ⅱ这些接口的返回值都是void,这说明它们仅仅用于通知,别无它用。
另外我们在必要时要调用unregisterActivityLifecycleCallbacks()方法来注销掉原先注冊的接口以免造成不必要的资源浪费。
以下我们通过一个实例来说明配置发生变化的时候。系统怎样通过onConfigurationChanged()回调接口来通知应用程序,详细的过程例如以下所看到的。
㈠实现自己的Application子类(名叫ALCApplication)。
我们将在应用程序创建(onCreate()方法中)时注冊自己的Activity生命周期接口。在程序终止(onTerMinate()方法中)时注销这个接口。当完毕这些工作以后,将得到例如以下所看到的的代码:
public class ALCApplication extends Application {
private final static String TAG="ALCApplication";
private ActivityLifecycleCallbacks mActivityLifecycleCallbacks=new ActivityLifecycleCallbacks() {
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
Log.e(TAG,"onActivityCreated");
}
@Override
public void onActivityStarted(Activity activity) {
Log.e(TAG,"onActivityStarted");
}
@Override
public void onActivityResumed(Activity activity) {
Log.e(TAG,"onActivityResumed");
}
@Override
public void onActivityPaused(Activity activity) {
Log.e(TAG,"onActivityPaused");
}
@Override
public void onActivityStopped(Activity activity) {
Log.e(TAG,"onActivityStopped");
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
Log.e(TAG,"onActivitySaveInstanceState");
}
@Override
public void onActivityDestroyed(Activity activity) {
Log.e(TAG,"onActivityDestroyed");
}
};
@Override
public void onCreate() {
super.onCreate();
registerActivityLifecycleCallbacks(this.mActivityLifecycleCallbacks);
}
@Override
public void onTerminate() {
super.onTerminate();
unregisterActivityLifecycleCallbacks(this.mActivityLifecycleCallbacks);
}
}
㈡将ALCApplication配置到AndroidManifest.xml中。当配置完毕时。最后的结果看起来与下图类似:
这里我们通过接口监视Activity从启动到推出的生命周期。
在这个实例中,我们在onTerminate()方法中做了注销接口的工作。但值得注意的是。onTerminate()方法仅仅会在虚拟机进程中被调用,永远不会在真实的Android设备中被调用。
⑤使用registerComponentCallbacks()注冊一个能够用来舰艇Activity生命周期的接口
该方法原型为:
public void registerComponentCallbacks(ComponentCallbacks callback){}
当中參数callback是ComponentCallbacks 接口的一个实现。当Activity的生命周期发生变化时。会通过这个接口通知应用程序。对于全部应用程序来。它是通用的回调API集合的接口。ComponentCallbacks中仅仅包含两个方法,它们各自是public abstract void onConfigurationChanged(Configuration
newConfig)和public abstract void onLowMemory()。
这两个方法的调用与Application中的同名回调方法的调用条件一样的。
ComponentCallbacks()和registerComponentCallbacks()方法的使用方法与ActivityLifecycleCallbacks()和registerActivityLifecycleCallbacks()的使用方法是一样的,这里就不单举例说明了。
Android清单文件具体解释(三)----应用程序的根节点<application>的更多相关文章
- Android清单文件详解(三)----应用程序的根节点<application>
<application>节点是AndroidManifest.xml文件中必须持有的一个节点,它包含在<manifest>节点下.通过<application>节 ...
- Android清单文件具体解释(二) ---- 应用程序权限声明
我们知道,Android系统的各个模块提供了很强大的功能(比方电话,电源和设置等),通过使用这些功能.应用程序能够表现的更强大.更灵活.只是,使用这些功能并非无条件的.而是须要拥有一些权限.接下来,我 ...
- Android清单文件具体解释(四) ---- backupAgent的使用方法
在<application>节点中有一个很重要的属性,那就是backupAgent.这里我们将它单独列出来,从基本含义,使用方法及其相关属性等方面来具体介绍一下. 1.backupAgen ...
- Android清单文件具体解释(六) ---- <activity>节点的属性
1.android:allowTaskReparenting android:allowTaskReparenting是一个任务调整属性,它表明当这个任务又一次被送到前台时,该应用程序所定义的Acti ...
- [android]清单文件中MAIN与LAUNCHER的区别
原文:[android]清单文件中MAIN与LAUNCHER的区别 MAIN 和 LAUNCHER,之前一直不注意这两个有区别,写程序的时候都放到一个filter中,前两天面试问到了,总结一下: MA ...
- Android清单文件合并的那些事
APK文件只能包含一个AndroidManifest.xml文件,但Android Studio项目可以包含多个文件(通过buildSrc.导入的库引入).因此,在构建应用时,Gradle构建会将所有 ...
- Android清单文件AndroidMenifest.xml
1.AndroidMenifes.xml清单文主要结构件结构 所谓主要结构就是每一个清单文件中都必不可少的结构主要是下面三层 第一层.menifest 第二层.application,use-sdk ...
- Android WebView 开发具体解释(三)
转载请注明出处 http://blog.csdn.net/typename/article/details/40302351 powered by miechal zhao 概览 Android ...
- (备忘)android清单文件中<meta-data>标签,以及<intent-filter>下的<data>标签及其他标签
1.metadata可以写在application下也可以写在activity下,作为全局或activity内共享的数据 以键值对形式保存 <meta-data android:name=&qu ...
随机推荐
- Linux学习之Makefile文件的编写
转自:http://goodcandle.cnblogs.com/archive/2006/03/30/278702.html 目的: 基本掌握了 make 的用法,能在Linux系统上编 ...
- Java学习之利用集合发牌小练习
/* * 思路: * A:创建一个HashMap集合 * B:创建一个ArrayList集合 * C:创建花色数组和点数数组 * D:从0开始往HashMap里面存储编号,并存储对应的牌同时往Arra ...
- Java中的流程控制(一)
程序的流程控制(一) 关于Java程序的流程控制(一) 从结构化程序设计角度出发,程序有三种结构: 顺序结构 选择结构 循环结构 1.顺序结构 就是程序从上到下一行行执行,中间没有判断和跳转. 2.i ...
- hdu 4735Little Wish~ lyrical step~ 重复覆盖
题目链接 给出一棵树, 树上点的值为0或1, 可以交换树上两个点的权值, 给出一个距离m, 所有的0距离最近的1的距离不能超过m, 求最少的交换次数. 首先对于每一个点u,所有离u的距离不超过m的点v ...
- ny 58 最少步数 (BFS)
题目:http://acm.nyist.net/JudgeOnline/problem.php?pid=58 就是一道简单的BFS 练习练习搜索,一次AC #include <iostream& ...
- JavaScript 鸭子模型
Javascript:由 “鸭子类型” 得出来的推论 背景 学动态语言的都知道一句话:“如果它走起来像鸭子,而且叫起来像鸭子,那么它就是鸭子”,Javascript也支持鸭子类型,下文就说说鸭子类型在 ...
- css兼容问题与实践归纳总结
css兼容问题与实践归纳总结 一.IE6/7 原生块元素与display:inline-block; <div style="display:inline-block;"&g ...
- Linux中环境变量到底写在哪个文件中?解析login shell 和 no-login shell
login shell:取得bash 时需要完整的登入流程,就称为login shell.举例来说,同tty1~tty6登入时, 需要输入用户名和密码,此时取得的bash就称为login shell ...
- linux下emacs安装
1.下载地址:http://ftp.gnu.org/pub/gnu/emacs/ 下载文件:emacs-24.2.tar.gz 步骤: 一.安装依赖文件: (先进入root:终端中输入 su -) ...
- 最近adt升级引起的问题
其实也不知道是什么原因引起的,因为 之前安装的adt就是23.0.3的版本,但是最近突然创建安卓工程时出现了如下问题 D:\workspace\appcompat_v7\res\values-v21\ ...