安卓项目模块集成JNI的两种方式回顾

在 Android 模块中编写 JNI 模块来调用第三方的 .so 文件,可以使用 NDK Build (老项目)或 CMake 两种方式。以下是详细的操作步骤:

使用 NDK Build

1. 创建 JNI 目录结构

在你的 Android 模块中创建一个 jni 目录,并在其中创建 Android.mkApplication.mk 文件。

CppApp/
├── app/
│   ├── src/
│       ├── cpp/
│           └── jni-ndk-build/
│               ├── Android.mk
│               ├── Application.mk
│               └── native.cpp

2. 编写 Android.mk 文件

jni/Android.mk 文件中定义你的模块和第三方库:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := cppapp
LOCAL_SRC_FILES := native.cpp

#如果三方库需要被编译
#LOCAL_SHARED_LIBRARIES := third_party_lib  # 这里是你的第三方.so库名称
#include $(CLEAR_VARS)
#LOCAL_MODULE := third_party_lib
#LOCAL_SRC_FILES := libs/$(TARGET_ARCH_ABI)/libthird_party.so  # 第三方库的位置
#include $(PREBUILT_SHARED_LIBRARY)


#设置三方库的搜索路径,LOCAL_PATH:Android.mk所在位置
#THIRD_PART_LIBS_PATH := $(LOCAL_PATH)/../../jniLibs/$(TARGET_ARCH_ABI)
LOCAL_LDLIBS += -llog #(如果有三方库)-L$(THIRD_PART_LIBS_PATH) -lfmod -lfmodL
include $(BUILD_SHARED_LIBRARY)



3. 编写 Application.mk 文件

jni/Application.mk 文件中指定编译的目标架构和应用设置:

APP_PLATFORM := android-21
APP_STL := c++_shared
4. 编写你的 JNI 代码

jni/native.cpp 文件中编写你的 JNI 代码:

#include "native.h"
#include <jni.h>
#include <string>
#include <iostream>
#include <android/log.h>
#define TAG "NativeProcess"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__)

extern "C"
JNIEXPORT void JNICALL
Java_com_hfengxiang_cppapp_NativeProcess_call(JNIEnv *env, jobject thiz) {
    // TODO: implement call()
    jclass  cls = env->GetObjectClass(thiz);
    jmethodID  jmtId = env->GetMethodID(cls,"toString", "()Ljava/lang/String;");
    jstring  jstr = static_cast<jstring>(env->CallObjectMethod(thiz, jmtId));
    const char * cstr = env->GetStringUTFChars(jstr,NULL);
    LOGD("caller is %s",cstr);
}
5. 在项目中使用 JNI

在你的 build.gradle 文件中配置 NDK 支持:

android {
    ...
    externalNativeBuild {
        ndkBuild {
            path file("src/main/cpp/jni/Android.mk")
        }
    }
}

在 Java 代码中加载 JNI 库并调用本地方法:

package com.hfengxiang.cppapp;

public class NativeProcess {
    static {
        System.loadLibrary("cppapp");
    }

    public native void call();
}

package com.hfengxiang.cppapp;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        NativeProcess process = new NativeProcess();
        process.call();
    }
}

使用 CMake

1. 创建 CMake 目录结构

在你的 Android 模块中创建一个 cpp 目录,并在其中创建 CMakeLists.txt 文件和你的 JNI 代码文件:

CppApp/
├── app/
│   ├── src/
│       ├── cpp/
│           └── jni-cmake/
│               ├── Android.mk
│               ├── Application.mk
│               └── native.cpp

2. 编写 CMakeLists.txt 文件

cpp/CMakeLists.txt 文件中定义你的模块和第三方库:

cmake_minimum_required(VERSION 3.22.1)

# 指定你的本地库名
add_library( # Sets the name of the library.
        cppapp

        # Sets the library as a shared library.
        SHARED

        # Provides a relative path to your source file(s).
        native.cpp)

# 引入log库
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)

# 引入第三方库
#add_library( third_party_lib SHARED IMPORTED )
#set_target_properties( third_party_lib PROPERTIES IMPORTED_LOCATION #${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI}/libthird_party.so )
                        

# 链接库
target_link_libraries( # Specifies the target library.
        cppapp

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


3. 编写你的 JNI 代码

native.cpp 文件中编写你的 JNI 代码:

#include "native.h"
#include <jni.h>
#include <string>
#include <iostream>
#include <android/log.h>
#define TAG "NativeProcess"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__)

extern "C"
JNIEXPORT void JNICALL
Java_com_hfengxiang_cppapp_NativeProcess_call(JNIEnv *env, jobject thiz) {
    // TODO: implement call()
    jclass  cls = env->GetObjectClass(thiz);
    jmethodID  jmtId = env->GetMethodID(cls,"toString", "()Ljava/lang/String;");
    jstring  jstr = static_cast<jstring>(env->CallObjectMethod(thiz, jmtId));
    const char * cstr = env->GetStringUTFChars(jstr,NULL);
    LOGD("caller is %s",cstr);
}
4. 在项目中使用 JNI

在项目下的 build.gradle 文件中配置 CMake 支持:

android {
    ...
    externalNativeBuild {
        cmake {
            path file("src/main/cpp/jni-cmake/CMakeLists.txt")
        }
    }
}

 在 Java 代码中加载 JNI 库并调用本地方法:

package com.hfengxiang.cppapp;

public class NativeProcess {
    static {
        System.loadLibrary("cppapp");
    }

    public native void call();
}

package com.hfengxiang.cppapp;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        NativeProcess process = new NativeProcess();
        process.call();
    }
}

附头文件生产方式

1. 配置JDK环境变量

2.执行命令

javac -h E:\WorkSpace\Projects\CppApp\app\src\main\java\com\hfengxiang\cppapp -encoding utf-8 E:\WorkSpace\Projects\CppApp\app\src\main\java\com\hfengxiang\cppapp\NativeProcess.java

(jdk1.8以及之前的版本用javah)

3.配置自定义命名

Program:D:\Program Files (x86)\Develop\AndroidStdio\android-studio-2023.3.1.18-windows\jbr\bin\javac.exe(javac命令所在位置)
Arguments:-h $FileDir$ -encoding utf-8 $FilePath$(命令参数)
Working directory:D:\Program Files (x86)\Develop\AndroidStdio\android-studio-2023.3.1.18-windows\jbr\bin (暂不清楚含义)

 com_hfengxiang_cppapp_NativeProcess.h(可重命名)


#ifndef _Included_com_hfengxiang_cppapp_NativeProcess
#define _Included_com_hfengxiang_cppapp_NativeProcess
#ifdef __cplusplus

/*
 * Class:     com_hfengxiang_cppapp_NativeProcess
 * Method:    call
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_hfengxiang_cppapp_NativeProcess_call
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

Demo下载地址

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值