android中Context深入详解

以下分别通过Context认知角度,继承关系,对象创建等方面android中Context做了深入的解释,一起学习下。

1、Context认知。

Context译为场景,一个应用程序可以认为是一个工作环境,在这个工作环境中可以存在许多场景,coding代码的场景 ,打电话的场景,开会的场景。这些场景可以类比不同的Activity,service。

2、从两个角度认识Context。

第一:Activity继承自Context,同时Activity还实现了其他的interface,我们可以这样看,activity在语法上extends了Context,其本质上是一个Context,但同时其实现了许多interface,扩充了Context的功能,扩充之后的类成为Activity或者Service。

第二:Context本质上包含了场景的所有元素,故而设定其为abstract,Activity和Service继承自Context,它们本质上可以认为就是Context。

3、Context继承关系图

4、Application对象的ContextImpl对象创建过程。

step 1、Ams通过远程Binder调用ActivityThread的内部类ApplicationThread的bingApplication方法,参数包括ApplicationInfo,这个对象由Ams创建,通过IPC传递到ActivityThread的内部类ApplicationThread中。

public final void bindApplication(String processName,
        ApplicationInfo appInfo, List<ProviderInfo> providers,
        ComponentName instrumentationName, String profileFile,
        ParcelFileDescriptor profileFd, boolean autoStopProfiler,
        Bundle instrumentationArgs, IInstrumentationWatcher instrumentationWatcher,
        int debugMode, boolean isRestrictedBackupMode, boolean persistent,
        Configuration config, CompatibilityInfo compatInfo,
        Map<String, IBinder> services, Bundle coreSettings) { 

      if (services != null) {
        // Setup the service cache in the ServiceManager
        ServiceManager.initServiceCache(services);
      } 

      setCoreSettings(coreSettings); 

      AppBindData data = new AppBindData();
      data.processName = processName;
      data.appInfo = appInfo;
      data.providers = providers;
      data.instrumentationName = instrumentationName;
      data.instrumentationArgs = instrumentationArgs;
      data.instrumentationWatcher = instrumentationWatcher;
      data.debugMode = debugMode;
      data.restrictedBackupMode = isRestrictedBackupMode;
      data.persistent = persistent;
      data.config = config;
      data.compatInfo = compatInfo;
      data.initProfileFile = profileFile;
      data.initProfileFd = profileFd;
      data.initAutoStopProfiler = false;
      queueOrSendMessage(H.BIND_APPLICATION, data);
    } 

step 2、构建AppBindData对象,如上代码所示。

step 3、调用H Handler,执行handleBindApplication()方法。

static final class AppBindData {
    LoadedApk info;
    String processName;
    ApplicationInfo appInfo;
    List<ProviderInfo> providers;
    ComponentName instrumentationName;
    Bundle instrumentationArgs;
    IInstrumentationWatcher instrumentationWatcher;
    int debugMode;
    boolean restrictedBackupMode;
    boolean persistent;
    Configuration config;
    CompatibilityInfo compatInfo; 

    /** Initial values for {@link Profiler}. */
    String initProfileFile;
    ParcelFileDescriptor initProfileFd;
    boolean initAutoStopProfiler; 

