Android——NDK笔记

我觉得这个也是我们Android开发者必须掌握的,所以在这里mark下,我们比较熟悉的是android的SDK开发,一般的开发中我们很少去接触NDK,其实就是我们常说的jni。已经有SDK了,为什么android支持NDK呢,google就是为了让android支持直接去调用c/c++的一些东西,我们都知道c/c++是比Java效率更高的,java是牺牲运行效率,提高编译效果,而c/c++则反之。那么SDK和NDK是什么关系呢,我直接在网上找了一张图来看下


通过上图我们可以知道NDK最终生成的是so文件,然后通过SDK去调用。下面我们就直接来写第一个NDK程序。写之前我们先来准备好环境。

我们在AS直接配置路径就好了,ctr+alt+shift+s,如下图配置!


我们来到local.properties配置下,在最后一行添加 

ndk.dir=D:\ProgramData\android-ndk-r9b,这个路径要填你自己ndk的路径。 
配置好之后,然后再src目录下的build.gradle的defaultConfig配置下

defaultConfig {
    ..........

    ndk{
        moduleName "LisnJniLibName"         //生成的so名字
        abiFilters "armeabi", "armeabi-v7a", "x86"  //输出指定三种abi体系结构下的so库。目前可有可无。
    }
}


编译出错 直接gradle.properties加一行就好了

android.useDeprecatedNdk=true

在AS中新建一个Project,然后再新建一个class为NdkJniUtils,在内部声明native方法

package com.test.lisn.my_jni;
public class NdkJniUtils {
    public native String getCLanguageString();
}



在工程主文件Activity中写入如下代码调运JNI的东西显示在UI上。

public class MainActivity extends AppCompatActivity {
    private TextView mTextView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mTextView = (TextView) this.findViewById(R.id.test);
        NdkJniUtils jni = new NdkJniUtils();
        mTextView.setText(jni.getCLanguageString());
    }
}

然后build project得到其中中间文件,我们关注的是.class文件。编译OK以后生成的class文件在AS工程的如下目录:

NDKApplication\app\build\intermediates\classes\debug

然后接下来的步骤就是根据生成的class文件,利用javah生成对应的 .h头文件。

点开AS的Terminal标签,默认进入到该项目的app文件夹下。我在windows平台下输入如下命令跳转到class中间文件生成路径:

xxxxx\app> cd build\intermediates\classes\debug

然后执行如下javah命令生成h文件。

xxxxx\debug> javah -jni com.test.lisn.my_jni.NdkJniUtils

执行完之后你可以在文件夹 my_jni/app/build/intermediates/classes/debug下看见生成的 .h头文件为:

com_test_lisn_my_jni_NdkJniUtils.h

里边内容如下:

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

#ifndef _Included_com_test_lisn_my_jni_NdkJniUtils
#define _Included_com_test_lisn_my_jni_NdkJniUtils
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_test_lisn_my_jni_NdkJniUtils
 * Method:    getCLanguageString
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_test_lisn_my_1jni_NdkJniUtils_getCLanguageString
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

在工程的main目录下新建一个名字为jni的目录,然后将刚才的 .h文件剪切过来。在jni目录下新建一个c文件,随意取名,我的叫jnitest.c 。然后编辑代码如下(后面会解释啥意思,这里重在工具使用):

<code class="language-c++ hljs scala has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"></code><pre style="font-family: Consolas; font-size: 13.5pt; background-color: rgb(190, 255, 190);"><span style="color:#808000;">#include</span><span style="color:#008000;"><strong> "com_test_lisn_my_jni_NdkJniUtils.h"
</strong></span><span style="color:#008000;"><strong>
</strong></span>JNIEXPORT jstring JNICALL Java_com_test_lisn_my_1jni_NdkJniUtils_getCLanguageString
  (JNIEnv *env, jobject obj){
  <span style="color:#000080;"><strong>return</strong></span>(*env)->NewStringUTF(env,<span style="color:#008000;"><strong>"This just a test for Android Studio NDK JNI developer!"</strong></span>);
  };
 

接下来在工程的local.properties文件中添加NDK路径(上面下载好的那个NDK),类似其中的SDK路径一样,我的添加后如下:

ndk.dir=D\:\\ProgramData\\android-ndk-r9b
sdk.dir=D\:\\ProgramData\\Android\\sdk


现在生成的so库名字也有了,那就去代码的NdkJniUtils Java文件添加静态初始化load代码,添加如下:

<code class="language-java hljs  has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> {
        System.loadLibrary(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"LisnJniLibName"</span>);   <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//defaultConfig.ndk.moduleName</span>
    }</code>

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值