Android之NDK开发初体验

个人博客地址 http://dandanlove.com/

记得前年开始自己在项目中使用第三方so库的时候就接触NDK编程开发了,只不过哪个时候自己是输出了"Hello Wrold~!"。如今一年多的时间过去了,回头拾起之前的代码再次翻看。

概念

在阅读文章之前我们首先了解几个概念

JNI

JNI是Java语言提供的Java和C/C++相互沟通的机制,Java可以通过JNI调用本地的C/C++代码,本地的C/C++的代码也可以调用java代码。JNI 是本地编程接口,Java和C/C++互相通过的接口。Java通过C/C++使用本地的代码的一个关键性原因在于C/C++代码的高效性。

NDK

NDK是一系列工具的集合。它提供了一系列的工具,帮助开发者快速开发C(或C++)的动态库,并能自动将so和java应用一起打包成apk。这些工具对开发者的帮助是巨大的。它集成了交叉编译器,并提供了相应的mk文件隔离CPU、平台、ABI等差异,开发人员只需要简单修改mk文件(指出“哪些文件需要编译”、“编译特性要求”等),就可以创建出so。它可以自动地将so和Java应用一起打包,极大地减轻了开发人员的打包工作。

ARM

早起Android只支持ARMv5的CPU架构,而发展到现在,支持一下7种架构:


arm.jpg

世界在进步,cup在arm基础上不断升级优化。每种架构关联着一种ABI(application binary interface应用程序二进制接口),所以每一种架构都对应一个.so文件,但都兼容arm。对于我们Android开发者来说,我们的app需要能在大多数手机上运行。所以要么我们所有arm类型都兼容,要么只兼容armeabi。兼容所有CPU架构类型是在性能上比较好,但是同时它也造成了apk体积的剧增(PS:我们之前的项目因为接入so库后导致apk体积剧增,最后只支持armeabi一种类型了)。

搭建环境

Java环境配置(略)

AndroidSDK环境配置(略)

NDK环境配置

本文主要讲述NDK环境配置:

  • 下载对应操作系统的NDK
  • 解压文件(windows随意解压,Ubuntu解压在bin目录下)
  • windows环境下配置


    windows-ndk.jpg
  • Ubuntu环境下配置
    修改系统环境变量
    sudo gedit /etc/profile
    在profile文件下面添加,保存并退出
    export ANDROID_NDK= ndk路径
    export PATH=$ANDROID_NDK:$PATH
    source /etc/profile

查看是否配置成功

im@58user:~/StudioProjects/NDKDemo/app/src/main/java$ ndk-build -v
GNU Make 3.81
Copyright (C) 2006  Free Software Foundation, Inc.
该程序为自由软件,详情可参阅版权条款。在法律允许的范围内
我们不作任何担保,这包含但不限于任何商业适售性以及针对特
定目的的适用性的担保。

 这个程序创建为 x86_64-pc-linux-gnu

Android studio环境配置

android-ndk-env-config.jpg

以上是下边使用Android studio 进行NDK开发的基础,下边我们进入真正的开发环节。

NDK开发环节

native方法的定义

为了方便,我直接将native方法定义在了Activity当中

public class MainActivity extends AppCompatActivity {
   //加载so库,libjnilib.so文件
    static {
        System.loadLibrary("jnilib");
    }
    //定义native方法
    private native String getStringForNative();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ((TextView) findViewById(R.id.text)).setText(getStringForNative());
    }
}

gradle配置

android {
    /**略**/
    defaultConfig {
        applicationId "ndk.tzx.com.ndkdemo"
        minSdkVersion 19
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
        ndk {
            //定义生成的mk文件中的model名称
            moduleName "jnilib"
        }
    }
    sourceSets {
        main {
            //引入so路径
            jni.srcDirs = ['src/main/jni']
        }
    }
   /**略**/
}

创建jni目录

new-jni.jpg

生成C++head文件

make-.c.jpg

执行完改命令会在main/jni目录下生成对应的头文件

ndk-build.cpp.jpg