    public String toString() {
      return "AppBindData{appInfo=" + appInfo + "}";
    }
  } 

  private void handleBindApplication(AppBindData data) {
    mBoundApplication = data;
    mConfiguration = new Configuration(data.config);
    mCompatConfiguration = new Configuration(data.config); 

    //..........
    TimeZone.setDefault(null); 

    /*
     * Initialize the default locale in this process for the reasons we set the time zone.
     */
    Locale.setDefault(data.config.locale); 

    data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);//data.info对象为LoadApk,此时data.info为null,使用getPackageINfoNoCheck创建此对象。 

    if (data.instrumentationName != null) {//该条件尽在Android Unit Test工程时会执行到,此处直接看else语句
      ContextImpl appContext = new ContextImpl();
      appContext.init(data.info, null, this);
      InstrumentationInfo ii = null;
      try {
        ii = appContext.getPackageManager().
          getInstrumentationInfo(data.instrumentationName, 0);
      } catch (PackageManager.NameNotFoundException e) {
      }
      if (ii == null) {
        throw new RuntimeException(
          "Unable to find instrumentation info for: "
          + data.instrumentationName);
      } 

      mInstrumentationAppDir = ii.sourceDir;
      mInstrumentationAppPackage = ii.packageName;
      mInstrumentedAppDir = data.info.getAppDir(); 

      ApplicationInfo instrApp = new ApplicationInfo();
      instrApp.packageName = ii.packageName;
      instrApp.sourceDir = ii.sourceDir;
      instrApp.publicSourceDir = ii.publicSourceDir;
      instrApp.dataDir = ii.dataDir;
      instrApp.nativeLibraryDir = ii.nativeLibraryDir;
      LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
          appContext.getClassLoader(), false, true);
      ContextImpl instrContext = new ContextImpl();
      instrContext.init(pi, null, this); 

      try {
        java.lang.ClassLoader cl = instrContext.getClassLoader();
        mInstrumentation = (Instrumentation)
          cl.loadClass(data.instrumentationName.getClassName()).newInstance();
      } catch (Exception e) {
        throw new RuntimeException(
          "Unable to instantiate instrumentation "
          + data.instrumentationName + ": " + e.toString(), e);
      } 

      mInstrumentation.init(this, instrContext, appContext,
          new ComponentName(ii.packageName, ii.name), data.instrumentationWatcher); 

      if (mProfiler.profileFile != null && !ii.handleProfiling
          && mProfiler.profileFd == null) {
        mProfiler.handlingProfiling = true;
        File file = new File(mProfiler.profileFile);
        file.getParentFile().mkdirs();
        Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
      } 

      try {
        mInstrumentation.onCreate(data.instrumentationArgs);
      }
      catch (Exception e) {
        throw new RuntimeException(
          "Exception thrown in onCreate() of "
          + data.instrumentationName + ": " + e.toString(), e);
      } 

    } else {
      mInstrumentation = new Instrumentation();//初始化Instrumentation对象,一个应用程序对应一个Instrumentation对象
    } 

    Application app = data.info.makeApplication(data.restrictedBackupMode, null);
    mInitialApplication = app; 

    try {
      mInstrumentation.callApplicationOnCreate(app);//调用Application程序都应的onCreate方法。
    } catch (Exception e) {
      if (!mInstrumentation.onException(app, e)) {
        throw new RuntimeException(
          "Unable to create application " + app.getClass().getName()
          + ": " + e.toString(), e);
      }
    }
  }

第三步可以又可以分为三小步。

step 3.1、给AppBindData的info变量赋值。

data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);//data.info对象为LoadApk,此时data.info为null,使用getPackageINfoNoCheck创建此对象。

step 3.2、初始化Instrumentation对象。

mInstrumentation = new Instrumentation();//初始化Instrumentation对象,一个应用程序对应一个Instrumentation对象 

step 3.3、创建Application对象。

Application app = data.info.makeApplication(data.restrictedBackupMode, null);

我们着重看一下step 3.1和step3.3.

step 3.1:mPackages和mResourcePackages集合,以packageName为key值,我们知道一个应用程序中的packageName是相同的,也就是说,此处一旦创建,其他地方再次调用此函数,就不需要创建了。总结:也就是说一个应用程序中的LoadedApk对象是唯一的。此处的LoadedApk,也被称为packageInfo。

