NO.2 Android Studio NDK开发全攻略

读完本章,你可以:

  • 在Android Studio上轻松搭建NDK开发环境。
  • 掌握最快捷的JNI开发方式。
  • 掌握使用.so文件开发Android程序的技巧。

一、 NDK环境搭建

  1. 开发工具准备
    要进行Android NDK开发,首先要下载Android NDK开发工具。可以在AndroidStudio上面下载,也可以自己下载好了,然后将NDK的路径设置为自己下载的Android NDK开发工具的路径。


    Android Studio中设置NDK路径
  2. Gradle的相关配置
  1. 我们来配置Project的build.gradle。
/*gradle插件不支持NDK,我们需要使用gradle-experimental插件。 */
 dependencies {
        classpath 'com.android.tools.build:gradle-experimental:0.7.0'
    }  
  1. 我们来配置Module的build.gradle。
apply plugin: 'com.android.model.application'
model {
    android {
        compileSdkVersion = 23
        buildToolsVersion = "23.0.2"
        defaultConfig {
            applicationId "com.lavor.ndklearning"
            minSdkVersion.apiLevel 15
            targetSdkVersion.apiLevel 23
            versionCode 4
            versionName "1.0.1"
        }
    }
    android.ndk {
        moduleName "lavor"
        ldLibs.addAll(['log'])
        cppFlags.add("-std=c++11")
        cppFlags.add("-fexceptions")
        platformVersion 15
        stl 'gnustl_shared'
    }
    android.buildTypes {
        release {
            minifyEnabled = false
            proguardFiles.add(file("proguard-rules.txt"))
        }
    }
}
dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:23.1.1'
    compile 'com.android.support:recyclerview-v7:23.1.1'
    compile 'com.android.support:design:23.1.1'
}  

小提示

  • 首先,在apply的时候我们引入的插件名称由'com.android.application'变成了'com.android.model.application'。
  • 其次,在原来android的外层加入了一个model层次。
  • 再次,原来在android的里面的块,除了defaultConfig外,全部移除android块放入model块中与android并列,并且前面的名字加上android.。
  • 然后,compileSdkVersion 23与 buildToolsVersion "23.0.2"改成 compileSdkVersion = 23和 buildToolsVersion = "23.0.2",中间加上了=。
  • 其次,添加上android.ndk块,块中的moduleName表示C/C++代码打包成so文件的名字。
  • 再次,android.buildTypes块中的proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'改成proguardFiles.add(file("proguard-rules.txt"))。
  • 最后,注意dependencies块依然在最外层,它不在model块中。

二、 使用NDK开发第一个JNI程序

  1. 在Android程序中新建一个包含native(本地)方法的NDKTest类。
package com.lavor.ndklearning;
public class NDKTest {
            static {
                //加载.so库文件
                System.loadLibrary("lavor");
            }
            public native String getString();
}

小知识

  • 程序中static{}称为静态代码块,它在类初始化的时候执行。不懂请猛击>>
  1. 将鼠标移动到方法名getString上,然后按下Alt+Enter快捷键,弹出一些解决的方法建议,点击第一个Create Function...


    自动生成.c文件
  2. 此时会自动建立一个与java目录同级的jni目录,在jni目录自动建立一个c文件,在c文件中实现了刚才的native方法。


    .c文件
  3. 然后,稍稍修改一下.c文件中实现的native方法。
JNIEXPORT jstring JNICALL
Java_com_lavor_ndklearning_NDKTest_getString(JNIEnv *env, jobject instance) {
    // TODO
    return (*env)->NewStringUTF(env, "AndroidStudio NDK开发最佳入门实践");
}  

补充说明

  • 仔细观察可以看到c文件的方法名是遵循“Java_包名类名本地方法名”来组织的(了解到这些后,我们就可以脱离编译器的帮助,直接去写.c文件啦)。
  1. 最后在Android程序中调用JNI接口。
public class MainActivity extends Activity {
        private android.widget.TextView text;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            this.text = (TextView) findViewById(R.id.text);
            NDKTest NDK=new NDKTest();
            text.setText(NDK.getString());
        }
}

运行程序后界面如下:


运行结果

深度总结

  • 讲道理,我们在正式开发时,不会像这样子去开发。因为这样的话就会把我们的c代码也暴露了出来。这明显与JNI的安全保密机制相违背,所以,正式开发的时候,我们会使用.so文件进行全保密式的开发。

三、 使用.so文件开发Android程序

不知道大家有没有记得上一章说过,使用JNI有个好处就是安全性高,JNI部分的代码很难被反编译。这其实是要归功于.so文件。下图为.so文件的生成位置。

Android Studio中生成的.so文件位置

具体的使用步骤是怎样的呢?

  1. 新建一个Android工程,命名为:AndroidApplication。(工程名、包名、组织名任意)


    一个随意的Android工程
  2. 导入.so文件至app/libs中。


    导入.so文件至Android工程
  3. 为了能够调用libs文件夹下的.so资源,需在app的build.gradle的android节点下设置。
    sourceSets{
        main{
            jniLibs.srcDirs = ['libs']
        }
    }
  1. 新建相关类结构。
package com.lavor.ndklearning;
public class NDKTest {
            static {
                        //加载.so库文件
                System.loadLibrary("lavor");
            }
            public native String getString();
}

补充说明

  • Android端声明native code的代码需要严格按照JNI接口来组织。(也就是说,包名、类名都要和.so文件中JNI名称一致)不懂就点击这里吧>>
  1. 函数调用。
public class DemoActivity extends AppCompatActivity {
            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_demo);
                Log.d("NDK",new NDKTest().getString());
            }
}

运行结果如下:


运行结果

注意啦!此文并非原创,算是对一波优秀文章的总结吧。笔者希望通过这种方式激励自己学习,也期待可以帮到正在学习NDK的你。欢迎指出本文的BUG,共勉!!!!!


参考资料

  1. AndroidStudio NDK开发最佳入门实践
  2. 如何在Android中使用编译好的.so库
  3. Android Studio NDK及so文件开发
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念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

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,569评论 25 707
  • 一、NDK产生的背景 Android平台从诞生起,就已经支持C、C++开发。众所周知,Android的SDK基于J...
    Ten_Minutes阅读 3,398评论 1 27
  • afinalAfinal是一个android的ioc,orm框架 https://github.com/yangf...
    passiontim阅读 15,087评论 2 44
  • Android游戏开发实践(1)之NDK与JNI开发02 承接上篇Android游戏开发实践(1)之NDK与JNI...
    AlphaGL阅读 3,686评论 0 24
  • 我对自己的定位:水, 外柔内刚,水滴石穿。 我曾温柔地对待这个世界,但是是有所求的。我患病期间,有段时间念佛,参与...
    freshriver阅读 360评论 0 0