Context——Context详解(6)

本文深入探讨了Android中的Context概念,解析了其在Application、Activity及Service中的实现方式,并讨论了它们之间的区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://www.cnblogs.com/android100/p/Android-Context.html



Context是一个抽象基类,我们通过它访问当前包的资源(getResources、getAssets)和启动其他组件(Activity、Service、Broadcast)以及得到各种服务(getSystemService),当然,通过Context能得到的不仅仅只有上述这些内容。对Context的理解可以来说:Context提供了一个应用的运行环境,在Context的大环境里,应用才可以访问资源,才能完成和其他组件、服务的交互,Context定义了一套基本的功能接口,我们可以理解为一套规范,而Activity和Service是实现这套规范的子类,这么说也许并不准确,因为这套规范实际是被ContextImpl类统一实现的,Activity和Service只是继承并有选择性地重写了某些规范的实现。

Application、Activity和Service作为Context的区别

首先,它们都间接继承了Context,这是它们的相同点。

不同点,可以从几个方面来说:首先看它们的继承关系

Activity的继承关系

通过对比可以清晰地发现,Service和Application的类继承关系比较像,而Activity还多了一层继承ContextThemeWrapper,这是因为Activity有主题的概念,而Service是没有界面的服务,Application更是一个抽象的东西,它也是通过Activity类呈现的。

Activity对象中ContextImpl的创建

代码为ActivityThread中的performLaunchActivity方法

if (activity != null) {  
    Context appContext = createBaseContextForActivity(r, activity);  
    /** 
     *  createBaseContextForActivity中创建ContextImpl的代码 
     *  ContextImpl appContext = new ContextImpl(); 
     *  appContext.init(r.packageInfo, r.token, this); 
     *  appContext.setOuterContext(activity); 
     */  
    CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());  
    Configuration config = new Configuration(mCompatConfiguration);  
    if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "  
            + r.activityInfo.name + " with config " + config);  
    activity.attach(appContext, this, getInstrumentation(), r.token,  
            r.ident, app, r.intent, r.activityInfo, title, r.parent,  
            r.embeddedID, r.lastNonConfigurationInstances, config);  
  
    if (customIntent != null) {  
        activity.mIntent = customIntent;  
    }  
    ...  
} 

可以看出,Activity在创建的时候会new一个ContextImpl对象并在attach方法中关联它,需要注意的是,创建Activity使用的数据结构是ActivityClientRecord。

Application对象中ContextImpl的创建

代码在ActivityThread中的handleBindApplication方法中,此方法内部调用了makeApplication方法

public Application makeApplication(boolean forceDefaultAppClass,  
        Instrumentation instrumentation) {  
    if (mApplication != null) {  
        return mApplication;  
    }  
  
    Application app = null;  
  
    String appClass = mApplicationInfo.className;  
    if (forceDefaultAppClass || (appClass == null)) {  
        appClass = "android.app.Application";  
    }  
  
    try {  
        java.lang.ClassLoader cl = getClassLoader();  
        ContextImpl appContext = new ContextImpl();  
        appContext.init(this, null, mActivityThread);  
        app = mActivityThread.mInstrumentation.newApplication(  
                cl, appClass, appContext);  
        appContext.setOuterContext(app);  
    } catch (Exception e) {  
        if (!mActivityThread.mInstrumentation.onException(app, e)) {  
            throw new RuntimeException(  
                "Unable to instantiate application " + appClass  
                + ": " + e.toString(), e);  
        }  
    }  
    ...  
} 

看代码发现和Activity中ContextImpl的创建是相同的。

 

Service对象中ContextImpl的创建

通过查看代码发现和Activity、Application是一致的。分析到这里,那么三者的Context有什么区别呢?没有区别吗?尽管如此,有一些细节是确定的:Dialog的使用需要Activity,在桌面上我们采用Application的Context无法弹出对话框,同时在桌面上想启动新的activity,我们需要为intent设置FLAG_ACTIVITY_NEW_TASK标志,否则无法启动activity,这一切都说明,起码Application的Context和Activity的Context还是有区别的,当然这也可能不是Context的区别,因为在桌面上,我们的应用没有界面,这意味着我们能干的事情可能受到了限制,事情的细节目前我还没有搞的很清楚。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值