public final LoadedApk getPackageInfoNoCheck(ApplicationInfo ai,
      CompatibilityInfo compatInfo) {
    return getPackageInfo(ai, compatInfo, null, false, true);
  }
  private LoadedApk getPackageInfo(ApplicationInfo aInfo, CompatibilityInfo compatInfo,
      ClassLoader baseLoader, boolean securityViolation, boolean includeCode) {/*includeCode 默认为true*/
    synchronized (mPackages) {
      WeakReference<LoadedApk> ref;
      if (includeCode) {//1、首先从mPackages或者mResourcePackages 集合中以packageName为Key值,获取LoadApk对象。
        ref = mPackages.get(aInfo.packageName);
      } else {
        ref = mResourcePackages.get(aInfo.packageName);
      }
      LoadedApk packageInfo = ref != null ? ref.get() : null;
      if (packageInfo == null || (packageInfo.mResources != null
          && !packageInfo.mResources.getAssets().isUpToDate())) {
        if (localLOGV) Slog.v(TAG, (includeCode ? "Loading code package "
            : "Loading resource-only package ") + aInfo.packageName
            + " (in " + (mBoundApplication != null
                ? mBoundApplication.processName : null)
            + ")");
        packageInfo =
          new LoadedApk(this, aInfo, compatInfo, this, baseLoader,
              securityViolation, includeCode &&
              (aInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0);//2、如果packageInfo对象为null,则new初始化此对象
        if (includeCode) {//3、最后将创建的此packageInfo对象,加入到mPackages或者mResourcePackages集合中。
          mPackages.put(aInfo.packageName,
              new WeakReference<LoadedApk>(packageInfo));
        } else {
          mResourcePackages.put(aInfo.packageName,
              new WeakReference<LoadedApk>(packageInfo));
        }
      }
      return packageInfo;
    }
  }

step 3.3、总结:每个应用程序都存在一个Application,用户可以在AndroidManifest中重写它,如果不重写也存在一个默认的Application对象。

framework/base/core/java/android/app/LoadedApk.java

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";//1、每个工程都存在一个Application对象,默认的Application对象为android.app.Application,客户端可以重写
  } 

  try {
    java.lang.ClassLoader cl = getClassLoader();
    ContextImpl appContext = new ContextImpl();//2、创建ContextImpl对象,这才是Context的实际实现类
    appContext.init(this, null, mActivityThread);//3、执行ContextImpl对象的init方法,initResource等对象
    app = mActivityThread.mInstrumentation.newApplication(//4、以appContext为参数得到Application对象。
        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);
    }
  }
  mActivityThread.mAllApplications.add(app);//5、将创建的Application对象,加入到A来了Application中。
  mApplication = app; 

  if (instrumentation != null) {//6、此时的instrumentation为null。
    try {
      instrumentation.callApplicationOnCreate(app);
    } catch (Exception e) {
      if (!instrumentation.onException(app, e)) {
        throw new RuntimeException(
          "Unable to create application " + app.getClass().getName()
          + ": " + e.toString(), e);
      }
    }
  } 

  return app;
}

5、Activity中Context的创建过程

step 1、Ams通过远程Binder调用ActivityThread的Application的scheduleLaunchActivity方法,参数包括ActivityInfo,这个对象由Ams创建,通过IPC传递到ActivityThread的内部类ApplicationThread中。

public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
        ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
        Bundle state, List<ResultInfo> pendingResults,
        List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
        String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
      ActivityClientRecord r = new ActivityClientRecord(); 

      r.token = token;
      r.ident = ident;
      r.intent = intent;
      r.activityInfo = info;
      r.compatInfo = compatInfo;
      r.state = state; 

      r.pendingResults = pendingResults;
      r.pendingIntents = pendingNewIntents; 

      r.startsNotResumed = notResumed;
      r.isForward = isForward; 

      r.profileFile = profileName;
      r.profileFd = profileFd;
      r.autoStopProfiler = autoStopProfiler; 

      updatePendingConfiguration(curConfig); 

      queueOrSendMessage(H.LAUNCH_ACTIVITY, r);
    }

step 2、构建ActivityClientRecord对象,如上代码所示。

step 3、调用H Handler,执行handleLaunchActivity()方法。

