在看framework层代码时,经常会看到native方法,这是往往需要查看所对应的C++方法在哪个文件,对应哪个方法?下面从一个实例出发带大家如何查看java层方法所对应的native方法位置。

实例(一)

当分析Android消息机制源码,遇到MessageQueue.java中有多个native方法,比如:

 private native void nativePollOnce(long ptr, int timeoutMillis);

步骤1:
MessageQueue.java的全限定名为android.os.MessageQueue.java,方法名:android.os.MessageQueue.nativePollOnce(),而相对应的native层方法名只是将点号替换为下划线,可得android_os_MessageQueue_nativePollOnce()。
Tips: nativePollOnce ==> android_os_MessageQueue_nativePollOnce()

步骤2:
有了native方法,那么接下来需要知道该native方法所在那个文件。Android系统启动时就已经注册了大量的JNI方法,见AndroidRuntime.cpp的gRegJNI数组。这些注册方法命令方式:

register_[包名]_[类名]

那么MessageQueue.java所定义的jni注册方法名应该是register_android_os_MessageQueue,的确存在于gRegJNI数组,说明这次JNI注册过程是有开机过程完成的。 该方法在AndroidRuntime.cpp申明为extern方法:


extern int register_android_os_MessageQueue(JNIEnv* env);

这些extern方法绝大多数位于/framework/base/core/jni/目录,大多数情况下native文件命名方式:

[包名]_[类名].cpp
[包名]_[类名].h

Tips: MessageQueue.java ==> android_os_MessageQueue.cpp

打开android_os_MessageQueue.cpp文件,搜索android_os_MessageQueue_nativePollOnce方法,这便找到了目标方法:

static void android_os_MessageQueue_nativePollOnce(JNIEnv* env, jobject obj,jlong ptr, jint timeoutMillis) {NativeMessageQueue* nativeMessageQueue = reinterpret_cast<NativeMessageQueue*>(ptr);nativeMessageQueue->pollOnce(env, obj, timeoutMillis);
}

到这里完成了一次从Java层方法搜索到所对应的C++方法的过程。

实例(二)

对于native文件命名方式,有时并非[包名]_[类名].cpp,比如Binder.java

Binder.java所对应的native文件:android_util_Binder.cpp

public static final native int getCallingPid();

根据实例(一)方式,找到getCallingPid ==> android_os_Binder_getCallingPid(),并且在AndroidRuntime.cpp中的gRegJNI数组中找到register_android_os_Binder。

按实例(一)方式则native文名应该为android_os_Binder.cpp,可是在/framework/base/core/jni/目录下找不到该文件,这是例外的情况。其实真正的文件名为android_util_Binder.cpp,这就是例外,这一点有些费劲,不明白为何google要如此打破规律的命名。

static jint android_os_Binder_getCallingPid(JNIEnv* env, jobject clazz)
{return IPCThreadState::self()->getCallingPid();
}

有人可能好奇,既然如何遇到打破常规的文件命令,怎么办?这个并不难,首先,可以尝试在/framework/base/core/jni/中搜索,对于binder.java,可以直接搜索binder关键字,其他也类似。如果这里也找不到,可以通过grep全局搜索android_os_Binder_getCallingPid这个方法在哪个文件。

实例(三)

前面两种都是在Android系统启动之初,便已经注册过JNI所对应的方法。 那么如果程序自己定义的jni方法,该如何查看jni方法所在位置呢?下面以MediaPlayer.java为例,其包名为android.media:

public class MediaPlayer{static {System.loadLibrary("media_jni");native_init();}private static native final void native_init();...
}

通过static静态代码块中System.loadLibrary方法来加载动态库,库名为media_jni, Android平台则会自动扩展成所对应的libmedia_jni.so库。 接着通过关键字native加在native_init方法之前,便可以在java层直接使用native层方法。

接下来便要查看libmedia_jni.so库定义所在文件,一般都是通过Android.mk文件定义LOCAL_MODULE:= libmedia_jni,可以采用grep或者mgrep来搜索包含libmedia_jni字段的Android.mk所在路径。

搜索可知,libmedia_jni.so位于/frameworks/base/media/jni/Android.mk。用前面实例(一)中的知识来查看相应的文件和方法名分别为:

android_media_MediaPlayer.cpp
android_media_MediaPlayer_native_init()

再然后,你会发现果然在该Android.mk所在目录/frameworks/base/media/jni/中找到android_media_MediaPlayer.cpp文件,并在文件中存在相应的方法:

static void
android_media_MediaPlayer_native_init(JNIEnv *env)
{jclass clazz;clazz = env->FindClass("android/media/MediaPlayer");fields.context = env->GetFieldID(clazz, "mNativeContext", "J");...
}

Tips:MediaPlayer.java中的native_init方法所对应的native方法位于/frameworks/base/media/jni/目录下的android_media_MediaPlayer.cpp文件中的android_media_MediaPlayer_native_init方法。

原文链接:http://gityuan.com/2016/05/28/android-jni/

欢迎关注微信公众号:DroidMind
精品内容独家发布平台


呈现与博客不一样的技术干货

