【我的Android进阶之旅】Android调用JNI出错 java.lang.UnsatisfiedLinkError: No implementation found for的解决方法
来源:互联网 发布:三好街专业数据恢复 编辑:程序博客网 时间:2024/05/20 06:27
错误描述
今天使用第三方的so库时候,调用JNI方法时出现了错误。报错如下所示:
11-01 16:39:20.979 4669-4669/com.netease.xtc.cloudmusic E/art: No implementation found for void com.netease.xtc.cloudmusic.utils.NeteaseMusicUtils.nativeInit(android.content.Context) (tried Java_com_netease_xtc_cloudmusic_utils_NeteaseMusicUtils_nativeInit and Java_com_netease_xtc_cloudmusic_utils_NeteaseMusicUtils_nativeInit__Landroid_content_Context_2)11-01 16:39:20.980 4669-4669/com.netease.xtc.cloudmusic D/AndroidRuntime: Shutting down VM11-01 16:39:20.984 4669-4669/com.netease.xtc.cloudmusic E/AndroidRuntime: FATAL EXCEPTION: main Process: com.netease.xtc.cloudmusic, PID: 4669 java.lang.UnsatisfiedLinkError: No implementation found for void com.netease.xtc.cloudmusic.utils.NeteaseMusicUtils.nativeInit(android.content.Context) (tried Java_com_netease_xtc_cloudmusic_utils_NeteaseMusicUtils_nativeInit and Java_com_netease_xtc_cloudmusic_utils_NeteaseMusicUtils_nativeInit__Landroid_content_Context_2) at com.netease.xtc.cloudmusic.utils.NeteaseMusicUtils.nativeInit(Native Method) at com.netease.xtc.cloudmusic.utils.NeteaseMusicUtils.<clinit>(NeteaseMusicUtils.java:11) at com.netease.xtc.cloudmusic.MainActivity$1.onClick(MainActivity.java:26) at android.view.View.performClick(View.java:5277) at android.view.View$PerformClick.run(View.java:21704) at android.os.Handler.handleCallback(Handler.java:815) at android.os.Handler.dispatchMessage(Handler.java:104) at android.os.Looper.loop(Looper.java:207) at android.app.ActivityThread.main(ActivityThread.java:5905) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:888) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:749)
在MainActivity中,尝试调用NeteaseMusicUtils类封装好的JNI方法,代码如下所示:
package com.netease.xtc.cloudmusic;import android.os.Bundle;import android.support.design.widget.FloatingActionButton;import android.support.design.widget.Snackbar;import android.support.v7.app.AppCompatActivity;import android.support.v7.widget.Toolbar;import android.view.View;import com.netease.xtc.cloudmusic.utils.NeteaseMusicUtils;public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); fab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { String params = NeteaseMusicUtils.getUrlParameters("/search","{\"keyword\":\"周杰伦\",\"limit\":10,\"offset\":0}"); Snackbar.make(view, "params = " + params , Snackbar.LENGTH_LONG) .setAction("Action", null).show(); } }); }}
而com.netease.xtc.cloudmusic.utils.NeteaseMusicUtils代码如下:
package com.netease.xtc.cloudmusic.utils;import android.content.Context;import com.netease.xtc.cloudmusic.app.NeteaseMusicApplication;public class NeteaseMusicUtils { static { //加载库文件 System.loadLibrary("poison"); nativeInit(NeteaseMusicApplication.getContext()); } /** * 初始化,必须 * @param context */ public native static void nativeInit(Context context); /** * 获取请求中"params"的值 * 例:如果调用搜索接口,搜索keyword=周杰伦 limit=10 offset=0 * params=getUrlParameters("/search","{\"keyword\":\"周杰伦\",\"limit\":10,\"offset\":0}\") * @param requestUri 接口说明中的uri * @param paramJson 接口说明中的参数json表达,如果为空请传"{}" * @return */ public native static String getUrlParameters(String requestUri, String paramJson);}
其中so库位置如下所示:
错误分析
再一次查看下错误日志,如下所示:
11-01 16:47:53.363 11117-11117/com.netease.xtc.cloudmusic E/art: No implementation found for void com.netease.xtc.cloudmusic.utils.NeteaseMusicUtils.nativeInit(android.content.Context) (tried Java_com_netease_xtc_cloudmusic_utils_NeteaseMusicUtils_nativeInit and Java_com_netease_xtc_cloudmusic_utils_NeteaseMusicUtils_nativeInit__Landroid_content_Context_2)11-01 16:47:53.364 11117-11117/com.netease.xtc.cloudmusic D/AndroidRuntime: Shutting down VM11-01 16:47:53.365 11117-11131/com.netease.xtc.cloudmusic I/[MALI][Gralloc]: [+]r_hnd(0xf24b3960), client(36), share_fd(44)11-01 16:47:53.373 11117-11117/com.netease.xtc.cloudmusic E/AndroidRuntime: FATAL EXCEPTION: main Process: com.netease.xtc.cloudmusic, PID: 11117 java.lang.UnsatisfiedLinkError: No implementation found for void com.netease.xtc.cloudmusic.utils.NeteaseMusicUtils.nativeInit(android.content.Context) (tried Java_com_netease_xtc_cloudmusic_utils_NeteaseMusicUtils_nativeInit and Java_com_netease_xtc_cloudmusic_utils_NeteaseMusicUtils_nativeInit__Landroid_content_Context_2) at com.netease.xtc.cloudmusic.utils.NeteaseMusicUtils.nativeInit(Native Method) at com.netease.xtc.cloudmusic.utils.NeteaseMusicUtils.<clinit>(NeteaseMusicUtils.java:11) at com.netease.xtc.cloudmusic.MainActivity$1.onClick(MainActivity.java:26) at android.view.View.performClick(View.java:5277) at android.view.View$PerformClick.run(View.java:21704) at android.os.Handler.handleCallback(Handler.java:815) at android.os.Handler.dispatchMessage(Handler.java:104) at android.os.Looper.loop(Looper.java:207) at android.app.ActivityThread.main(ActivityThread.java:5905) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:888) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:749)
错误日志提示我们没有 Java_com_netease_xtc_cloudmusic_utils_NeteaseMusicUtils_nativeInit 方法的实现,如下所示:
java.lang.UnsatisfiedLinkError: No implementation found for void com.netease.xtc.cloudmusic.utils.NeteaseMusicUtils.nativeInit(android.content.Context) (tried Java_com_netease_xtc_cloudmusic_utils_NeteaseMusicUtils_nativeInit and Java_com_netease_xtc_cloudmusic_utils_NeteaseMusicUtils_nativeInit__Landroid_content_Context_2)
然后我去咨询了一下第三方提供so库的工作人员,回复说NeteaseMusicUtils类的包名一定要是com.netease.cloudmusic.utils。原因是JNI接口Java_com_netease_xtc_cloudmusic_utils_NeteaseMusicUtils_nativeInit中,com.netease.xtc.cloudmusic.utils代表的是package name,NeteaseMusicUtils则是class name。
而第三方提供so库的工作人员的c文件的定义JNI接口为Java_com_netease_cloudmusic_utils_NeteaseMusicUtils_nativeInit,即:package name必须为:com.netease.cloudmusic.utils,而class name必须为 NeteaseMusicUtils。
也就是说,我们.so中函数声明涉及到的package name和class name与调用它的package name和class name不符。因此我们要改变我们工程中的package name和class name。使其与.so文件中函数签名提示的一致,在这个类中加入native方法的声明。
错误解决方法
好吧,我新建一个包名为com.netease.cloudmusic.utils,并把NeteaseMusicUtils类移到该包名地下。
未移动NeteaseMusicUtils到com.netease.cloudmusic.utils包之前
移动NeteaseMusicUtils到com.netease.cloudmusic.utils包之后
然后重新编译,成功运行。
JNI的命名规则
这里顺便说一下JNI的命名规则,对于传统的JNI编程来说,JNI方法跟Java类方法的名称之间有一定的对应关系,要遵循一定的命名规则,如下所示:
- 前缀: Java_
- 类的全限定名,用下划线进行分隔(_):com_oyp_jni_JniTest
- 方法名:getTestString
- JNI函数指定第一个参数: JNIEnv *
- JNI函数指定第二个参数: jobject
- 实际Java参数: jstring, jint ….
所以对于在Java类 com.oyp.jni.JniTest类的一个方法:
public native String getTestString (String oyp);
其对应的jni层的方法如下:
jstring Java_com_oyp_jni_JniTest_getTestString(JNIEnv * e, jobject clazz, jstring oyp);
如果不这样命名,当把动态库加载进DVM的时候,通过JNIEnv *指针去查找Java Native方法对应的JNI方法的时候,就会找不到了。
注意,我们也可以利用函数注册的方法,将Java层的方法名跟JNI层的方法名的对应关系保存起来,注册到DVM中,就不需要这样的命名规范了。
JNI 数据类型
我们知道Java的数据类型是跟C/C++的数据类型是不一样的,而JNI是处于Java和Native本地库(大部分是用C/C++写的)中间的一层,JNI对于两种不同的数据类型之间必须做一种转换,所以在JNI跟Java之间就会有数据类型的对应关系。 在JNI中,提供了以下各种数据类型,可以分为原生类型和引用类型: 对于原生类型有:jchar, jbyte, jshort, jint, jlong, jfloat, jdouble, jboolean,其与java端的数据类型对应如下表:
对于引用类型则有:jobject, jstring, jthrowable, jclass, jarray, 以及继承于jarray,对应于其原生类型的8种jarray和jobjectarray。
作者:欧阳鹏 欢迎转载,与人分享是进步的源泉!
转载请保留原文地址:http://blog.csdn.net/ouyang_peng/article/details/52973274
- 【我的Android进阶之旅】Android调用JNI出错 java.lang.UnsatisfiedLinkError: No implementation found for的解决方法
- Android调用JNI出错 java.lang.UnsatisfiedLinkError: No implementation found for的解决方法
- Android调用JNI出错 java.lang.UnsatisfiedLinkError: No implementation found for的解决方法
- NDK .so Android调用JNI出错 java.lang.UnsatisfiedLinkError: No implementation found for的解决方案
- 调用JNI出错 java.lang.UnsatisfiedLinkError: No implementation found for
- Android 调用.so包时报错:No implementation found for native Lxxx, java.lang.UnsatisfiedLinkError: XXX时的解决办法
- 关于android某些手机java.lang.UnsatisfiedLinkError: No implementation found for ......的问题
- Android之JNI错误:no implementation found in native -java.lang.UnsatisfiedLinkError: Native method not
- Android studio 高德sdkjava.lang.UnsatisfiedLinkError: No implementation found for long...错误的记录
- Android中java.lang.UnsatisfiedLinkError: No implementation found问题解决
- [JNI] java.lang.UnsatisfiedLinkError:Native method not found && no implementation found for native ~
- java.lang.UnsatisfiedLinkError: No implementation found for java.lang.String.....
- 百度地图java.lang.UnsatisfiedLinkError: No implementation found for int
- 调用百度地图 5.0手机报错java.lang.UnsatisfiedLinkError: No implementation found for int
- 调用百度地图5.0出现java.lang.UnsatisfiedLinkError: No implementation found for int
- 解决java.lang.UnsatisfiedLinkError: No implementation found for java.lang.String 报错的一个小方法
- java.lang.UnsatisfiedLinkError: No implementation found
- 解决:java.lang.UnsatisfiedLinkError: No implementation found
- poj 1502 MPI Maelstrom([kuangbin带你飞]专题四 最短路练习)
- 11.1模拟赛总结
- MES ROCKWELL FTPC 之 权限设计
- win 8 Mysql安装记
- 转载-精通CSS滤镜(filter)(实例解析)
- 【我的Android进阶之旅】Android调用JNI出错 java.lang.UnsatisfiedLinkError: No implementation found for的解决方法
- mysql sql-syntax-prepared-statements 变量做表名&& 字符函数
- CentOS上安装Asterisk 11
- 菜鸟的进步
- unix环境高级编程--IO
- Android事件拦截机制
- python获取当前目录下子文件夹大小 然后大到小排序 询问是否删除某些子文件夹
- 第二讲 了解html网页的结构
- javascriptDom笔记(三)