[置顶] Android调用JNI的简单实例(附详细步骤)
最近想调用FFmepg库来做编解码的东西,首先就得学会使用JNI(JAVA Native Interface)调用。
下面做个简单的JNI调用实例,中间遇到的问题及解决过程省略一万字,查找到的资料也都是东一句西一句的,整理一下完整的实现过程,希望对初学JNI的朋友有所帮助:
1、创建一个Android工程,名为SimpleJni;
2、在com.example.simplejni包下新建一个Jni接口类SimpleInterface,这个类不需要继承java的接口类;
package com.example.simplejni;public class SimpleInterface {public static native String sayName();}3、编译这个接口类,为c端调用的头文件。
工程目录:
命令窗口:Win+R运行cmd,cd进入到eclipse工作空间中SimpleJni工程目录,
输入javah -classpath bin/classes -d jni com.example.simplejni.SimpleInterface编译接口类
编译完成后,刷新工程,就可以看到工程中自动创建了jni文件夹,其中包含编译好的.h头文件
4、事先安装好NDT插件,右键SimpleJni工程选择Android tools下Add Native Support选项,library name使用默认的工程名;
完成后,会在jni文件夹中添加一个Android.mk文件和SimpleJni.cpp文件;
打开头文件,是不是发现JNICALL报错了,不着急,下面有解决方法。
5、然后给工程新建并配置一个Builder,能够自动生成so库在Android端代码进行调用。
①右键工程-Properties-Builders-New,在弹出对话框中点击Program。
②在Edit Configuration对话框中的Main选项卡中,添加路径;
Location中选择到NDK安装目录下的ndk-build.cmd;
WorkingDirectory中选择到SimpleJni工程目录。
③选择Refresh选项卡,在其中勾选如下
④在Build Options选项卡中勾选如下
其中Specify Resource中配置到SimpleJni工程的jni目录即可。
到此点击ok,配置完成了,相比通过命令行编译的方法,至少方便很多。
完成后,会在SimpleJni工程libs文件下自动创建armeabi文件夹并包含编译好的libSimpleJni.so库文件,当工程有所改变的时候,就会自动编译so文件;
目前的工程目录结构:
6、下面来填充SimpleJni.cpp,相信学过C++的朋友会觉得很熟悉,在这个cpp文件里面写接口的具体实现。
这里会出现JNICALL等类型无法识别等报错,需要导入一个NDK的include头文件库:
①右键工程,选择Properties -> C/C++ General -> Path and Symbols 中点击include选项卡,添加NDK安装目录下的include文件夹D:\AndroidNDK\android-ndk-r10d\platforms\android-14\arch-arm\usr\include
导入完毕之后就不会报错了
7、首先将头文件Include进来,但是要遵循方法的命名规则:Java_(固定开头)com_example_hellojni(用"_"连接的包名)_HelloJni(类名)_stringFromJNI(函数名)再从接口.h头文件中把sayName方法复制过来,并修改参数,简单的返回一个字符串。
#include <jni.h>#include <com_example_simplejni_SimpleInterface.h>JNIEXPORT jstring JNICALL Java_com_example_simplejni_SimpleInterface_sayName (JNIEnv *env, jclass){return env->NewStringUTF("I'm Eric!");}8、然后修改MainActivity.java代码,添加一个TextView并设置其文本为SayName()方法的返回值;添加static代码块,载入so库,之前右键工程add native Support的library名称就是在这里调用:
package com.example.simplejni;import android.app.Activity;import android.os.Bundle;import android.view.Menu;import android.view.MenuItem;import android.widget.TextView;public class MainActivity extends Activity {private TextView textView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);textView = (TextView) findViewById(R.id.textview_id);textView.setText(SimpleInterface.sayName());}static {System.loadLibrary("SimpleJni");}}运行SimpleJni工程,运行结果如下:
可以参考的文章:
NDK生成SO文件:http://blog.csdn.net/laczff21/article/details/7542236
Android调用JNI方法:http://www.2cto.com/kf/201409/330892.html
Android移植ffmpeg后so库的使用:http://tq09931.iteye.com/blog/1011895
还参考了很多资料,就不一一贴上来了,主要对我有帮助的就这些,另外其中遇到了很多问题,通过论坛等大牛获得解决办法。
附上Demo地址:http://download.csdn.net/detail/ericfantastic/9199871
更多相关文章
- 一款常用的 Squid 日志分析工具
- GitHub 标星 8K+!一款开源替代 ls 的工具你值得拥有!
- RHEL 6 下 DHCP+TFTP+FTP+PXE+Kickstart 实现无人值守安装
- Linux 环境下实战 Rsync 备份工具及配置 rsync+inotify 实时同步
- 总结一下各大开发板android烧写方式
- Android学习之ListView控件
- Android中preference的使用
- 教你修改eclipse创建android project时默认生成的包名
- Android(安卓)HAL的作用及编程实例