DexFile_openDexFileNative函数解析

static jint DexFile_openDexFileNative(JNIEnv* env, jclass, jstring javaSourceName, jstring javaOutputName, jint) { ScopedUtfChars sourceName(env, javaSourceName); // Java中的String转换成char*型 i
摘要由CSDN通过智能技术生成

      DexFile_openDexFileNative对应于java层的openDexFile(String sourceName, String outputName, int flags)函数。其中sourceName为指定源文件路径,outputName为输出目录。

一、DexFile_openDexFileNative

static jint DexFile_openDexFileNative(JNIEnv* env, jclass, jstring javaSourceName, jstring javaOutputName, jint) {    
  ScopedUtfChars sourceName(env, javaSourceName);    // 将 javaSourceName 从jstring类转换成ScopedUtfChars类
  if (sourceName.c_str() == NULL) {                  // 若javaSourceName为空,则返回
	return 0;
  }
  std::string dex_location(sourceName.c_str());      // char*型转换成c++中的string
  NullableScopedUtfChars outputName(env, javaOutputName);  // A smart pointer that provides read-only access to a Java string's UTF chars.
  if (env->ExceptionCheck()) {    // NullableScopedUtfChars的习惯用法
	return 0;
  }
  ScopedObjectAccess soa(env);    // 线程加锁
	
               .
               .
               .

  ClassLinker* linker = Runtime::Current()->GetClassLinker();    // Get ClassLinker* of current Runtime
  const DexFile* dex_file;    
  if (outputName.c_str() == NULL) {                      // 如果outputName为空,则dex_file由sourceName确定
	dex_file = linker->FindDexFileInOatFileFromDexLocation(dex_location, dex_location_checksum);                   // ②  
  } else {                                               // 如果outputName
	std::string oat_location(outputName.c_str());    
	dex_file = linker->FindOrCreateOatFileForDexLocation(dex_location, dex_location_checksum, oat_location);       // ①  
  }    
  if (dex_file == NULL) {    
	LOG(WARNING) << "Failed to open dex file: " << dex_location;    
	ThrowLocation throw_location = soa.Self()->GetCurrentLocationForThrow();    
	soa.Self()->ThrowNewExceptionF(throw_location, "Ljava/io/IOException;",    
								   "Unable to open dex file: %s", dex_location.c_str());    
	return 0;    
  }    
  return static_cast<jint>(reinterpret_cast<uintptr_t>(dex_file));    
} 

       函数位于/art/runtime/native/dalvik_system_DexFile.cc中。

       函数做的4件事:

       1.字符串类型的转换。将 javaSourceName 从jstring类转换成ScopedUtfChars类。ScopedUtfChars类的实例sourceName中的utf_chars_变量中保存着javaSourceName的信息。然后将得到的utf_chars_从char*型转换成c++中的string类型。string类实例变量dex_location中保存着javaSourceName的信息。(javaSourceName对应为一个jar/zip/dex/apk文件)

       2.NullableScopedUtfChars类的 outputName实例中的jstring mString和 const char* mUtfChars值,分别对应于javaOutputName的jstring和char*类型。

       3.得到此源文件的checksum_值。保存在dex_location_checksum中,用于对源文件进行校验。

       4.分两条支路outputName==NULL和outputName!=NULL对源文件提取dex_file的提取。


二、FindOrCreateOatFileForDexLocation

       首先,分析outputName!=NULL时的分支:

       这个分支首先调用 FindOrCreateOatFileForDexLocation(dex_location, dex_location_checksum, oat_location)方法:

const DexFile* ClassLinker::FindOrCreateOatFileForDexLocation(const std::string& dex_location,
                                                              uint32_t dex_location_checksum,
                                                              const std::string& oat_location) {
  WriterMutexLock mu(Thread::Current(), dex_lock_);   // 互锁
  return FindOrCreateOatFileForDexLocationLocked(dex_location, dex_location_checksum, oat_location);
}
       该方法位于/art/runtime/class_linker.cc中。

       函数根据源文件目录dex_location(由javaSourceName指定)产生oat文件存储到输出目录oat_location(由javaOutputName指定)中。并返回此oat文件中的DexFile文件。// ??????

       WriterMutexLock是对当前的互锁。接着调用:FindOrCreateOatFileForDexLocationLocked(dex_location, dex_location_checksum, oat_location)函数


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值