安卓源码分析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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探