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端调用的头文件。

工程目录:

Android调用JNI的简单实例(附详细步骤)_第1张图片

命令窗口:Win+R运行cmd,cd进入到eclipse工作空间中SimpleJni工程目录

输入javah -classpath bin/classes -d jni com.example.simplejni.SimpleInterface编译接口类

Android调用JNI的简单实例(附详细步骤)_第2张图片

编译完成后,刷新工程,就可以看到工程中自动创建了jni文件夹,其中包含编译好的.h头文件

Android调用JNI的简单实例(附详细步骤)_第3张图片

4、事先安装好NDT插件,右键SimpleJni工程选择Android tools下Add Native Support选项,library name使用默认的工程名;

Android调用JNI的简单实例(附详细步骤)_第4张图片

完成后,会在jni文件夹中添加一个Android.mk文件和SimpleJni.cpp文件;

打开头文件,是不是发现JNICALL报错了,不着急,下面有解决方法。

5、然后给工程新建并配置一个Builder,能够自动生成so库在Android端代码进行调用。

①右键工程-Properties-Builders-New,在弹出对话框中点击Program。

②在Edit Configuration对话框中的Main选项卡中,添加路径;

Location中选择到NDK安装目录下的ndk-build.cmd;

WorkingDirectory中选择到SimpleJni工程目录。

Android调用JNI的简单实例(附详细步骤)_第5张图片

③选择Refresh选项卡,在其中勾选如下

Android调用JNI的简单实例(附详细步骤)_第6张图片

④在Build Options选项卡中勾选如下

Android调用JNI的简单实例(附详细步骤)_第7张图片

其中Specify Resource中配置到SimpleJni工程的jni目录即可。

到此点击ok,配置完成了,相比通过命令行编译的方法,至少方便很多。

完成后,会在SimpleJni工程libs文件下自动创建armeabi文件夹并包含编译好的libSimpleJni.so库文件,当工程有所改变的时候,就会自动编译so文件;

目前的工程目录结构:

Android调用JNI的简单实例(附详细步骤)_第8张图片

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

Android调用JNI的简单实例(附详细步骤)_第9张图片

导入完毕之后就不会报错了

7、首先将头文件Include进来,但是要遵循方法的命名规则:Java_(固定开头)com_example_hellojni(用"_"连接的包名)_HelloJni(类名)_stringFromJNI(函数名) 再从接口.h头文件中把sayName方法复制过来,并修改参数,简单的返回一个字符串。

#include 
#include 
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;
	@Override
	protected 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工程,运行结果如下:

Android调用JNI的简单实例(附详细步骤)_第10张图片
可以参考的文章:

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





你可能感兴趣的:(JNI&NDK)