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

Posted c小旭

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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()

项目源码

以上是关于Android so库开发——使用Studio生成自己的so库的主要内容,如果未能解决你的问题,请参考以下文章

Android 逆向Android 进程注入工具开发 ( Visual Studio 开发 Android NDK 应用 | VS 自带的 Android 平台应用创建与配置 )

在android studio的apk中包含.so库[重复]

Android JNI开发二: 如何生成SO库

Android JNI开发一: 如何生成SO库

Android Studio 开发JNI应用

在 Android Studio 中使用 .so(共享对象)文件