安卓源码分析1

一、dex的加载

ClassLoader -> DexPathList-> loadDex -> OpenDexFilesFromOat - > dex2oat . dexFile 对象 保存在DexPathList 中

 static DexFile loadDex(String sourcePathName, String outputPathName,
        int flags, ClassLoader loader, DexPathList.Element[] elements) throws IOException {
        return new DexFile(sourcePathName, outputPathName, flags, loader, elements);
    }

 

 

dex_files = runtime->GetOatFileManager().OpenDexFilesFromOat(sourceName.c_str(),
                                                               class_loader,
                                                               dex_elements,
                                                               /*out*/ &oat_file,
                                                               /*out*/ &error_msgs);

 

二、so加载

System.load->ClassLoader.findLibary->DexplathList(this.nativeLibraryPathElements)->findLibary->LoadNativeLibrary->android_dlopen_ext -> libraries_

 void* handle = android::OpenNativeLibrary(env,
                                            runtime_->GetTargetSdkVersion(),
                                            path_str,
                                            class_loader,
                                            library_path.get(),
                                            &needs_native_bridge,
                                            error_msg);

 

 

__attribute__((__weak__))
void* android_dlopen_ext(const char* filename, int flag, const android_dlextinfo* extinfo) {
  const void* caller_addr = __builtin_return_address(0);
  return __loader_android_dlopen_ext(filename, flag, extinfo, caller_addr);
}

 

三、类加载

classloader.findClass->dexPathList.findClass-> loadClassBinaryName -> classlinker.defineClass->linkCode -> loadMehod

dexPathList遍历找到需要jclass 返回  

复制代码
     static jclass DexFile_defineClassNative(JNIEnv* env,
353                                          jclass,
354                                          jstring javaName,
355                                          jobject javaLoader,
356                                          jobject cookie,
357                                          jobject dexFile) {
358    std::vector<const DexFile*> dex_files;
359    const OatFile* oat_file;
360    if (!ConvertJavaArrayToDexFiles(env, cookie, /*out*/ dex_files, /*out*/ oat_file)) {
364    }371    const std::string descriptor(DotToDescriptor(class_name.c_str()));
372    const size_t hash(ComputeModifiedUtf8Hash(descriptor.c_str()));
373    for (auto& dex_file : dex_files) {
374      const DexFile::ClassDef* dex_class_def =
375          OatDexFile::FindClassDef(*dex_file, descriptor.c_str(), hash);
376      if (dex_class_def != nullptr) {
377        ScopedObjectAccess soa(env);
378        ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
379        StackHandleScope<1> hs(soa.Self());
380        Handle<mirror::ClassLoader> class_loader(
381            hs.NewHandle(soa.Decode<mirror::ClassLoader>(javaLoader)));
382        ObjPtr<mirror::DexCache> dex_cache =
383            class_linker->RegisterDexFile(*dex_file, class_loader.Get());
384        if (dex_cache == nullptr) {
385          // OOME or InternalError (dexFile already registered with a different class loader).
386          soa.Self()->AssertPendingException();
387          return nullptr;
388        }
389        ObjPtr<mirror::Class> result = class_linker->DefineClass(soa.Self(),
390                                                                 descriptor.c_str(),
391                                                                 hash,
392                                                                 class_loader,
393                                                                 *dex_file,
394                                                                 *dex_class_def);
395        // Add the used dex file. This only required for the DexFile.loadClass API since normal
396        // class loaders already keep their dex files live.
397        class_linker->InsertDexFileInToClassLoader(soa.Decode<mirror::Object>(dexFile),
398                                                   class_loader.Get());
399        if (result != nullptr) {
400          VLOG(class_linker) << "DexFile_defineClassNative returning " << result
401                             << " for " << class_name.c_str();
402          return soa.AddLocalReference<jclass>(result);
403        }
404      }
405    }
406    VLOG(class_linker) << "Failed to find dex_class_def " << class_name.c_str();
407    return nullptr;
408  }
复制代码

 

 

四、ART下的另外一层

 

oat 文件(类似序列化的对象)

OAT文件是ELF格式文件,其包含2个重要的Section,oatdata段保存了被优化的原.dex文件(Dex File Content),以及一个用来找到方法的索引(OatClass)。通过OatClass段,可以在art文件中找到本地机器指令的偏移。

DexCache的初始化过程。当classloader load一个尚未加载的类A,findClass->loadClass->defineClass A的时候,会去ClassLinker(单例)中查找A类所在的DEXFile,然后调用ClassLinker->RegisterDexFile(),有几个dexfile就会注册几个dexCache。

Handle<mirror::DexCache> dex_cache(hs.NewHandle(klass->GetDexCache()));

 

类的初始化 ObjPtr<mirror::Class> klass 对象 ,对象 包含多个table,和与之对应的DexCache

 

参考:

https://blog.csdn.net/zhu929033262/article/details/75093012

ART执行类方法解析流程

 

posted @   0ne小孩  阅读(4)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
点击右上角即可分享
微信分享提示