android application context 小结

      android学了快一年了,也写了一些代码,但是经常使用的application和context只是会简单的时候,有时候遇到问题也不知道为什么,最近上网查看了各种博客,对application和context有了一点了解,整理了一些资料,供大家探讨学习。

一、application

      1、application是什么

      Application是android系统的一个系统组件,当android程序启动的时候,系统会创建一个application对象。通常我们不需要自己去配置application,系统会自动帮我们创建一个默认的application,如果想自定义一个application,就需要继承application,并在manifest中的application中进行注册即可。

       Android系统只会为每一个应用程序创建一个application,所以application是单例的,且在整个应用中生命周期最长,等于这个程序的生命周期。通常application可以用来传递数据(activity之间跳转),数据缓存等操作。

       2、application如何自定义

       (1)自定义MyApplication类,继承于Application

import android.app.Application;

import java.util.HashMap;

public class MyApplication extends Application{

    private HashMap<String, Object> datas;

    @Override
    public void onCreate() {
        super.onCreate();
        datas = new HashMap<String, Object>();
    }

    public Object getData(String key){
        return datas.get(key);
    }

    public void putData(String key, Object data){
        datas.put(key, data);
    }
    
}

        说明:继承于Application类,主要重写里面的onCreate()方法,其实这次才是整个app程序的入口函数(部分人认为是activity的onCreat函数),在创建的时候,初始化变量的值,之后,整个app就可以存取数据了。该函数不能做需要大量时间才能完成的任务,不然会影响app的启动时间。

      (2)MainActivity

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    public void toOtherActivity(View v){
        MyApplication myApplication = (MyApplication)getApplication();
        myApplication.putData("name", "paulzeng");
        startActivity(new Intent(this, OtherActivity.class));
    }
}

       说明:该界面只有一个button,onClick属性为toOtherActivity

(3)OtherActivity       

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class OtherActivity extends Activity{
    private TextView nameTextView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_other);
        nameTextView = (TextView)findViewById(R.id.name);

        MyApplication myApplication = (MyApplication)getApplication();
        String name = (String)myApplication.getData("name");
        nameTextView.setText(name);
    }
}

        (4)配置MyApplication

<application
        android:name=".MyApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".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=".OtherActivity">
         </activity>
</application>

         (5)搞起来

                  

        3、小结

        这个案例演示使用application实现activity之间的数据共享,也可以用来实现数据传递,在MyApplication中再添加一个removeData的函数,在第二个界面获取数据之后,就可以把数据删除掉。当然还可以用自定义的application保存当前打开的activity,就可以实现在一个activity中,调用另一个activity的finish方法,关闭其它的界面。

二、context

        1、context是什么

        Context是一个系统抽象类,我们通过他访问应用程序的资源和启动各种组件(activity,service)以及获取系统服务。context被翻译成上下文,从名字可以看出它提供了一个运用可运行的环境,包括资源访问,组件和各服务的交互。Context定义了一套基本的功能接口,可以理解为一套规范,而activity和service是实现了这套规范的子类。

        2、Context相关类的继承关系         

        说明:从这个继承关系图中可以看出,主要是ContextIml和ContextWrapper实现了Context接口,而ContextWrapper里面有一个ContextIml的实例,通过后面源代码的展示我们可以看出ContextWrapper只是提供了获取资源的方法,具体操作是调用ContextIml的方法。在我们常用的activity,service和application都属于Context的子类,这也就能说明为什么activity中调用一些函数时,要求传递Context,只需要传递this就搞定了。

      (1)ContextWrapper部分源代码

public class ContextWrapper extends Context {
    Context mBase;

    public ContextWrapper(Context base) {
        mBase = base;
    }

    protected void attachBaseContext(Context base) {
        if (mBase != null) {
            throw new IllegalStateException("Base context already set");
        }
        mBase = base;
    }

    public Context getBaseContext() {
        return mBase;
    }

    @Override
    public AssetManager getAssets() {
        return mBase.getAssets();
    }

    @Override
    public Resources getResources()
    {
        return mBase.getResources();
    }

    @Override
    public PackageManager getPackageManager() {
        return mBase.getPackageManager();
    }

    @Override
    public ContentResolver getContentResolver() {
        return mBase.getContentResolver();
    }
}

        说明:从代码中可以看出,ContextWrapper只是覆写了Context的方法,每个方法里面调用实现了Context的ContextImpl的方法。

        3、不同Context具有不同的能力

        说明:NO1 表示Application context的确可以开始一个Activity,但是它需要创建一个新的task。这可能会满足一些特定的需求,但是在你的应用中会创建一个不标准的回退栈(back stack),这通常是不推荐的或者不是是好的实践。NO2 表示这是非法的,但是这个填充(inflation)的确可以完成,但是是使用所运行的系统默认的主题(theme),而不是你app定义的主题。NO3 在Android4.2以上,如果Receiver是null的话(这是用来获取一个sticky broadcast的当前 值的),这是允许的。

        从这张图可以看出,虽然application,activity,Service都是Context的子类,但是他们都有一定的局限性,在使用的时候,并不是等价的,在使用的时候需要注意自己使用的场景。比如:我们在show a dialog,我们需要传递一个context,如果使用getApplicationContext()会造成crash,而使用activity就能解决这个问题,因为dialog属于activity,而application并没有承载界面。


参考文档:

http://www.cnblogs.com/renqingping/archive/2012/10/24/Application.html

http://www.360doc.com/content/13/0620/15/110467_294299969.shtml

http://blog.csdn.net/qinjuning/article/details/7310620

http://blog.csdn.net/race604/article/details/9331807


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值