美文网首页
资源加载的流程

资源加载的流程

作者: gogoingmonkey | 来源:发表于2021-04-04 09:42 被阅读0次

APP加载资源

我们APP中经常会用到图片,颜色等资源,但是你是否清楚这些资源是从什么时机,如何加载到我们的页面吗

加载思维导图

image.png

流程总结:

1.activtyThread的handerbindApplication开始,里面创建仪表盘,并调用Application的onCreate方法,调用loadedApk的makeApplication方法
2.这个方法中创建contextImpl类ContextImpl.createAppContext,这个里面调用contextImpl 的.setResources方法加载资源。资源参数是packageInfo.getResource()
3.资源调用ResourcesManager.getInstance().getResources获取,里面调用createResources方法创建,findOrCreateResourcesImplForKeyLocked 里面再AssetManager assets = createAssetManager ,最后是通过setApkAssert调用native方法实现加载资源。

源码分析

1.入口和View创建在同一个类,ActivityThread中,handleBindApplication()开始,主要就三个核心点:1.创建Instrumentation对象,2,调用AppBindData.loadAPKInfo.makeApplication()创建Application,3再调用我们一般APP初始化的地方Application的onCreate方法

  /*  1.创建Instrumentation对象*/ 
    mInstrumentation = new Instrumentation();
            mInstrumentation.basicInit(this);
        }

    ...
 /*  2.创建application对象*/ 
            app = data.info.makeApplication(data.restrictedBackupMode, null);

            // Propagate autofill compat state
            app.setAutofillOptions(data.autofillOptions);

            // Propagate Content Capture options
            app.setContentCaptureOptions(data.contentCaptureOptions);

            mInitialApplication = app;

            // don't bring up providers in restricted mode; they may depend on the
            // app's custom Application class
            if (!data.restrictedBackupMode) {
                if (!ArrayUtils.isEmpty(data.providers)) {
                    installContentProviders(app, data.providers);
                }
            }

            // Do this after providers, since instrumentation tests generally start their
            // test thread at this point, and we don't want that racing.
            try {
                mInstrumentation.onCreate(data.instrumentationArgs);
            }
            catch (Exception e) {
                throw new RuntimeException(
                    "Exception thrown in onCreate() of "
                    + data.instrumentationName + ": " + e.toString(), e);
            }
            try {
 /*  3.通过Instrumentation对象调用Application的 onCreate方法*/ 
                mInstrumentation.callApplicationOnCreate(app);
            } catch (Exception e) {
                if (!mInstrumentation.onException(app, e)) {
                    throw new RuntimeException(
                      "Unable to create application " + app.getClass().getName()
                      + ": " + e.toString(), e);
                }
            }

2.上面方法2调用了

ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);

3.里面调用了createAppContext方法

static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo,
/**1,这里set资源*/
       context.setResources(packageInfo.getResources());
       context.mIsSystemOrSystemUiContext = isSystemOrSystemUI(context);
       return context;
   }

4.调用到getResouce方法

 public Resources getResources() {
       
            mResources = ResourcesManager.getInstance().getResources(null, mResDir,
                    splitPaths, mOverlayDirs, mApplicationInfo.sharedLibraryFiles,
                    Display.DEFAULT_DISPLAY, null, getCompatibilityInfo(),
                    getClassLoader(), null);
        }
        return mResources;
    }

5.又从LoadedApk方法,调到ResourcesManager.getInstance().getResources


public @Nullable Resources getResources(
            @Nullable IBinder activityToken,
            @Nullable String resDir,
            @Nullable String[] splitResDirs,
            @Nullable String[] overlayDirs,
            @Nullable String[] libDirs,
            int displayId,
            @Nullable Configuration overrideConfig,
            @NonNull CompatibilityInfo compatInfo,
            @Nullable ClassLoader classLoader,
            @Nullable List<ResourcesLoader> loaders) {
    ...

            return createResources(activityToken, key, classLoader);
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_RESOURCES);
        }
    }

直接看createResources方法,里面调用了

private @Nullable Resources createResources(@Nullable IBinder activityToken,
            @NonNull ResourcesKey key, @NonNull ClassLoader classLoader) {
        synchronized (this) {
            if (DEBUG) {
                Throwable here = new Throwable();
                here.fillInStackTrace();
                Slog.w(TAG, "!! Get resources for activity=" + activityToken + " key=" + key, here);
            }

            ResourcesImpl resourcesImpl = findOrCreateResourcesImplForKeyLocked(key);
            if (resourcesImpl == null) {
                return null;
            }

            if (activityToken != null) {
                return createResourcesForActivityLocked(activityToken, classLoader,
                        resourcesImpl, key.mCompatInfo);
            } else {
                return createResourcesLocked(classLoader, resourcesImpl, key.mCompatInfo);
            }
        }
    }

看这个方法 findOrCreateResourcesImplForKeyLocked(key里面终于调用到 createResourcesImpl(key) ,这里就到咯Assert类类

private @Nullable ResourcesImpl createResourcesImpl(@NonNull ResourcesKey key) {
        final DisplayAdjustments daj = new DisplayAdjustments(key.mOverrideConfiguration);
        daj.setCompatibilityInfo(key.mCompatInfo);

        final AssetManager assets = createAssetManager(key);
        if (assets == null) {
            return null;
        }

        final DisplayMetrics dm = getDisplayMetrics(key.mDisplayId, daj);
        final Configuration config = generateConfig(key, dm);
        final ResourcesImpl impl = new ResourcesImpl(assets, dm, config, daj);

        if (DEBUG) {
            Slog.d(TAG, "- creating impl=" + impl + " with key: " + key);
        }
        return impl;
    }

再调用到加载资源到setApkAssets完成资源加载,调用native方法实现

相关文章

  • Android之插件换肤(一)

    1.布局创建流程(源码) 2.资源加载流程(源码) 介绍LayoutInflater 1.资源加载 ImageVi...

  • Android 换肤那些事儿, Resource包装流 ?Ass

    一、Res资源加载流程 应用资源加载的过程 主要涉及两个类: Resource只与应用程序交互,负责加载资源的管理...

  • Glide最新源码解析(三)- 加载Model

    介绍 上一篇介绍了加载资源的流程,主要讲解了加载资源的主流程,本篇主要讲解从Model到Data是如何加载的? M...

  • 资源加载的流程

    APP加载资源 我们APP中经常会用到图片,颜色等资源,但是你是否清楚这些资源是从什么时机,如何加载到我们的页面吗...

  • Tinker源码分析(四):加载资源补丁流程

    本系列 Tinker 源码解析基于 Tinker v1.9.12 加载资源补丁流程 将到资源补丁的加载,首先还要回...

  • Hybrid资源管理

    为了提高hybrid中webView的加载速度,将需要加载的资源文件提前下到APP中,下面将对资源下载流程进行介绍...

  • Android加载Split资源新方案

    在学习qigsaw的过程中发现其加载和检查资源流程相对麻烦,从而造成效率低下。 加载新资源后不需要重复加载,所以加...

  • 119.乾坤资源加载机制

    通过import-html-entry请求资源 资源加载主要流程图,只看第二个节点的即可 加载entry方法 im...

  • 一键换肤背后的原理

    该文主要从三个方面去介绍,分别为Activity的布局流程,资源加载流程以及换肤思路。 Activity的布局流程...

  • webpack 源码-资源加载

    准备编译的代码资源 一共四个文件资源 webpack 资源加载 - 主流程 1.Compiler.js - run...

网友评论

      本文标题:资源加载的流程

      本文链接:https://www.haomeiwen.com/subject/rqakkltx.html