native方法的实现

然后我们在main/jni目录下创建cpp文件并进行native方法的实现

  • include头问件
  • 实现方法
    这一步经常有好多人会遇到错误,只因方法名写错
edit.cpp.jpg

构建并运行出结果

arm-&-mk.jpg

上图是项目build后的结果,在app/build/intermediates/ndk/debug目录下有lib文件夹,obj文件夹和Android.mk文件。
在Android.mk这个文件当中我们定义生成so的名称,生成so对应cpp文件的路径和so输出的路径。
lib目录下我们可以看到各种类型的CPU架构下的so文件。

如果以上过程都没有问题的话,那么恭喜你整个项目就可以直接运行了。

踩坑需要一步一步来

build项目的时候遇到下边问题:

Android.mk生成问题

ndk-intergration.jpg

直接在gradle.properties文件尾部添加android.useDeprecatedNdk=true

so生成问题

Error:Execution failed for task ':app:compileDebugNdk'.
> com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process 'command '/bin/android-ndk-r13b/ndk-build.cmd'' finished with non-zero exit value 2

使用Android.md文件生成so的时候可能会遇到这样的问题:
解决办法1:

将Android.mk文件copy到jni目录下和.h与.cpp文件放在同一级目录,然后在该目录下执行ndk-build

ndk-build.jpg

这种方法也肯能报错:

Error:(15) *** Android NDK: Aborting.    .  Stop.
Android NDK: /home/im/StudioProjects/NDKDemo/app/src/main/jni/Android.mk: Cannot find module with tag 'core' in import path    
Android NDK: Are you sure your NDK_MODULE_PATH variable is properly defined ?    
Android NDK: The following directories were searched:    
Android NDK:         
make: Entering directory `/home/im/StudioProjects/NDKDemo/app/src/main/jni'
make: Leaving directory `/home/im/StudioProjects/NDKDemo/app/src/main/jni'
:app:buildNative FAILED
Error:Execution failed for task ':app:buildNative'.
> Process 'command '/bin/android-ndk-r13b/ndk-build'' finished with non-zero exit value 2

遇到这种情况,偶查了很多资料最后才解决(参见解决方法2)

解决方法2:

安装最新的ndk(_

运行问题

整个项目可以运行安装的时候是不是很爽,但是还可能遇到下边的问题:

$ adb shell am start -n "ndk.tzx.com.ndkdemo/ndk.tzx.com.ndkdemo.MainActivity" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER
Error while executing: am start -n "ndk.tzx.com.ndkdemo/ndk.tzx.com.ndkdemo.MainActivity" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER
Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] cmp=ndk.tzx.com.ndkdemo/.MainActivity }
Error type 3
Error: Activity class {ndk.tzx.com.ndkdemo/ndk.tzx.com.ndkdemo.MainActivity} does not exist.

Error while Launching activity

这问题偶也整了好久,网上大多数解释为native方法名不匹配,最后重新写cpp文件也成功解决。

心好累!~!复习之前的东西还是要当初做好笔记啊。

想阅读作者的更多文章,可以查看我 个人博客 和公共号:

振兴书城

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

推荐阅读更多精彩内容

  • Android游戏开发实践(1)之NDK与JNI开发02 承接上篇Android游戏开发实践(1)之NDK与JNI...
    AlphaGL阅读 3,744评论 0 24
  • 一、NDK产生的背景 Android平台从诞生起,就已经支持C、C++开发。众所周知,Android的SDK基于J...
    Ten_Minutes阅读 3,487评论 1 27
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,815评论 25 707
  • 神农尝草识黄花,世代栽培品质佳。 大嫂采收头滴汗,幺姑翻晒面飞霞。 观光赏景游人醉,摄影题诗骚客夸。 补脑养颜纯绿...
    艾思阅读 2,195评论 6 6
  • 所有的故事,都有个结局。但幸运的是,我们的生活中,每个结局都会变成一个新的开始。 如果有一天,我变得没心没肺,请记...
    5star阅读 675评论 0 0