其中step 3,又可分为10小步。

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")"); 

    ActivityInfo aInfo = r.activityInfo;
    if (r.packageInfo == null) {//1、如果packageInfo为null,则调用getPackageInfo的得到LoadedApk
      r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
          Context.CONTEXT_INCLUDE_CODE);
    } 

    ComponentName component = r.intent.getComponent();
    if (component == null) {
      component = r.intent.resolveActivity(
        mInitialApplication.getPackageManager());
      r.intent.setComponent(component);
    } 

    if (r.activityInfo.targetActivity != null) {
      component = new ComponentName(r.activityInfo.packageName,
          r.activityInfo.targetActivity);
    } 

    Activity activity = null;
    try {//2、调用mInstrumentation的newActivity方法,得到Activity对象
      java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
      activity = mInstrumentation.newActivity(
          cl, component.getClassName(), r.intent);
      StrictMode.incrementExpectedActivityCount(activity.getClass());
      r.intent.setExtrasClassLoader(cl);
      if (r.state != null) {
        r.state.setClassLoader(cl);
      }
    } catch (Exception e) {
      if (!mInstrumentation.onException(activity, e)) {
        throw new RuntimeException(
          "Unable to instantiate activity " + component
          + ": " + e.toString(), e);
      }
    } 

    try {
      Application app = r.packageInfo.makeApplication(false, mInstrumentation);//3、获取Application对象 

      if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
      if (localLOGV) Slog.v(
          TAG, r + ": app=" + app
          + ", appName=" + app.getPackageName()
          + ", pkg=" + r.packageInfo.getPackageName()
          + ", comp=" + r.intent.getComponent().toShortString()
          + ", dir=" + r.packageInfo.getAppDir()); 

      if (activity != null) {//4、创建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);//5、执行Activity的attach方法,将此ContextImpl对象,设置给Activity,activity会调用attachBaseContext 

        if (customIntent != null) {
          activity.mIntent = customIntent;
        }
        r.lastNonConfigurationInstances = null;
        activity.mStartedActivity = false;
        int theme = r.activityInfo.getThemeResource();//6、设置主题
        if (theme != 0) {
          activity.setTheme(theme);
        } 

        activity.mCalled = false;
        mInstrumentation.callActivityOnCreate(activity, r.state);//7、执行Activity的onCreate方法
        if (!activity.mCalled) {
          throw new SuperNotCalledException(
            "Activity " + r.intent.getComponent().toShortString() +
            " did not call through to super.onCreate()");
        }
        r.activity = activity;
        r.stopped = true;
        if (!r.activity.mFinished) {
          activity.performStart();//8、执行Activity的onStart方法
          r.stopped = false;
        }
        if (!r.activity.mFinished) {
          if (r.state != null) {
            mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);//9、质细腻感onRestoresInstanceState方法
          }
        }
        if (!r.activity.mFinished) {
          activity.mCalled = false;
          mInstrumentation.callActivityOnPostCreate(activity, r.state);
          if (!activity.mCalled) {
            throw new SuperNotCalledException(
              "Activity " + r.intent.getComponent().toShortString() +
              " did not call through to super.onPostCreate()");
          }
        }
      }
      r.paused = true; 

      mActivities.put(r.token, r);//10、将包含activity信息集的r对象,也就是ActivityClientRecord,加入到mActivities中,r.token为key值。 

    } catch (SuperNotCalledException e) {
      throw e; 

    } catch (Exception e) {
      if (!mInstrumentation.onException(activity, e)) {
        throw new RuntimeException(
          "Unable to start activity " + component
          + ": " + e.toString(), e);
      }
    } 

    return activity;
  }

总结:activity的packageInfo对象和application的packageInfo是同一个对象。

6、Service中Context的创建过程

step 1、Ams通过远程Binder调用ActivityThread的内部类ApplicationThread的scheduleCreateService方法,参数包括serviceInfo,这个对象由Ams创建,通过IPC传递到ActivityThread的内部类ApplicationThread中。

