Android清单文件详解(三)----应用程序的根节点<application>

网友投稿 625 2022-05-28

节点是AndroidManifest.xml文件中必须持有的一个节点,它包含在节点下。通过节点的相关属性,我们可以声明Android应用程序的相关特性。这个节点包含所有应用程序组件的节点,包括Activity,服务,广播接收器和内容提供者,并且包含了一些可能影响所有组件的属性。这些属性中的其中一些又会作为默认值而被设置到应用程序组件的相同属性上,比如icon,label,permission,process,taskAffinity和allowTaskReparenting等,而其他的一些值则作为应用程序的整体被设置,并且不能被应用程序组件的属性覆盖,比如debuggable,enabled,description和allowClearUserData等。

1.节点配置

Android清单文件详解(三)----应用程序的根节点<application>

一般来说,在生成Android应用程序的时候,默认的AndroidManifest.xml文件中就已经包含了一些默认的节点,其中包含应用程序的基本属性。现在我们就来看看节点信息的全集,代码如下:

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">

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中内android:name中

从图中可以看出来,Android先创建的MyApplication,最后才创建的MainActivity。

3.Application提供的函数及其用法

android.app.Application类提供了许多类似onCreate()的方法,它们会在不同的场景下被Android框架回调。与此同时,Application类还提供了一些监控的函数,用于监视本应用中组件的生命周期。如下表所示:

接下来,我们通过一些实例来说明如何使用这些方法和接口

①使用onConfigurationChanged()方法监听系统配置更新

onConfigurationChanged()方法的函数原型如下:

public void onConfigurationChanged(Configuration newConfig){}其中newConfig参数表示新的设备配置

onConfigurationChanged()方法是一个回调接口,在设备配置发生变化时由Android系统调用。与此同时,Android系统会通过参数(newConfig)传给应用程序,由应用程序处理这个变化。注意,不同于Activity,其他组件在一个配置改变时从不重新启动,它们孙弱自己处理改变的结果。这里所述的“配置”如下表所示:

下面我们通过一个实例来说明当设备配置发生变化的时候,系统如何通过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秒,程序并没有崩溃,而是等待下去,直到程序正常。当这样会造成不好的用户体验。所以在以后开发过程中,要充分考虑到这些容易出错的情况。

③使用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生命周期信息。下表列出了这些接口以及用途。

特别提醒:从接口定义中,我们可以知道如下信息。

Ⅰ这些接口都是抽象的,因此当我们实现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

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:华为全联接2021:华为云发布一系列重磅AI服务,让创新触手可及
下一篇:Linux基础IO
相关文章