NDK开发 (一)Hello World!

先导知识:

1.JNI是java中调用其他语言的接口(在NDK开发中也就是调用C\C++),NDK是一组帮助java调用C\C++的工具,可以将so文件和java文件一起编入apk等。

2.java运行在java虚拟机上,是跨平台的。但是C\C++是不跨平台的,根据CPU不同编译生成的so文件(动态链接库)也会不同。安卓中有7中CPU架构,通过NDK工具我们可以快速编译生成这7中各自的so文件。有些型号即使没有自己的so文件也会尝试去支持使用别的so文件,通过一个模拟层,当然这样的话性能肯定会下降,而且可能会出各种各样的问题。所以编译生成全平台的so库是很有必要的,在安装到手机上的时候会根据型号选择相应的so,其他的并不会安装。

3.NDK开发的基本流程:创建java文件,用native关键字标记要在C\C++中实现的函数。

根据java文件生成.h文件。

创建相应的C\C++文件,实现函数。

编写Android.mk和Application.mk文件指导编译过程。

编译生成so文件。

在java中调用函数。


环境搭建:

首先打开Project Structure确认下载了NDK:



在gradle.properties中加入一行,允许低版本NDK编译(不太懂):

android.useDeprecatedNdk=true

在Settings->Tools->External tools里添加两个插件,分别用于将java生成.h和编译C\C++生成so(来自博客http://blog.youkuaiyun.com/xiaoyu_93/article/details/52870395,但是原博客参数中没有编码参数,所以中文会报错编码GBK的不可映射字符




注意第二个的那个cmd地址是你自己的,其他不用变。


******************************************************************************************************************

开始编写Hello World:



1.在module的gradle中配置一个name,jni会根据这个name在这个module中找so文件,这是设为“JNI_ANDROID_TEST”。(下面会提到)否则报错找不到so文件

defaultConfig {
        applicationId "com.example.listtest"
        minSdkVersion 15
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

        ndk{
            moduleName = "JNI_ANDROID_TEST"

            //abiFilters "x86","armeabi-v7a"
            // 这里填写两个abi cpu架构,如果什么都不写,则默认支持所有平台
        }
    }


2.创建一个java类,加载so库并用native修饰要在C\C++中实现的方法:

public class JavaH {

    public static native String getPkgName();

    /**
     * 加载so库或者jni库
     */
    static {
        System.loadLibrary("JNI_ANDROID_TEST");
    }

}
这里加载库用到的名字对应第一步的配置。


3.在该类中右键-->External tools-->javah -jni(自定义的插件),生成.h文件。生成的头文件在cpp文件夹中,名字比较复杂,这里重命名为jnitest.h。

4.在cpp下创建jnitest.cpp并编写:

#include <jni.h>
#include <stdio.h>
#include <stdlib.h>
#include "jnitest.h"

JNIEXPORT jstring JNICALL Java_com_example_listtest_tool_JavaH_getPkgName
        (JNIEnv * env, jclass clazz){
    return env->NewStringUTF("HelloWorld! I am from JNI !");
}
可以看到,就是引入了jnitest.h头文件然后实现了函数,函数返回Hello World。网上有些博客中的(*env)不是C++而是C的语法。


5.在cpp下创建Android.mk并编写:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := JNI_ANDROID_TEST
LOCAL_SRC_FILES := jnitest.cpp
include $(BUILD_SHARED_LIBRARY)
下面的四行是一个module的mk,有价值的就是JNI_ANDROID_TEST和jnitest.cpp,指出编译的模块和要编译的文件。


6.在cpp下创建Application.mk并编写:

APP_ABI := all
含义很简单,就是支持全平台。


7.cpp文件中右键-->External tools-->ndk build编译生成so文件,可以把视角调到Project看到:


8.在java中调用该函数即可:

Button button= (Button) findViewById(R.id.btn);
button.setText(JavaH.getPkgName());






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值