Application类是什么
动时系统会创建一个application对象,用来存储系统的一些信息。通常我们是不需要指定一个Application的,这时系统会自动帮我们创建。打开每一个应用程序的manifest文件,可以看到activity都是包含在application标签之中,如下:Application和Activity,Service一样是android框架的一个系统组件,当android程序启
<span style="font-size:18px;"><span style="font-size:18px;"><span style="background-color: rgb(255, 102, 102);"> <application</span> android:icon="@drawable/ic_launcher" android:label="@string/app_name" > <activity android:name=".BarCodeTestActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:configChanges="orientation|keyboardHidden" android:name="com.jalon.activity.CaptureActivity" android:screenOrientation="portrait" android:theme="@android:style/Theme.NoTitleBar.Fullscreen" android:windowSoftInputMode="stateAlwaysHidden" > </activity> <span style="background-color: rgb(255, 102, 102);"> </application></span></span></span>
android系统会为每个程序运行时创建一个Application类的对象且仅创建一个,所以Application是单例 (singleton)模式的一个类.且application对象的生命周期是整个程序中最长的,它的生命周期就等于这个程序的生命周期。因为它是全局的单例的,所以在不同的Activity,Service中获得的对象都是同一个对象。
Application的作用
因为Application它是全局的单例的,它的生命周期就等于这个程序的生命周期,因此在安卓中我们可以避免使用静态变量来存储长久保存的值,而用Application。可以通过Application来进行一些,如:数据传递、数据共享和数据缓存等操作。系统在启动Application时,系统会创建一个PID,即进程ID,所有的Activity都会在此进程上运行。那么我们在Application创建的时候初始化全局变量,同一个应用的所有Activity都可以取到这些全局变量的值,换句话说,我们在某一个Activity中改变了这些全局变量的值,那么在同一个应用的其他Activity中值就会改变。
Application的使用
通常我们是不需要指定一个Application的,系统会自动帮我们创建,如果需要创建自己的Application,那也很简单!创建一个类继承Application并在AndroidManifest.xml文件中的application标签中进行注册(只需要给application标签增加name属性,并添加自己的 Application的名字即可)。
在默认情况下应用系统会自动生成Application对象,但是如果我们自定义了Application,那就需要告知系统,实例化的时候,是实例化我们自定义的,而非默认的。比如我们自定义了一个AppContext类:
<span style="font-size:18px;">public class AppContext extends Application {
public static final int NETTYPE_WIFI = 0x01;
public static final int NETTYPE_CMWAP = 0x02;
public static final int NETTYPE_CMNET = 0x03;
public static final int PAGE_SIZE = 20;//默认分页大小
private static final int CACHE_TIME = 10*60000;//缓存失效时间
.
.
.
.
}</span>
为了让系统实例化的时候找到,我们必须在manifest中修改application标签属性:
<span style="font-size:18px;"><application
android:name=".AppContext"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" ></span>
关键的是这句:android:name=".AppContext"
通常Application全局对象是通过Context或者Activity的getApplicationContext()方法获得的比如我们在应用程序中想要获得我们刚刚定义的AppContext对象,就需要在activity中这样做:
appContext = (AppContext)this.getApplicationContext();
如果有Context对象,还可以:appContext = (AppContext)mContext.getApplicationContext();
appContext = (AppContext)this.getApplicationContext();
如果有Context对象,还可以:appContext = (AppContext)mContext.getApplicationContext();
但是很多时候我们的代码可能在activity之外,且没有context对象的引用,但是又需要获得AppContext对象,原始的做法可能是想办法将activity或者context传递到需要调用的地方,但是这样代码耦合度太高,可读性差。我们有更优雅的做法。
我们谈到Application对象是全局的,单例的,既然是单例应该有一个类方法能让我们获得这个单例对象才是,但Application本身没有,我们只能在自定义的时候想办法。
我们谈到Application对象是全局的,单例的,既然是单例应该有一个类方法能让我们获得这个单例对象才是,但Application本身没有,我们只能在自定义的时候想办法。
Application是系统的一个组件,也就有自己的生命周期函数,让人感到意外的是他的生命周期函数中居然也有onCreate(),onCreate是被自动调用的,我们可以利用这点来获得这个Application对象。
在AppContext中加入如下几行代码:
Context的getExternalFilesDir()方法。但是这个工具类没有直接的办法获取到context,于是我们可以:
在AppContext中加入如下几行代码:
<span style="font-size:18px;">private static AppContext instance;
public static AppContext getInstance() {
return instance;
}
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
instance = this;
}</span>
这样我们就能在app工程的任何地方通过AppContext.getInstance()来获得Application全局对象。比如我定义了一个工具类,在工具内中我们需要使用Context的getExternalFilesDir()方法。但是这个工具类没有直接的办法获取到context,于是我们可以:
<span style="font-size:18px;">return AppContext.getInstance().getExternalFilesDir(null);</span>
应用举例
1、继承Application
<span style="font-size:18px;">package com.jalon.customapplication;
import android.app.Application;
public class CustomApplication extends Application
{
private static final String VALUE = "Hello,Jalon!";
private String value;
private static CustomApplication instance;
@Override
public void onCreate()
{
super.onCreate();
instance=this;
setValue(VALUE); // 初始化全局变量
}
public void setValue(String value)
{
this.value = value;
}
public String getValue()
{
return value;
}
public static CustomApplication getInstance() {
return instance;
}
}
</span>
注:继承Application类,主要重写里面的onCreate()方法(android.app.Application包的onCreate()才是真正的Android程序的入口点),就是创建的时候,初始化变量的值。然后在整个应用中的各个文件中就可以对该变量进行操作了。
2、配置自定义的Application
在ApplicationManifest.xml文件中配置自定义的Application。
<span style="font-size:18px;"> <application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme"
android:name="<span style="background-color: rgb(255, 102, 102);">CustomApplication</span>"
></span>
实例化代码:
<span style="font-size:18px;">package com.jalon.customapplication;
import android.app.Application;
public class CustomApplication extends Application
{
private static final String VALUE = "Hello,Jalon!";
private String value;
private static CustomApplication instance;
@Override
public void onCreate()
{
super.onCreate();
instance=this;
setValue(VALUE); // 初始化全局变量
}
public void setValue(String value)
{
this.value = value;
}
public String getValue()
{
return value;
}
public static CustomApplication getInstance() {
return instance;
}
}
</span>
<span style="font-size:18px;">package com.jalon.customapplication;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.util.Log;
import android.view.Menu;
//first FirstActivity
public class MainActivity extends Activity {
private CustomApplication app;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
app = (CustomApplication) getApplication(); // 获得CustomApplication对象
Log.i("jalon", "初始值=====" + app.getValue()); // 获取进程中的全局变量值,看是否是初始化值
app.setValue("Hi,Jalon!"); // 重新设置值
Log.i("jalon", "修改后=====" + app.getValue()); // 再次获取进程中的全局变量值,看是否被修改
Intent intent = new Intent();
intent.setClass(this, SecondActivity.class);
startActivity(intent);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
</span>
<span style="font-size:18px;">package com.jalon.customapplication;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
public class SecondActivity extends Activity
{
private CustomApplication app;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
app = (CustomApplication) getApplication(); // 获取应用程序
Log.i("jalon", "当前值=====" + app.getValue()); // 获取全局值
}
}</span>
注:只需要调用Context的 getApplicationContext或者Activity的getApplication方法来获得一个Application对象,然后再得到相应的成员变量即可。它是代表我们的应用程序的类,使用它可以获得当前应用的主题和资源文件中的内容等,这个类更灵活的一个特性就是可以被我们继承,来添加我们自己的全局属性。
AndroidManifest.xml
<span style="font-size:18px;"><?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.jalon.customapplication"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="18" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme"
android:name="CustomApplication"
>
<activity
android:name="com.jalon.customapplication.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".SecondActivity"
android:label="@string/app_name">
</activity>
</application>
</manifest>
</span>
I/jalon ( 2411): 初始值=====Hello,Jalon!
I/jalon ( 2411): 修改后=====Hi,Jalon!
I/jalon ( 2411): 当前值=====Hi,Jalon!