当前位置: 首页 > news >正文

推介做界面的网站付费网站源码

推介做界面的网站,付费网站源码,四川公共交易资源信息网,自己做一个app目录 前言一、Context简介二、Application Context2.1 Application Context的创建过程2.2 Application Context的获取过程 三、Activity的Context创建过程四、Service的Context创建过程 前言 Context也就是上下文对象#xff0c;是Android较为常用的类#xff0c;但是对于Co… 目录 前言一、Context简介二、Application Context2.1 Application Context的创建过程2.2 Application Context的获取过程 三、Activity的Context创建过程四、Service的Context创建过程 前言 Context也就是上下文对象是Android较为常用的类但是对于Context大多都停留在会用的阶段本文会从源码角度来分析Context从而更加深入的理解它。 一、Context简介 Context意为上下文或者场景是一个应用程序环境信息的接口。 在开发中我们经常会使用Context它的使用场景总的来说分为两大类它们分别是 使用Context调用方法比如启动Activity、访问资源、调用系统级服务等。调用方法时传入Context比如弹出Toast、创建Dialog等。 Activity、Service和Application都是间接的继承自Context的因此可以计算出一个应用程序进程中有多少个Context这个数量等于Activity和Service的总个数加11指的是Application的数量。 Context是一个抽象类它的内部定义了很多方法以及静态常量它的具体实现类为ContextImpl。和Context相关联的类除了ContextImpl还有ContextWrapper、ContextThemeWrapper和Activity等等下面给出Context的关系图。 从图中我们可以看出ContextImpl和ContextWrapper继承自ContextContextThemeWrapper、Service和Application继承自ContextWrapper。ContextWrapper和ContextThemeWrapper都是Context的包装类它们都含有Context类型的mBase对象mBase具体指向的是ContextImpl这样通过ContextWrapper和ContextThemeWrapper也可以使用Context的方法。ContextThemeWrapper中包含和主题相关的方法比如 getTheme方法因此需要主题的Activity继承ContextThemeWrapper而不需要主题的Service则继承ContextWrapper。 二、Application Context 2.1 Application Context的创建过程 我们通过调用getApplicationContext来获取应用程序的全局的Application Context那么Application Context是如何创建的呢 当一个应用程序启动完成后应用程序就会有一个全局的Application Context。那么我们就从应用程序启动过程开始着手。 ActivityThread作为应用程序进程的核心类它会调用它的内部类ApplicationThread的scheduleLaunchActivity方法来启动Activity如下所示。 frameworks/base/core/java/android/app/ActivityThread.java private class ApplicationThread extends ApplicationThreadNative {...Overridepublic final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,ActivityInfo info, Configuration curConfig, Configuration overrideConfig,CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,int procState, Bundle state, PersistableBundle persistentState,ListResultInfo pendingResults, ListReferrerIntent pendingNewIntents,boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {updateProcessState(procState, false);ActivityClientRecord r new ActivityClientRecord();...sendMessage(H.LAUNCH_ACTIVITY, r);}... } 在ApplicationThread的scheduleLaunchActivity方法中向H类发送LAUNCH_ACTIVITY类型的消息目的是将启动Activity的逻辑放在主线程中的消息队列中这样启动Activity的逻辑会在主线程中执行。我们接着查看H类的handleMessage方法对LAUNCH_ACTIVITY类型的消息的处理。 frameworks/base/core/java/android/app/ActivityThread.java private class H extends Handler {public static final int LAUNCH_ACTIVITY 100; ... public void handleMessage(Message msg) {if (DEBUG_MESSAGES) Slog.v(TAG, handling: codeToString(msg.what));switch (msg.what) {case LAUNCH_ACTIVITY: {Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, activityStart);final ActivityClientRecord r (ActivityClientRecord) msg.obj;r.packageInfo getPackageInfoNoCheck(r.activityInfo.applicationInfo, r.compatInfo);//1handleLaunchActivity(r, null, LAUNCH_ACTIVITY);//2Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);} break;... }H继承自Handler 是ActivityThread的内部类。在注释1处通过getPackageInfoNoCheck方法获得LoadedApk类型的对象并将该对象赋值给ActivityClientRecord 的成员变量packageInfo其中LoadedApk用来描述已加载的APK文件。在注释2处调用handleLaunchActivity方法如下所示。 frameworks/base/core/java/android/app/ActivityThread.java private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {...Activity a performLaunchActivity(r, customIntent);...}接着查看performLaunchActivity方法 frameworks/base/core/java/android/app/ActivityThread.java private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {...try {Application app r.packageInfo.makeApplication(false, mInstrumentation);...} ...return activity;}performLaunchActivity方法中有很多重要的逻辑这里只保留了Application Context相关的逻辑这里ActivityClientRecord 的成员变量packageInfo是LoadedApk类型的接着来查看LoadedApk的makeApplication方法如下所示。 frameworks/base/core/java/android/app/LoadedApk.java public Application makeApplication(boolean forceDefaultAppClass,Instrumentation instrumentation) {if (mApplication ! null) {//1return mApplication;}...try {...java.lang.ClassLoader cl getClassLoader();...ContextImpl appContext ContextImpl.createAppContext(mActivityThread, this);//2app mActivityThread.mInstrumentation.newApplication(cl, appClass, appContext);//3appContext.setOuterContext(app);//4} catch (Exception e) {...}mActivityThread.mAllApplications.add(app);mApplication app;//5...return app; }注释1处如果mApplication不为null则返回mApplication这里假设是第一次启动应用程序因此mApplication为null。 在注释2处通过ContextImpl的createAppContext方法来创建ContextImpl。 注释3处的代码用来创建Application在Instrumentation的newApplication方法中传入了ClassLoader类型的对象以及注释2处创建的ContextImpl 。 在注释4处将Application赋值给ContextImpl的Context类型的成员变量mOuterContext。 注释5处将Application赋值给LoadedApk的成员变量mApplication在Application Context的获取过程中我们会再次用到mApplication。 来查看注释3处的Application是如何创建的Instrumentation的newApplication方法如下所示。 frameworks/base/core/java/android/app/Instrumentation.java static public Application newApplication(Class? clazz, Context context)throws InstantiationException, IllegalAccessException, ClassNotFoundException {Application app (Application)clazz.newInstance();//1app.attach(context);return app; }Instrumentation中有两个newApplication重载方法最终会调用上面这个重载方法。注释1处通过反射来创建Application并调用了Application的attach方法并将ContextImpl传进去 frameworks/base/core/java/android/app/Application.java /* package */ final void attach(Context context) {attachBaseContext(context);mLoadedApk ContextImpl.getImpl(context).mPackageInfo; }attach方法中调用了attachBaseContext方法它的实现在Application的父类ContextWrapper中代码如下所示。 frameworks/base/core/java/android/content/ContextWrapper.java protected void attachBaseContext(Context base) {if (mBase ! null) {throw new IllegalStateException(Base context already set);}mBase base;}从上文得知这个base指的是ContextImpl将ContextImpl赋值给ContextWrapper的Context类型的成员变量mBase。 2.2 Application Context的获取过程 熟知了Application Context的创建过程那么它的获取过程会非常好理解。我们通过调用getApplicationContext方法来获得Application ContextgetApplicationContext方法的实现在ContextWrapper中如下所示。 frameworks/base/core/java/android/content/ContextWrapper.java Overridepublic Context getApplicationContext() {return mBase.getApplicationContext();}从上文得知mBase指的是ContextImpl我们来查看 ContextImpl的getApplicationContext方法 frameworks/base/core/java/android/app/ContextImpl.java Override public Context getApplicationContext() {return (mPackageInfo ! null) ?mPackageInfo.getApplication() : mMainThread.getApplication(); }如果LoadedApk不为null则调用LoadedApk的getApplication方法否则调用AvtivityThread的getApplication方法。由于应用程序这时已经启动因此LoadedApk不会为null则会调用LoadedApk的getApplication方法 frameworks/base/core/java/android/app/LoadedApk.java Application getApplication() {return mApplication;}这里的mApplication我们应该很熟悉它在上文LoadedApk的makeApplication方法的注释5处被赋值。这样我们通过getApplicationContext方法就获取到了Application Context。 三、Activity的Context创建过程 当我们在Activity中调用startActivity方法时其实调用的是Context的startActivity方法,如果想要在Activity中使用Context提供的方法务必要先创建Context。Activity的Context会在Activity的启动过程中被创建 ActivityThread是应用程序进程的核心类它的内部类ApplicationThread会调用scheduleLaunchActivity方法来启动ActivityscheduleLaunchActivity方法如下所示。 frameworks/base/core/java/android/app/ActivityThread.java Override public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,ActivityInfo info, Configuration curConfig, Configuration overrideConfig,CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,int procState, Bundle state, PersistableBundle persistentState,ListResultInfo pendingResults, ListReferrerIntent pendingNewIntents,boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {updateProcessState(procState, false);ActivityClientRecord r new ActivityClientRecord();r.token token;...sendMessage(H.LAUNCH_ACTIVITY, r); }scheduleLaunchActivity方法会将启动Activity的参数封装成ActivityClientRecord sendMessage方法向H类发送类型为LAUNCH_ACTIVITY的消息并将ActivityClientRecord 传递过去。sendMessage方法的目的是将启动Activity的逻辑放在主线程中的消息队列中这样启动Activity的逻辑就会在主线程中执行。 H类的handleMessage方法中会对LAUNCH_ACTIVITY类型的消息进行处理其中调用了handleLaunchActivity方法而handleLaunchActivity方法中又调用performLaunchActivity方法来查看performLaunchActivity方法。 frameworks/base/core/java/android/app/ActivityThread.java private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {...Activity activity null;try {java.lang.ClassLoader cl r.packageInfo.getClassLoader();activity mInstrumentation.newActivity(cl, component.getClassName(), r.intent);//1...}} catch (Exception e) {...}try {...if (activity ! null) {Context appContext createBaseContextForActivity(r, activity);//2.../***3*/activity.attach(appContext, this, getInstrumentation(), r.token,r.ident, app, r.intent, r.activityInfo, title, r.parent,r.embeddedID, r.lastNonConfigurationInstances, config,r.referrer, r.voiceInteractor, window); ...if (r.isPersistable()) {mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);//4} else {mInstrumentation.callActivityOnCreate(activity, r.state);}...}return activity;}performLaunchActivity方法中有很多重要的逻辑这里只保留了Activity的Context相关的逻辑。在注释1处用来创建Activity的实例。注释2处通过createBaseContextForActivity方法用来创建Activity的ContextImpl并将ContextImpl传入注释3处的activity的attach方法中。在注释4处Instrumentation的callActivityOnCreate方法中会调用Activity的onCreate方法。 我们先来查看注释2出的createBaseContextForActivity方法 frameworks/base/core/java/android/app/ActivityThread.java private Context createBaseContextForActivity(ActivityClientRecord r, final Activity activity) {...ContextImpl appContext ContextImpl.createActivityContext(this, r.packageInfo, r.token, displayId, r.overrideConfig);//1appContext.setOuterContext(activity);//2Context baseContext appContext;...return baseContext;}在注释1处调用ContextImpl的createActivityContext方法来创建ContextImpl注释2处调用了ContextImpl的setOuterContext方法将此前创建的Activity 实例赋值给ContextImpl的成员变量mOuterContext这样ContextImpl也可以访问Activity的变量和方法。 我们再回到ActivityThread的performLaunchActivity方法查看注释3处的Activity的attach方法如下所示。 frameworks/base/core/java/android/app/Activity.java final void attach(Context context, ActivityThread aThread,Instrumentation instr, IBinder token, int ident,Application application, Intent intent, ActivityInfo info,CharSequence title, Activity parent, String id,NonConfigurationInstances lastNonConfigurationInstances,Configuration config, String referrer, IVoiceInteractor voiceInteractor,Window window) {attachBaseContext(context);//1mFragments.attachHost(null /*parent*/);mWindow new PhoneWindow(this, window);//2mWindow.setWindowControllerCallback(this);mWindow.setCallback(this);//3mWindow.setOnWindowDismissedCallback(this);...mWindow.setWindowManager((WindowManager)context.getSystemService(Context.WINDOW_SERVICE),mToken, mComponent.flattenToString(),(info.flags ActivityInfo.FLAG_HARDWARE_ACCELERATED) ! 0);//4if (mParent ! null) {mWindow.setContainer(mParent.getWindow());}mWindowManager mWindow.getWindowManager();//5mCurrentConfig config;}在注释2处创建PhoneWindow它代表应用程序窗口。PhoneWindow在运行中会间接触发很多事件比如点击事件、菜单弹出、屏幕焦点变化等事件这些事件需要转发给与PhoneWindow关联的Actvity转发操作通过Window.Callback接口实现Actvity实现了这个接口在注释3处将当前Activity通过Window的setCallback方法传递给PhoneWindow。 注释4处给PhoneWindow设置WindowManager并在注释5处获取WindowManager并赋值给Activity的成员变量mWindowManager 这样在Activity中就可以通过getWindowManager方法来获取WindowManager。 在注释1处调用了ContextThemeWrapper的attachBaseContext方法如下所示。 frameworks/base/core/java/android/view/ContextThemeWrapper.java Override protected void attachBaseContext(Context newBase) {super.attachBaseContext(newBase); }attachBaseContext方法接着调用ContextThemeWrapper的父类ContextWrapper的attachBaseContext方法 frameworks/base/core/java/android/content/ContextWrapper.java protected void attachBaseContext(Context base) {if (mBase ! null) {throw new IllegalStateException(Base context already set);}mBase base;//1 }注释1处的base指的是一路传递过来的Activity的ContextImpl将它赋值给ContextWrapper的成员变量mBase。这样ContextWrapper的功能就可以交由ContextImpl处理举个例子 frameworks/base/core/java/android/content/ContextWrapper.java Override public Resources.Theme getTheme() {return mBase.getTheme(); }当调用ContextWrapper的getTheme方法其实就是调用的ContextImpl的getTheme方法。 Activity的Context创建过程就讲到这里。 总结一下在启动Activity的过程中创建ContextImpl并赋值给ContextWrapper的成员变量mBase中。Activity继承自ContextWrapper的子类ContextThemeWrapper这样在Activity中就可以使用ContextImpl了。 四、Service的Context创建过程 Service的Context创建过程与Activity的Context创建过程类似也是在Service的启动过程中被创建 ActivityThread的内部类ApplicationThread会调用scheduleCreateService方法来启动Service如下所示。 frameworks/base/core/java/android/app/ActivityThread.java public final void scheduleCreateService(IBinder token,ServiceInfo info, CompatibilityInfo compatInfo, int processState) {...sendMessage(H.CREATE_SERVICE, s);}sendMessage方法向H类发送CREATE_SERVICE类型的消息H类的handleMessage方法中会对CREATE_SERVICE类型的消息进行处理其中调用了handleCreateService方法 frameworks/base/core/java/android/app/ActivityThread.java private void handleCreateService(CreateServiceData data) {...try {if (localLOGV) Slog.v(TAG, Creating service data.info.name);ContextImpl context ContextImpl.createAppContext(this, packageInfo);//1context.setOuterContext(service);Application app packageInfo.makeApplication(false, mInstrumentation);service.attach(context, this, data.info.name, data.token, app,ActivityManagerNative.getDefault());//2service.onCreate();...} catch (Exception e) {... }}在注释1处创建了ContextImpl 并将该ContextImpl传入注释2处service的attach方法中 frameworks/base/core/java/android/app/Service.java public final void attach(Context context,ActivityThread thread, String className, IBinder token,Application application, Object activityManager) {attachBaseContext(context);//1mThread thread; // NOTE: unused - remove?mClassName className;mToken token;mApplication application;mActivityManager (IActivityManager)activityManager;mStartCompatibility getApplicationInfo().targetSdkVersion Build.VERSION_CODES.ECLAIR;}注释1处调用了ContextWrapper的attachBaseContext方法。 frameworks/base/core/java/android/content/ContextWrapper.java protected void attachBaseContext(Context base) {if (mBase ! null) {throw new IllegalStateException(Base context already set);}mBase base; }attachBaseContext方法在前文已经讲过这里不再赘述。 Service的Context创建过程就讲解到这里它和Activity的Context创建过程类似。 参考链接 深度详解 Android 之 Context Android Context完全解析你所不知道的Context的各种细节
http://www.hkea.cn/news/14450274/

