Android so库开发——使用Studio生成自己的so库(一)

一、创建Native项目

1、新建 Native 项目

1)新建项目

         选择最下面的 Native C++ 下一步即可

2)填写项目信息

 3)选择C++版本可以直接选择默认

2、下载并配置NDK及CMake

1)进入Studio 设置 SDK 设置界面

        这里选择需要的 NDK 和 CMake 版本进行下载。

2)加载 ndk

        通过 File -> Project Structure 或 点击图标进入设置界面。

         选择对应 ndk 版本。也可以在local.properties中直接添加 ndk 路径。

## This file must *NOT* be checked into Version Control Systems,
# as it contains information specific to your local configuration.
#
# Location of the SDK. This is only used by Gradle.
# For customization when using a Version Control System, please read the
# header note.
#Fri Jan 06 14:13:10 CST 2023
sdk.dir=/home/chen-xu-neu/Android/Sdk
ndk.dir=/home/chen-xu-neu/Android/Sdk/ndk/21.0.6113669

3、Native 项目结构

1)代码结构

         主要就是再 main 下增加了 cpp 文件夹以及下面的文件,这部分代码主要用来生成 so 库中代码。

2)build.gradle(app)

android {
    defaultConfig {
        // 对应创建项目时选择的 C++ 版本
        externalNativeBuild {
            cmake {
                cppFlags ''
                // 生成so库类型
                abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
            }
        }
    }
    // CMakeLists.txt 文件路径
    externalNativeBuild {
        cmake {
            path file('src/main/cpp/CMakeLists.txt')
            version '3.10.2'
        }
    }
}

3)CMakeLists.txt

# cmke版本
cmake_minimum_required(VERSION 3.10.2)

# 项目名称
project("nativetestdemo")

# 生成so库配置
add_library( # 设置库名称
        native_xiaoxu
        # 将库设置为共享库
        SHARED
        # 引入代码文件
        native-lib.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( # 指定目标库
        native_xiaoxu

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

4)native-lib.cpp

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

extern "C" JNIEXPORT jstring JNICALL
Java_com_wm_auto_nativetestdemo_MainActivity_stringFromJNI(
        JNIEnv* env,
        jobject /* this */) {
    std::string hello = "Hello XiaoXu";
    return env->NewStringUTF(hello.c_str());
}

        标准Native写法:Java_包名_类名_方法名

5)MainActivity

public class MainActivity extends AppCompatActivity {

    // 加载so库,与上面生成的库名对应
    static {
        System.loadLibrary("native_xiaoxu");
    }

    private ActivityMainBinding binding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        binding = ActivityMainBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        // Example of a call to a native method
        TextView tv = binding.sampleText;
        tv.setText(stringFromJNI());
    }

    /**
     * 添加 native 方法
     */
    public native String stringFromJNI();
}

        这样整个项目就完成了,运行项目会输出“Hello XiaoXu”,在build/intermediates/cmake/debug/obj/下就会生成对应的so库。这样最原始的so库就生成完了。

4、代码优化

so库代码优化

        在模块化开发及业务逻辑比较复杂时,将代码都写在 native-lib.cpp 中显然是不合理的,这就需要将代码抽取出来。

1)创建 .cpp 和 .h 文件

2)NativeImpl.h

#ifndef MYNATIVE_CLIENTIMPL_H
#define MYNATIVE_CLIENTIMPL_H

#include <vector>

class NativeImpl {
    public:
    NativeImpl();
    virtual ~NativeImpl();

    virtual char* getUserName();
};


#endif //MYNATIVE_CLIENTIMPL_H

3)NativeImpl.cpp

#include "NativeImpl.h"


NativeImpl::NativeImpl(){

}

NativeImpl::~NativeImpl(){

}

char* NativeImpl::getUserName(){
    // 这里处理代码逻辑
    return "XiaoXu";
}

4)CMakeLists.txt 增加 cpp 文件引入

add_library( # Sets the name of the library.
        native_xiaoxu

        # Sets the library as a shared library.
        SHARED

        # Provides a relative path to your source file(s).
        native-lib.cpp
        src/NativeImpl.cpp)

5)native-lib.cpp 增加对应方法

#include <jni.h>
#include <string>
#include "src/NativeImpl.h"

/* 获取NativeImpl */
NativeImpl nativeImpl;
NativeImpl* getNativeImpl(){
    return &nativeImpl;
}

/* 将Activity方法提取到NativeImpl中 */
extern "C" JNIEXPORT jstring JNICALL
Java_com_wm_auto_nativetestdemo_NativeImpl_getUserName(
        JNIEnv* env,
        jclass clazz) {
    char* c = getNativeImpl()->getUserName();
    return env->NewStringUTF(c);
}

so库使用优化

1)将Activity方法提取到NativeImpl中

public class NativeImpl {
    // 加载so库
    static {
        System.loadLibrary("native_xiaoxu");
    }

    /**
     * 添加 native 方法
     */
    public static native String getUserName();
}

2)Activity中使用

NativeImpl.getUserName()

项目源码

猜你喜欢

转载自blog.csdn.net/c19344881x/article/details/128575427