如何查找native方法相关推荐

  1. JNI查找 native 方法的规则(静态、动态注册)

    转载自:JNI查找 native 方法的规则 通过上一篇文章,大家明白了调用 native 方法之前,首先要调用 System.loadLibrary 接口加载一个实现了native 方法的动态库才能 ...

  2. JNI/NDK开发指南(二)——JVM查找java native方法的规则

    转载请注明出处:http://blog.csdn.net/xyang81/article/details/41854185 通过第一篇文章,大家明白了调用native方法之前,首先要调用System. ...

  3. 【Android 内存优化】Android 原生 API 图片压缩原理 ( 图片质量压缩方法 | 查找 Java 源码中的 native 方法对应的 C++ 源码 )

    文章目录 一. 图片质量压缩方法 二. 查找对应的 Native 方法源码 三. 分析 Bitmap.cpp 中动态注册 Native 方法 在博客 [Android 内存优化]图片文件压缩 ( An ...

  4. 【Android 逆向】ART 脱壳 ( InMemoryDexClassLoader 脱壳 | DexFile 构造函数及相关调用函数 | Android 源码中查找 native 函数 )

    文章目录 一.DexFile 构造函数 二.DexFile.openInMemoryDexFile 函数 三.Android 源码中查找 native 函数 一.DexFile 构造函数 上一篇博客 ...

  5. 带你掌握不同平台下,探索JDK源码所需的native方法

    摘要:要探索JDK的核心底层源码,那必须掌握native用法.文章中会以"获取系统的默认时区"为例,介绍说明如何查看native对应方法的源码. 本文分享自华为云社区<要探索 ...

  6. JAVA中native方法调用C语言实现学习

    在java虚拟机规范的内存管理划分中,对于虚拟机内存空间划分中专门划了一块内存叫做"本地方法栈(Native Method Stack)".本地方法栈是为了java专门用来调用na ...

  7. 安卓 jni 开发之 native 方法的动态注册

    博客: 安卓之家 微博: 追风917 CSDN: 蒋朋的家 简书: 追风917 最近一直在搞 jni 开发,里面坑挺多,其实都是自己不注意导致的.如果你不知道 jni,但是你又想了解这个坑,请先到隔壁 ...

  8. java native方法使用

    一.前言 今天在看java.lang.System源码的时候看到了System静态代码块中有一个registerNatives方法,该方法是被 native关键字修饰. public final cl ...

  9. JNI调用native方法出现 java.lang.UnsatisfiedLinkError: XXXclass.XXXmethod()异常的解决办法

    JNI调用native方法出现 java.lang.UnsatisfiedLinkError: XXXclass.XXXmethod()异常的解决办法 参考文章: (1)JNI调用native方法出现 ...

  10. 【EventBus】EventBus 源码解析 ( 注册订阅者 | 订阅方法 | 查找订阅方法 )

    文章目录 一.EventBus 注册订阅者 二.订阅方法 三.查找订阅方法 findSubscriberMethods 方法 四.查找订阅方法 findUsingInfo 方法 五.查找订阅方法 fi ...

最新文章

  1. 机器学习-----有监督,无监督,半监督学习的简单阐释
  2. 性能不打折,内存占用减少90%,Facebook提出极致模型压缩方法Quant-Noise
  3. php errorcode,php中pdo错误处理方法详解
  4. ros c++ 代码说明文档_减少运维工作量,如何通过 ROS 轻松实现资源编排新方式...
  5. 数据不够,游戏来凑!随机三维人物实现可泛化的行人再辨识(ReID)
  6. 侍魂胧月传说显示服务器未开启,侍魂胧月传说打开游戏黑屏怎么办 黑屏相关问题解答...
  7. sharelatex在centos 6.7 64位上的部署(2)
  8. 产生式系统 实验报告 人工智能原理实验
  9. 有关世界上第一台计算机的知识,计算机基础知识 1、世界上第一台电子计算机诞生于 A) 1943年 B) 1946年.doc...
  10. java简历校园经历_简历校园经历如何编
  11. 学习并掌握结构化写作方法,提高写作能力 ——结构化写作学习笔记(1)
  12. 使用 163 邮箱接收 ASP.NET 用户反馈
  13. ES6基本知识及API
  14. 论文阅读三:基于改进人工蜂群算法的SDN负载均衡策略研究
  15. 码元、波特、速率、带宽(附例题)
  16. 如何快速用docker搭建npm私服
  17. 一款可编程的的串口调试工具 报文分类 脚本编程
  18. jmeter分布式环境搭建
  19. 基于C#的超市收银管理系统
  20. 阿里云本机一键登录集成

热门文章

  1. 路由器刷php,【图片】【经验分享】路由器刷DDWRT认证锐捷校园网全程实录【哈尔滨工业大学吧】_百度贴吧...
  2. 手机怎么用外嵌字幕_教你用手机给视频添加字幕,超简单,3分钟就能学会
  3. 通讯协议集合- - -类比道路交通- - -一般肯定有数据电信号线和收发控制电信号线
  4. 即时通讯工具:Output Messenger Server
  5. 三线表里加小短线_三线表的格式
  6. 转移到ios下载安卓_转移到ios下载-转移到ios app下载v2.10.0 安卓最新版-2265安卓网...
  7. echarts官网jar包下载步骤
  8. RH850 Clock+LED
  9. 鲁班学院java高级架构师_鲁班学院三期java架构师
  10. 使用VSTO开发Excel WorkBook文档级项目中出现的Bug及处理办法