相关文章:

  • 一流的盐城网站开发网上做石材去哪个网站
  • 做分销网站好吗石景山郑州阳网站建设
  • 网站建设需要学多久任务发布平台
  • flash网站设计概述装修论坛
  • 网络 网站建设网站制作代码大全
  • 宣传网站建设的意义标题制作网站
  • 岳阳建设网站制作杭州市网站seo
  • 网站建设管理系统免费网站室内装修设计软件排行榜
  • 网站视频怎么做公共资源交易中心网站建设汇报
  • 南沙哪有做网站的专业网站建设哪家好
  • 购物网站开发 需求分析wordpress文章固定字段
  • 网站免费建站 图标用python做的网站多吗
  • 凡科做的网站提示证书错误展示型网站 带后台
  • wordpress电影网站主题广州优俊网站制作公司
  • 网站模板素材下载网址大全浏览器
  • 合作建站协议wordpress文章排行榜
  • 衡水公司做网站做网站标签栏的图片大小
  • 做整体衣柜宣传海报的网站网站建设九亭
  • 地产网站建设案例呼和浩特城乡建设网站
  • 网站建设设计制作方案与价格ireal 网站建设
  • 大学网站 作风建设专题新站seo快速排名 排名
  • seo与网站建设房山建站公司
  • 网站到期域名怎么解决办法杭州网站建设制作联系电话
  • 做网站空间需要多大建设物流网站
  • 中国建设银行网站个人客户没有货源怎么开网店?
  • 网站建设风险是什么意思网站建设答辩问题
  • 顺德做网站那家好长沙做网站公司有哪些
  • 淘宝的网站建设wordpress the field
  • 手机网站带后台源代码谷歌在线搜索
  • 国内自助建站品牌建设与诚信建设相结合