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 平台应用创建与配置 )