Android JNI开发入门

        又很久没写博文了,懒癌晚期,没得救了。

        这次要分享的又是全干货,想往底层方向发展的筒靴避不开药学习JNI开发,今天就从搭建环境到完成第一个demo开始带大家入门(其实我也才刚开始学JNI开发,有不对之处欢迎大家指正)。

环境搭建

(1)下载NDK、CMake等

打开Android studio的设置,然后搜索SDK,选择Android SDK

选择上图中勾选的进行下载,然后应用 

(2)配置环境变量

我这边是Mac系统,所以在.bash_profile文件内加入以下配置

export ANDROID_NDK_ROOT=/Users/你的/Library/Android/sdk/ndk/23.0.7599858
export PATH=$PATH:$ANDROID_NDK_ROOT

上面的路径就是第一步中下载NDK的路径,如果不配置这个环境变量,那你进行ndk编译时会遇到下面报错

ndk-build:command not found

注:如果不需要生成.so文件可以不配

至此,JNI开发环境搭建完成。

创建demo项目

 (1)新建Native C++项目

 这种方式创建会自动为你配置好CMake、native-lib库等;我们不采用这种方式,跟平时一样创建一个Empty Activity项目。完成之后,在main目录下心间jni文件夹,然后新建CMakeLists.txt

(2)配置CMakeLists.txt

cmake_minimum_required(VERSION 3.10.2)//最小CMake版本

# Declares and names the project.

project("jnidemo")

# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.
#定义需要编译的代码库
add_library( # Sets the name of the library.
             native-lib   //此处换成你新建的JNI库,有多个都在此添加

             # Sets the library as a shared library.
             SHARED

             # Provides a relative path to your source file(s).
        native-lib.cpp) //换成你的cpp文件

# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.

find_library( # Sets the name of the path variable.
              log-lib

              # Specifies the name of the NDK library that
              # you want CMake to locate.
              log )

# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.
#目标库
target_link_libraries( # Specifies the target library.
                       native-lib //此处换成你新建的JNi库,有多个都在此添加

                       # Links the target library to the log library
                       # included in the NDK.
                       ${log-lib} )

然后在build.gradle下做如下配置: 

android {
    ....

    defaultConfig {
        ....
        //配置CMake
        externalNativeBuild {
            cmake {
                cppFlags ""
            }
        }
    }

    //配置CMake
    externalNativeBuild {
        cmake {
            path "src/main/jni/CMakeLists.txt"
            version "3.10.2"
        }
    }

}

 (3)配置properties

 gradle.properties

#gradle:3.0.1  studio3.0 之前用
android.useDeprecatedNdk=true
#gradle:3.0.1  studio3.0 之后用
android.deprecatedNdkCompileLease=1511832698813

 local.properties

sdk.dir=/Users/你的/Library/Android/sdk
ndk.dir=/Users/你的/Library/Android/sdk/ndk

(4) 新建要编译成.h文件的java文件

public class JNIUtils {
    static {
        System.loadLibrary("JNIDemo");
    }

    public static native String stringFromJNI();
}

然后在Terminal控制台进入main目录下执行javah -d ./jni/ -classpath ./java/ -jni com.example.jnidemo.JNIUtils命令,就会在jni目录下生成JNIUtils.java的.h 头文件

(5)在jni目录下新建.c或者.cpp文件

#include <jni.h>
#include <string>
#include "com_example_jnidemo_JNIUtils.h"

extern "C" JNIEXPORT jstring JNICALL
Java_com_example_jnidemo_JNIUtils_stringFromJNI
         (JNIEnv* env,
          jclass) {
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
}

(6)在你想要调用的地方直接使用JNI接口

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        TextView tv = findViewById(R.id.sample_text);
        tv.setText(JNIUtils.stringFromJNI());
    }
}

至此,你就可以编译安装看一下效果了,不过在编译安装之前你需注释掉gradle.properties和local .properties有关ndk的配置,不然会报错的哟!!!!

生成.so文件

        这样就完事了吗?

        没有,如果其他地方需要使用,还得打包成.so文件,如何生成?在这一步的时候走了不少弯路,碰到了ndk-build命令无效,甚至不知道执行什么命令来生成.so。在网上找了不少博客,在上面的操作之后,还需要在jni目录下心间Android.mk和Application.mk文件方可生成.so.

(1) Android.mk

LOCAL_PATH := $(call my-dir) //jni目录
include $(CLEAR_VARS)
LOCAL_MODULE := JNIDemo //库名
LOCAL_SRC_FILES := JNIUtils.cpp //需要编译的文件
include $(BUILD_SHARED_LIBRARY)

 (2) Application.mk

APP_ABI := all //指定so文件的平台 ,设置为all, 代表所有平台
APP_PLATFORM := android-16
APP_STL := c++_shared //去掉会报错

 至此,就可以愉快的执行ndk-build命令了(同样在main目录下执行) 。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值