Android Studio 2.2以上NDK开发流程

android studio从2.2版本开始支持CMake的方式来搭建NDK项目,在这个版本下NDK的开发流程大概分为环境配置、本地方法与头文件生成、C/C++程序编写、本地方法调用这几个步骤。

环境配置

1.NDK下载

在Android Studio界面,选择File→settings,然后找到android SDK→SDK Tools,在这个页面下可以下载NDK。


NDK下载.png

要为应用编译和调试原生代码需要以下组件:
1.Android 原生开发工具包 (NDK):这套工具集允许您为 Android 使用 C 和 C++ 代码,并提供众多平台库,让您可以管理原生 Activity 和访问物理设备组件,例如传感器和触摸输入。
2.CMake:一款外部构建工具,可与 Gradle 搭配使用来构建原生库。如果您只计划使用 ndk-build,则不需要此组件。
3.LLDB:一种调试程序,Android Studio 使用它来调试原生代码。
这里把上述三个都下载。

2.Android Studio创建工程时自动生成C/C++项目目录

创建项目.png

在创建项目时,在New Project界面中,我们要把Include C++ support选中,然后Next,直到Customize C++ Support界面。


自定义选项.png

我们可以使用下列选项自定义项目:
1.C++ Standard:使用下拉列表选择您希望使用哪种 C++ 标准。选择 Toolchain Default 会使用默认的 CMake 设置,这里我们选择C++ 11。
2.Exceptions Support:如果您希望启用对 C++ 异常处理的支持,请选中此复选框。如果启用此复选框,Android Studio 会将 -fexceptions 标志添加到模块级 build.gradle 文件的 cppFlags 中,Gradle 会将其传递到 CMake,我们选中。
3.Runtime Type Information Support:如果您希望支持 RTTI,请选中此复选框。如果启用此复选框,Android Studio 会将 -frtti 标志添加到模块级 build.gradle 文件的 cppFlags 中,Gradle 会将其传递到 CMake,我们选中。
然后我们点Finish,创建好的项目目录如下:


项目目录.png

我们可以看到,比以前创建的项目多出两个目录,其中cpp目录存放的是C/C++的头文件如native-lib.cpp,External Build Files用于存放CMake脚本文件。
gradle.png

gradle多出了两个externalNativeBuile标签,第一个标签包含我们在创建项目选中的C++标准,异常支持和RTTI支持这三个标签。第二个标签包含cmake的脚本路径。

我们需要再gradle中的android{defaultConfig{}}中添加ndk支持的平台,比如:

    defaultConfig {
       ...
          externalNativeBuild {
            cmake {
                cppFlags "-std=c++11 -frtti -fexceptions"
            }
        }
        ndk{
            abiFilters "armeabi"
        }
    }

我们再来看看CMakeLists.txt:


cmakeLists.png

原本项目生成的cmakeLists.txt有很多注释,上图为删减之后的结果。

本地方法与头文件生成

接下来我们要做的是创建本地方法和生成对应头文件。我们还是以最简单的HelloWorld为例,新建类文件HelloWorld:

public class HelloWorld {
    static {
        System.loadLibrary("HelloWorld");
    }
    public native String getHelloWorldFromJNI();
}

然后选择Build→Make Project,这时会在project视图下的app/build/intermediates/debug生成类编译文件。然后我们需要在命令行生成HelloWorld头文件。


build.png

在命令行里面定位到debug目录下:

cd app/build/intermediates/classes/debug

然后用javah编译类文件:

javah -jni com.example.caixunwei.ndktest.HelloWorld

这里有两点需要注意:
一是:如果在HelloWorld.java中import了其他类,则需要-classpath <path>参数设定加载类的路径,比如说我现在的项目应该设置为

set classpath=C:\android\workspace\NDKTest\app\src\main\java

然后再生成.h文件

javah -jni com.example.caixunwei.ndktest.HelloWorld

否则,会提示无法加载类之类的错误

二是:如果提示没有找到javah之类的,需要把jdk的bin地址添加到环境路径path中。
接着在当前debug目录下会生成头文件,生成的头文件com_example_caixunwei_ndktest_HelloWorld.h如下:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_example_caixunwei_ndktest_HelloWorld */

#ifndef _Included_com_example_caixunwei_ndktest_HelloWorld
#define _Included_com_example_caixunwei_ndktest_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_example_caixunwei_ndktest_HelloWorld
 * Method:    getHelloWorldFromJNI
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_example_caixunwei_ndktest_HelloWorld_getHelloWorldFromJNI (JNIEnv , jobject )

#ifdef __cplusplus
}
#endif
#endif

如头文件第一段代码所说,我们不要编辑这个文件,而应该新建一个HelloWorld.cpp文件,把com_example_caixunwei_ndktest_HelloWorld.h的代码复制到HelloWorld.cpp文件里面,然后在HelloWorld.cpp中编写代码。
在cpp目录下新建HelloWorld.cpp文件,这时Android Studio会提示this is not a part of project,我们还需要在CMake脚本文件中将要新建的HelloWorld.cpp相关信息添加进去。
在CMakeLists.txt中添加:

add_library(HelloWorld
            SHARED
            src/main/cpp/HelloWorld.cpp )
            
target_link_libraries(HelloWorld
                      ${log-lib} )

形式跟自动生成的十分相似,需要其他连接库还可以继续在target_link_libraries里面添加,然后点击Sync Now。此时在Android视图下cpp目录会自动生成HelloWorld的库目录。


cpp.png

然后将com_example_caixunwei_ndktest_HelloWord.h的代码复制进来,现在我们就可以编写逻辑代码了。

C/C++代码编写

JNIEXPORT jstring JNICALL Java_com_example_caixunwei_ndktest_HelloWorld_getHelloWorldFromJNI
        (JNIEnv *env, jobject obj){
    return env->NewStringUTF("HelloWorld!");
};

这里的逻辑代码很简单,只是在JNI环境下创建了一个字符串“HelloWorld!”然后返回。把生成的头文件的代码复制过来之后记得在命令行输入exit结束占用。

本地方法调用

调用该方法的结果如下:


result.jpg

完整的MainActivity的代码:

public class MainActivity extends AppCompatActivity {
    private Button button;
    private TextView text;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        button = (Button)findViewById(R.id.button);
        text = (TextView)findViewById(R.id.textView);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                text.setText(new HelloWorld().getHelloWorldFromJNI());
            }
        });
    }

}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270

推荐阅读更多精彩内容