A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 武汉分校-小舞 黑马粉丝团   /  2017-8-17 14:59  /  1059 人查看  /  1 人回复  /   1 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 武汉分校-小舞 于 2017-8-17 15:10 编辑

今天看了一些博客写的关于ndk开发的,要么太老,要么太复杂。我就把我知道的简单一点方式的分享给大家。
##一:环境配置:
首先下载好NDK,网上一堆,自己找。
然后在AndroidStudio中配置好NDK,如下图:

![ndk环境配置.png](?imageMogr2/auto-orient/strip%7CimageView2/2/w/600)
再配置好NDK环境变量,配置好之后在黑窗口测试一把,出现如下界面就已经可用了
![环境变量演示.png](?imageMogr2/auto-orient/strip%7CimageView2/2/w/600)
##二:开发流程
####1、新建一个module或者使用工程中的app。
####2、在app中的MainActivity里面写如下代码(这行代码你愿意写在哪都行,也可以自己新建一个类里面写这行代码):
```
public native String getStringFromJNI(); //方法名随意,你开心就好。
```
####3、打开AS中的Terminal,然后输入如下命令:
```
cd app/src/main/java  //切换到该目录下

javah -jni com.example.demo.MainActivity //后面就是你所写的native方法所在类的全路径
```
这样你就能在你所写native方法所在类的同级目录下拿到一个.h文件。

![h文件所在目录.png](?imageMogr2/auto-orient/strip%7CimageView2/2/w/600)
打开这个.h文件看到如下信息:

![h文件内容.png](?imageMogr2/auto-orient/strip%7CimageView2/2/w/600)
其中有用的就是这行代码:
```
JNIEXPORT jstring JNICALL Java_com_example_demo_MainActivity_getJNIString
(JNIEnv *, jobject);
```
接下来我们需要根据这行代码写c文件。
####4、写C文件
首先在app目录下也就是libs文件夹同级目录下建一个文件夹jni(这个文件夹你可以建在任意位置,但是他会在再成一个libs文件夹来存放编译出来的so文件,放在同级目录下就会直接生成到app中的libs文件夹里面,大家可以试试)。
然后在jni文件夹下面建一个.c文件,文件名随意。


![新建c文件.png](?imageMogr2/auto-orient/strip%7CimageView2/2/w/600)

![新建c文件_1.png](?imageMogr2/auto-orient/strip%7CimageView2/2/w/600)
创建好c文件例如jnidemo.c 在这个文件中加入如下代码:
```
#include <jni.h>
JNIEXPORT jstring JNICALLJava_com_example_administrator_ndkapp_MainActivity_getCString
(JNIEnv *env, jobject obj){
return (*env)->NewStringUTF(env, "这是jni传给我的");
  }
```
细心的朋友就发现了,这里面写的是不是就是之前的.h文件生成的那些东西,只不过是帮他实现了,.h知识相当于调用,这里是具体实现类。
ps:不要问我代码什么意思,这样写就完了。这只是一个小入门demo,正真开发中会让你写C?
####5、创建Android.mk文件
还是在jni目录下,创建Android.mk文件,改文件中写进如下代码:
```
LOCAL_PATH := $(call my-dir)  //固定写法,不要纠结
include $(CLEAR_VARS)          //固定写法,不要纠结
LOCAL_MODULE:=jnidemo     //这里是你马上要生成的so文件的名字,系统会默认在这个名字之前加一个lib
LOCAL_SRC_FILES :=jnidemo.c     //这个就是你刚才写的那个c文件的名字
include $(BUILD_SHARED_LIBRARY)    //固定写法,不要纠结
```
####6、开始生成so文件
打开Terminal,输入:
```
cd app        //切换到jni所在目录上一级
ndk-build
```
如果不出意外你就会开到lib中的so文件了。
####7、如果仅仅这样写就只是生成了一种armeabi的so文件这不能满足我们的需求我们需要兼容各种类型

![libs.png](?imageMogr2/auto-orient/strip%7CimageView2/2/w/600)
其实只需要一步就完成了,相教与之前在build.gradle中配置,这样写也很简单。
我们只需要在建一个Application.mk文件就好了,在其中配置如下代码。
```
APP_ABI := all   //这样就能生成所有类型的so了,如果需要指定也可以如:
//APP_ABI := armeabi x86
```
然后在进行一次第6步的操作就ok了。

###三:调用so中的方法
有了so文件之后,就可以调用自己写的native方法了,虽然这个方法还是红的,但是不影响运行。调用步骤如下
####1、在app目录下的gradle中android节点下配置如下信息:
```
sourceSets{
       main{
           jniLibs.srcDirs=['libs']
       }

    }
```
####2、在初始化中加载so文件,我是在Activity中加入静态代码块如下:
```
static{
       System.loadLibrary("jnidemo"); //引号中的内容,是你在Android.mk指定的so文件的名字,不是libjnidemo哦。
    }
```
然后就可以开始调用这个方法咯!

1 个回复

倒序浏览
多谢分享
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马