【我的Android进阶之旅】Android调用JNI出错 java.lang.UnsatisfiedLinkError: No implementation found for的解决方法
错误描述
今天使用第三方的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 VM
11-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 VM
11-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端的数据类型对应如下表:
| java | jni |
|---|---|
| char | jchar |
| byte | jbyte |
| short | jshort |
| int | jint |
| long | jlong |
| float | jfloat |
| double | jdouble |
| boolean | jboolean |
对于引用类型则有: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进阶之旅------>关于调用Webservice查询火车票时刻表的几个接口介绍
今天发现一个可以提供火车票时刻表查询的WebService,先记录下来以后如果写一个火车票时刻表查询的Android App的话就用的着.首先该WebService的的名字是TrainTimeWebS ...
- 我的Android进阶之旅------> Android为TextView组件中显示的文本添加背景色
通过上一篇文章 我的Android进阶之旅------> Android在TextView中显示图片方法 (地址:http://blog.csdn.net/ouyang_peng/article ...
- 我的Android进阶之旅------>Android疯狂连连看游戏的实现之实现游戏逻辑(五)
在上一篇<我的Android进阶之旅------>Android疯狂连连看游戏的实现之加载界面图片和实现游戏Activity(四)>中提到的两个类: GameConf:负责管理游戏的 ...
- 我的Android进阶之旅------>Android疯狂连连看游戏的实现之加载界面图片和实现游戏Activity(四)
正如在<我的Android进阶之旅------>Android疯狂连连看游戏的实现之状态数据模型(三)>一文中看到的,在AbstractBoard的代码中,当程序需要创建N个Piec ...
- 我的Android进阶之旅------>Android中AsyncTask源码分析
在我的<我的Android进阶之旅------>android异步加载图片显示,并且对图片进行缓存实例>文章中,先后使用了Handler和AsyncTask两种方式实现异步任务机制. ...
- 我的Android进阶之旅------> Android为TextView组件中显示的文本加入背景色
通过上一篇文章 我的Android进阶之旅------> Android在TextView中显示图片方法 (地址:http://blog.csdn.net/ouyang_peng/article ...
- 我的Android进阶之旅------>Android颜色值(#AARRGGBB)透明度百分比和十六进制对应关系以及计算方法
我的Android进阶之旅-->Android颜色值(RGB)所支持的四种常见形式 透明度百分比和十六进制对应关系表格 透明度 十六进制 100% FF 99% FC 98% FA 97% F7 ...
- 我的Android进阶之旅------>Android中查看应用签名信息
一.查看自己的证书签名信息 如上一篇文章<我的Android进阶之旅------>Android中制作和查看自定义的Debug版本Android签名证书>地址:http://blog ...
- 我的Android进阶之旅------>Android利用温度传感器实现带动画效果的电子温度计
要想实现带动画效果的电子温度计,需要以下几个知识点: 1.温度传感器相关知识. 2.ScaleAnimation动画相关知识,来进行水印刻度的缩放效果. 3.android:layout_weight ...
随机推荐
- nyoj 460 项链 (区间dp)
项链 时间限制:1000 ms | 内存限制:65535 KB 难度:3 描述 在Mars星球上,每个Mars人都随身佩带着一串能量项链.在项链上有N颗能量珠.能量珠是一颗有头标记与尾标记的珠子, ...
- Android Screen Monitor
实现屏幕同步前提是安装有JDK和配置好ADB的环境变量 1.官方地址 http://code.google.com/p/android-screen-monitor/ 2.解压缩得到asm.jar 3 ...
- cocos2dx错误收集
1.读取ccb文件onNodeLoaded调用两次的问题 不小心把cocosbuilder里的控件的Custom class里填了两次自定义类,如下: 结果在onNodeLoaded时调用了两次,结果 ...
- idea,eclipse创建多模块项目
新建一个maven项目 iead,新建是不选择archetype,新建好之后,pom中的 <packaging>pom</packaging>节点是默认的,如果不是要改成这这样 ...
- linux 文件夹的颜色代表什么意思
linux 文件夹的颜色代表什么意思 绿色 蓝色 黑色代表什么意思 蓝色表示目录: 绿色表示可执行文件: 红色表示压缩文件: 浅蓝色表示链接文件: 灰色表示其它文件: 红色闪烁表示链接的文件有问题了: ...
- CentOS装JDK1.8
1.下载jdk1.8:http://download.csdn.net/download/yichen01010/10017267 直接使用liunx下默认安装的浏览器 下载 2.卸载系统自带的jdk ...
- zend studio 10.6.2 字体大小 设置
如果汉化的:窗体-->常规-->外观-->颜色和字体-->基本-->文字字体 点击编辑 如果未汉化:Window->Preferences->General ...
- linux 启动jar命令
进入ECS目录jar 存放目录: 1.执行命令: linux:启动jar nohup java -jar qualityshop-api.jar>log.file 2>&1 &am ...
- Python之Seaborn
install: pip install seaborn official examples: https://seaborn.pydata.org/examples/index.html 在mac上 ...
- 第二百二十四节,jQuery EasyUI,ComboGrid(数据表格下拉框)组件
jQuery EasyUI,ComboGrid(数据表格下拉框)组件 学习要点: 1.加载方式 2.属性列表 3.方法列表 本节课重点了解 EasyUI 中 ComboGrid(数据表格下拉框)组件的 ...