public final void scheduleCreateService(IBinder token,
        ServiceInfo info, CompatibilityInfo compatInfo) {
      CreateServiceData s = new CreateServiceData();
      s.token = token;
      s.info = info;
      s.compatInfo = compatInfo; 

      queueOrSendMessage(H.CREATE_SERVICE, s);
    }

step 2、构建CreateServiceData对象,如上代码所示。

step 3、调用H Handler,执行handleCreateService()方法。

其中step 3又可分为一下5步。

private void handleCreateService(CreateServiceData data) {
    // If we are getting ready to gc after going to the background, well
    // we are back active so skip it.
    unscheduleGcIdler(); 

    LoadedApk packageInfo = getPackageInfoNoCheck(
        data.info.applicationInfo, data.compatInfo);//1、得到packageInfo,调用getPackageInfoNoCheck
    Service service = null;
    try {
      java.lang.ClassLoader cl = packageInfo.getClassLoader();
      service = (Service) cl.loadClass(data.info.name).newInstance();
    } catch (Exception e) {
      if (!mInstrumentation.onException(service, e)) {
        throw new RuntimeException(
          "Unable to instantiate service " + data.info.name
          + ": " + e.toString(), e);
      }
    } 

    try {
      if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name); 

      ContextImpl context = new ContextImpl();//2、创建ContextImpl对象
      context.init(packageInfo, null, this); 

      Application app = packageInfo.makeApplication(false, mInstrumentation);//3、得到Application对象
      context.setOuterContext(service);
      service.attach(context, this, data.info.name, data.token, app,
          ActivityManagerNative.getDefault());//4、调用service的attach方法,将实例化的ContextImpl设置给Service
      service.onCreate();
      mServices.put(data.token, service);//5、将service对象加入到mService集合中,key值为data.token。
      try {
        ActivityManagerNative.getDefault().serviceDoneExecuting(
            data.token, 0, 0, 0);
      } catch (RemoteException e) {
        // nothing to do.
      }
    } catch (Exception e) {
      if (!mInstrumentation.onException(service, e)) {
        throw new RuntimeException(
          "Unable to create service " + data.info.name
          + ": " + e.toString(), e);
      }
    }
  }

综上所述:

1、无论是Application还是Activity、Service,他们的LoadedApk对象都是同一个,或者说packageInfo为同一个对象。

2、在创建ContextImpl对象时,Application和SErvice通过getPackageInfoNoCheck方法,Activity通过getPackageInfo方法得到。

3、一个应用程序中Context的个数 = Activity的数量+Service的数量 +1。这里的1代表Application。

4、应用程序中包含着多个ContextImpl对象,其内部的PackageInfo却是同一个。这样设计意味着ContextImpl是一个轻量级类,PackageInfo是一个重量级类,所有和包相关的操作封装到PackageInfo中,有利于代码的封装与隐藏。

class ContextImpl extends Context {
  private final static String TAG = "ApplicationContext";
  private final static boolean DEBUG = false; 

  private static final HashMap<String, SharedPreferencesImpl> sSharedPrefs =
      new HashMap<String, SharedPreferencesImpl>(); 

  /*package*/ LoadedApk mPackageInfo;

以上就是本篇文章的全部内容,希望大家通过学习能够对Context有更深入的理解。

您可能感兴趣的文章:

  • Android 中Context的使用方法详解
  • Android编程实现全局获取Context及使用Intent传递对象的方法详解
  • Android全局获取Context实例详解
  • Android编程实现为ListView创建上下文菜单(ContextMenu)的方法
  • Android context源码详解及深入分析
  • Android面试笔记之常问的Context
  • 谈谈Android里的Context的使用实例
  • 避免 Android中Context引起的内存泄露
  • 安卓Android Context类实例详解
  • 详解Android中的Context抽象类
  • 深入解析Android App开发中Context的用法
  • Android编程获取全局Context的方法
  • Android编程中context及全局变量实例详解
  • Android中ContextMenu用法实例
  • android基础教程之context使用详解
  • Android获取其他包的Context实例代码
(0)

相关推荐

