JNI学习,第一个NdkJni_demo

    为了学习JNI,先做一个小demo来练手和入门。
    再结合自己的实际情况和遇到的问题。(问题挺多的)
相关环境
  • ubuntn14.04 (64位)
  • Android studio2.1.3 
  • Jdk1.8
  • Sdk(android-23
  • Ndk(r10,android-L

JNI是什么?
    Java Native Interface (JNI)标准是java平台的一部分,它允许Java代码和其他语言写的代码进行交互。
    JNI 是本地编程接口,它使得在 Java 虚拟机 (VM) 内部运行的 Java 代码能够与用其它编程语言(如 C、C++ 和汇编语言)编写的应用程序和库进行交互操作。(抄的)

怎么调用?
    这不是一句话能说的清楚的,得写个demo。不过用一句话来讲,就是架起java和c的一座桥梁。(我就叫它jc桥梁)

提前配置
    首先把配置说一下,后面的步骤就可以一直走了。
    ndk配置:
    下载:
  • http://www.androiddevtools.cn/(需翻墙,不过有最新的r12);
  • http://blog.csdn.net/zhanghuoding/article/details/51345256(我在这下了r10的);
  • ndk环境配置跟jdk类似,解压后(我解压到/opt),在/etc/profile文件下添加ndk路径到PATH(把根目录添进去就行);
  • 需要注意的是:确保ndk目录下的platforms目录的版本跟sdk目录下的plarforms版本都对得上,这样编译不会出错;
  • 之前我的ndk为r9,最高只有19的platform,而sdk最高到24,这里被坑了好多,编译老是出错。
  • 后来改成sdk编译版本23的,因为下了一个ndk r10的版本刚好有Android-L的platform。
    相关文件配置:
  • gradle.properties文件末尾添加android.useDeprecatedNdk=true
  • local.properties文件末尾,查看时候有sdk.dir和ndk.dir出现;如果没有,通过file->project structure来设置。    

步骤简介(后边有详解)
  1.     在Android Studio先建立一个project(project名:NdkJniDemo),带有默认的MainActivity
  2.     新建一个java类(JniUtils.java,跟MainActivity同路径),在里边声明一个native函数(也可以直接在MainActivity里声明):getStringFormC()
  3.     用javah -jni 命令编译这个类,会生成一个头文件。该头文件就是jc桥梁。期间一个小问题,参考着:http://bbs.csdn.net/topics/370236601
  4.     将上一步产生的头文件复制到src/main的jni文件夹(自己新建)下。
  5.     在jni文件夹下新建一个c文件去实现头文件的函数。(这里需要ndk的环境的配置了,后面再讲)
  6.     配置app目录下的build.gradle文件,指定编译输出的so文件的文件名:NdkJniDemo
  7.     接着,在新建的java类(JniUtils.java),加入代码:static { System.loadLibrary("NdkJniDemo");//之前在build.gradle里面设置的so     名字,必须一致}
  8.     最后在MainActivity里面就可以调用了:JniUtils.getStringFormC()


步骤1详解 略

步骤2详解
  • 代码如下:
public class JniUtils {

public static native String getStringFormC();

}

步骤3详解
  • 进入下面的路径(可能版本不同略有差异),可以并找到JniUtils类:(NdkJniDemo为我的project名
NdkJniDemo/app/build/intermediates/classes/debug/com/topwise/ndkjnidemo

  • NdkJniDemo/app/build/intermediates/classes/debug目录下,打开终端,键入命令:
javah -jni com.topwise.ndkjnidemo.JniUtils

个人认为可能是找不到你的Android.jar包,把你sdk目录的platform路径配到CLASSPATH去试试。
如果还是不行,试试这个命令:【命令模板 :javah   -classpath bin/classes -bootclasspath {sdk_home}/platforms/android-xx/android.jar  -d jni com.xxx.xxxActivity】
【我的这个命令(去掉了  -classpath bin/classes)成功了:javah -bootclasspath /opt/android-sdk-linux/platforms/android-23/android.jar -d jni com.topwise.ndkjnidemo.JniUtils】

  • 如果顺利,就会得到一个头文件,在NdkJniDemo/app/build/intermediates/classes/debug目录下。我的头文件名为:com_topwise_ndkjnidemo_JniUtils.h
该头文件里面就会有一个函数:,跟JniUtils类里的函数对应。
 
步骤4详解
  • 将上一步产生的头文件复制到src/main的jni文件夹(自己新建)下。

步骤5详解
  • c文件名随便取,我的c文件名为:jctest.c
  • 然后去实现上述头文件里面的函数,添加的代码如下:
#include "com_topwise_ndkjnidemo_JniUtils.h"
/* Class: Java_com_wobiancao_ndkjnidemo_ndk_JniUtils
* Method: getStringFormC
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_topwise_ndkjnidemo_JniUtils_getStringFormC
(JNIEnv *env, jobject obj)
{
return (*env)->NewStringUTF(env,"这里是来自cstring");
}

步骤6详解
  • 注意是app目录下的build.gradle, 在android节点的defaultConfig{ ..... }里面加入:
ndk {
moduleName "NdkJniModule" //生成的so名字
abiFilters "armeabi", "armeabi-v7a", "x86" //输出指定三种abi体系结构下的so库,目前可有可无。
}

步骤7详解
  • 代码如下:
public class JniUtils {

public static native String getStringFormC();


static {
System.
loadLibrary("NdkJniModule");//之前在build.gradle里面设置的so名字,必须一致
}

}
  • 这里要注意,static{.......}语句如果放在声明函数的语句前面,会报错。(后来就没有这个问题了。我猜测static语句放哪里都可以,没报错可能是因为ndk换了r10的)

步骤8详解
  • MainActivity代码如下,(自己去布局文件添加一个id)
public class MainActivity extends AppCompatActivity {

TextView textView;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.test);
textView.setText(JniUtils.getStringFormC());
}
}
  • 结果成功,略过,真机懒得截图了哈。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值