  • Android context源码详解及深入分析

    Android context详解 前言: Context都没弄明白,还怎么做Android开发? Activity mActivity =new Activity() 作为Android开发者,不知道你有没有思考过这个问题,Activity可以new吗?Android的应用程序开发采用Java语言,Activity本质上也是一个对象,那上面的写法有什么问题呢?估计很多人说不清道不明.Android程序不像Java程序一样,随便创建一个类,写个main()方法就能运行,Android应用模型是基

  • 安卓Android Context类实例详解

    1.例如下面的代码片段,Toast类的第一个参数接受一个Context对象: @Override protected Dialog onCreateDialog(int id) { switch (id) { case 0: Builder builder = new AlertDialog.Builder(this); builder.setIcon(R.drawable.ic_launcher); builder.setTitle("This is a dialog with some si

  • Android编程中context及全局变量实例详解

    本文实例讲述了Android编程中context及全局变量的用法.分享给大家供大家参考,具体如下: 今天在研究context的时候,对application和activity context有了一定的了解,下面是从网上复制过来的资料 Application context和Activity context的区别: 这是两种不同的context,也是最常见的两种.第一种中context的生命周期与Application的生命周期相关的,context随着Application的销毁而销毁,伴随ap

  • Android 中Context的使用方法详解

    Android 中Context的使用方法详解 概要: Context字面意思是上下文,位于framework package的android.content.Context中,其实该类为LONG型,类似Win32中的Handle句柄.很多方法需要通过 Context才能识别调用者的实例:比如说Toast的第一个参数就是Context,一般在Activity中我们直接用this代替,代表调用者的实例为Activity,而到了一个button的onClick(View view)等方法时,我们用t

  • 深入解析Android App开发中Context的用法

    Context在开发Android应用的过程中扮演着非常重要的角色,比如启动一个Activity需要使用context.startActivity方法,将一个xml文件转换为一个View对象也需要使用Context对象,可以这么说,离开了这个类,Android开发寸步难行,对于这样一个类,我们又对他了解多少呢.我就说说我的感受吧,在刚开始学习Android开发时,感觉使用Context的地方一直就是传入一个Activity对象,久而久之感觉只要是Context的地方就传入一个Activity就行

  • Android编程实现为ListView创建上下文菜单(ContextMenu)的方法

    本文实例讲述了Android编程实现为ListView创建上下文菜单(ContextMenu)的方法.分享给大家供大家参考,具体如下: ContextMenu称为上下文菜单,一般在控件上长按时弹出.今天我们学习ContextMenu的用法,这里与listview相结合,先在ListView显示几个Item,然后在Item上长按,弹出一个菜单(就是ContextMenu),点击菜单上的项目,提示刚才长按的Item的Position. main.xml文件 <?xml version="1.0

  • Android编程实现全局获取Context及使用Intent传递对象的方法详解

    本文实例讲述了Android编程实现全局获取Context及使用Intent传递对象的方法.分享给大家供大家参考,具体如下: 一.全局获取 Context Android 开发中很多地方需要用到 Context,比如弹出 Toast.启动活动.发送广播.操作数据库-- 由于很多操作都是在活动中进行的,而活动本身就是一个 Context 对象,所以获取 Context 并不是那么困难. 但是,当应用程序的架构逐渐开始复杂起来的时候,很多的逻辑代码都将脱离 Activity 类,由此在某些情况下,获

  • Android全局获取Context实例详解

    Android全局获取Context实例详解 在弹出Toast 启动活动 发送广播 操作数据库 使用通知等等时都需要Context 如果操作在活动中进行是很简单的,因为活动本身就是一个Context对象 但是当逻辑代码脱离了Activity类,此时使用Context就需要一些技巧了: 我们可以定制一个自己的Application类,以便管理程序内一些全局状态信息,比如全局Context 代码如下: public class MyApplication extends Application{ p

  • Android中ContextMenu用法实例

    本文实例讲述了Android中ContextMenu用法.分享给大家供大家参考.具体如下: main.xml文件如下: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:Android="http://schemas.android.com/apk/res/android" Android:orientation="vertical" And

  • 详解Android中的Context抽象类

    关于Context我们首先应该知道: (1)它描述的是一个应用程序环境的信息,即上下文. (2)该类是一个抽象(abstract class)类,Android提供了该抽象类的具体实现类(后面我们会讲到是ContextIml类). (3)通过它我们可以获取应用程序的资源和类,也包括一些应用级别操作,例如:启动一个Activity,发送广播,接受Intent信息等.. 于是,我们可以利用该Context对象去构建应用级别操作(application-level operations) . 一.Co

  • 避免 Android中Context引起的内存泄露

    Context是我们在编写Android程序经常使用到的对象,意思为上下文对象. 常用的有Activity的Context还是有Application的Context.Activity用来展示活动界面,包含了很多的视图,而视图又含有图片,文字等资源.在Android中内存泄露很容易出现,而持有很多对象内存占用的Activity更加容易出现内存泄露,开发者需要特别注意这个问题. 本文讲介绍Android中Context,更具体的说是Activity内存泄露的情况,以及如何避免Activity内存泄

  • Android编程获取全局Context的方法

    本文实例讲述了Android编程获取全局Context的方法.分享给大家供大家参考,具体如下: 有时,在处理业务逻辑的时候,需要Context对象,但在某些情况下,并非容易获取,这时就需要一些巧妙的手段来管理Context. 在Android中,提供了一个类Application,当应用程序启动的时候,系统会自动将这个类进行初始化,所以我们可以编写自己的Application类以管理一些全局的状态信息. 在这里,以获取全局Context为例. 1.编写自己的Application类 packag

  • 谈谈Android里的Context的使用实例

    大家好,今天给大家分享一下Android里的Context的一些用法,以前经常有人在群里问我比如我在一个工具类里的某个方法,或者View里需要调用Context.但是工具类还有View里没有这个上下文怎么办?为了解决大家的疑问,为了解决大家的疑问,我今天写一个简单的Demo.让大家如何学好自如的用Context.想什么时候有Context,什么时候就有Context. 这里大致可以分为两种:一是传递Context参数,二是调用全局的Context. 其实我们应用启动的时候会启动Applicati

  • Android获取其他包的Context实例代码

    Android中有Context的概念,想必大家都知道.Context可以做很多事情,打开activity.发送广播.打开本包下文件夹和数据库.获取classLoader.获取资源等等.如果我们得到了一个包的Context对象,那我们基本上可以做这个包自己能做的大部分事情.那我们能得到吗?很高兴的告诉你,能!Context有个createPackageContext方法,可以创建另外一个包的上下文,这个实例不同于它本身的Context实例,但是功能是一样的. 这个方法有两个参数:1.packag

  • Android面试笔记之常问的Context

    前言 Context,在翻译为上下文,也可以理解为环境,是提供一些程序的运行环境基础信息.基本上在开发项目的时候,时刻都有接触到.Android程序不像Java程序,随便创建一个类,写个main()方法就能跑,而是要有一个完整的Android工程环境,在这个环境下,有像Activity.Service.BroadcastReceiver等系统组件,而这些组件并不是像一个普通的Java对象new一下就能创建实例的了,而是要有它们各自的上下文环境,也就是Context.可以说Context是维持An

  • android基础教程之context使用详解

    在android中有两种context,一种是application context,一种是activity context,通常我们在各种类和方法间传递的是activity context. 区别联系: 复制代码 代码如下: public class MyActivity extends Activity {    public void method() {       mContext = this;    // since Activity extends Context       m

随机推荐