Android Studio 简单生成so文件并调用「建议收藏」

Android Studio 简单生成so文件并调用「建议收藏」

大家好,又见面了,我是你们的朋友全栈君。

注意:可以直接翻到后面的## 2021年新增部分看起了,当然前面看看也挺好,哈哈。

平台:windows

IDE :Android Studio

下载好ndk:下载地址 https://developer.android.com/ndk/downloads/index.html

第1步:新建一个Android Studio 工程 JniHelloWorld。新建一个MyJni.java文件。

MyJni.java

代码语言:javascript复制public class MyJni {

static {

System.loadLibrary("MyJni");

}

public native static String getString();

}第2步:然后点击一下 make project 会在app的build目录下面生成.class文件。

第3步,在app/src/main文件夹下新建一个jni文件夹,然后打开Android Studio的终端,cd到这个目录,然后输入下面的指令

代码语言:javascript复制javah -jni -classpath D:\github\JniHelloWorld\app\build\intermediates\classes\debug com.brotherd.jnihelloworld.MyJni就会在这个jni文件夹下生成一个.h文件,com_brotherd_jnihelloworld_MyJni.h,文件内容如下。

代码语言:javascript复制/* DO NOT EDIT THIS FILE - it is machine generated */

#include

/* Header for class com_brotherd_jnihelloworld_MyJni */

#ifndef _Included_com_brotherd_jnihelloworld_MyJni

#define _Included_com_brotherd_jnihelloworld_MyJni

#ifdef __cplusplus

extern "C" {

#endif

/*

* Class: com_brotherd_jnihelloworld_MyJni

* Method: getString

* Signature: ()Ljava/lang/String;

*/

JNIEXPORT jstring JNICALL Java_com_brotherd_jnihelloworld_MyJni_getString

(JNIEnv *, jclass);

#ifdef __cplusplus

}

#endif

#endif在scr/main/jni目录下新建一个c/c++source file ,取名test.c 实现上面.h文件中的方法。

代码语言:javascript复制#include "jni.h"

#include "com_brotherd_jnihelloworld_MyJni.h"

JNIEXPORT jstring JNICALL Java_com_brotherd_jnihelloworld_MyJni_getString

(JNIEnv *env, jclass jz){

return (*env)->NewStringUTF(env,"this is the first time for me to use jni");

}接着在jni文件夹下新建Android.mk和Application.mk文件。

Android.mk

代码语言:javascript复制LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := MyJni

LOCAL_SRC_FILES := Test.c

include $(BUILD_SHARED_LIBRARY)Application.mk

代码语言:javascript复制APP_ABI := all第4步,关联下载好的ndk包,我的解压好的路径是C:\android-ndk-r14b

然后在终端进入到jni目录,输入指令 ndk-build,就会生成相应的so文件。

第5步,调用so文件。

在app的bulid文件中加入如下代码,然后build project

代码语言:javascript复制android {

...

sourceSets {

main() {

jniLibs.srcDirs = ['src/main/libs']

jni.srcDirs = [] //屏蔽掉默认的jni编译生成过程

}

}

}在MainActivity中调用

代码语言:javascript复制public class MainActivity extends AppCompatActivity {

private TextView textView;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

textView = (TextView) findViewById(R.id.textView);

textView.setText(MyJni.getString());

}

}运行效果图

2021年新增使用CMake平台:mac

IDE :Android Studio 4.2.1

首先确保已经安装了CMake工具,没有安装的安装一下。

然后新建一个项目,选择Native C++,点击Next

输入项目名称,JniHelloWorld1,语言这里选择了Kotlin。Next

C++我们选择 Toolchain Default 这一项就可以,然后点击finish。

创建好的项目结构如下所示:

我们可以看到这里有一个cpp文件夹,文件夹下面有两个文件。我们先运行看一下效果。

创建项目时,默认的MainActivity

代码语言:javascript复制package com.example.jnihellowrold1

import androidx.appcompat.app.AppCompatActivity

import android.os.Bundle

import android.widget.TextView

import com.example.jnihellowrold1.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {

private lateinit var binding: ActivityMainBinding

override fun onCreate(savedInstanceState: Bundle?) {

super.onCreate(savedInstanceState)

binding = ActivityMainBinding.inflate(layoutInflater)

setContentView(binding.root)

// 调用一个native方法来获取字符串。

binding.sampleText.text = stringFromJNI()

}

/** * native方法,由 'native-lib' 这个native库来实现。native-lib会打包到应用中。 */

external fun stringFromJNI(): String

companion object {

// 静态方法,在加载MainActivity类的时候,会加载'native-lib'库。

init {

System.loadLibrary("native-lib")

}

}

}我们在build文件夹下可以看到生成的so文件。有趣的是真正生成的so的命名是libnative-lib.so。

我们看下native-lib.cpp文件。

代码语言:javascript复制#include

#include

extern "C" JNIEXPORT jstring JNICALL

Java_com_example_jnihellowrold1_MainActivity_stringFromJNI(

JNIEnv* env,

jobject /* this */) {

std::string hello = "Hello from C++";

//返回一个字符串 Hello from C++

return env->NewStringUTF(hello.c_str());

}我们什么都没有做,我们就生成了libnative-lib.so文件并实现了调用native方法,这一切是谁帮我们做的呢?显然是CMake了。我们看一下CMakeLists.txt这个文件里面的内容。

代码语言:javascript复制# For more information about using CMake with Android Studio, read the

# documentation: https://d.android.com/studio/projects/add-native-code.html

# 设置用来构建native library所需CMake的最小版本。

cmake_minimum_required(VERSION 3.10.2)

# 声明项目名称。

project("jnihellowrold1")

# 创建并命名库,将库设置为静态的或者共享的,并提供源代码文件的相对路径。

# 你可以定义多个库,CMake会为你构建它们。

# Gradle会自动将共享库打包到你的apk里面。

add_library( # 设置库的名称

native-lib

# 将库设置为共享的

SHARED

# 提供源代码文件(可以是多个文件)的相对路径。

native-lib.cpp )

# 搜索指定的预构建库并将其路径存储为变量。

# 因为CMake会在搜索路径上默认包含系统库,你只需要指定你想添加的公共的NDK库。

# 在完成构建之前CMake会验证这些库是否存在。

find_library( # 设置路径变量的名称。

log-lib

# 指定你想让CMake定位的NDK库的名称。

log )

# 指定CMake应该链接到目标库的库。

# 你可以链接多个库,例如你在这个构建脚本中定义的库,预编译的三方库,或者系统库。

target_link_libraries( # 指定目标库

native-lib

# 将目标库链接到NDK中包含的日志库。

${

log-lib} )那么CMakeLists.txt是怎么执行的呢,显然是在gradle.build文件中。

app/build.gradle文件精简版

代码语言:javascript复制//...

android {

compileSdkVersion 30

defaultConfig {

applicationId "com.example.jnihellowrold1"

minSdkVersion 21

targetSdkVersion 30

versionCode 1

versionName "1.0"

//注释1处,

externalNativeBuild {

cmake {

cppFlags ''

}

}

}

//...

//注释2处,指定cmake文件所在的路径

externalNativeBuild {

cmake {

path file('src/main/cpp/CMakeLists.txt')

version '3.10.2'

}

}

}参考链接:

我的Android NDK之旅(二),使用ndk-build构建JniAndroid JNI学习(二)——实战JNI之“hello world”版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/191740.html原文链接:https://javaforall.cn

相关数据

网络摄像头在线 白宫,华盛顿
beat365倍率

网络摄像头在线 白宫,华盛顿

📅 12-02 👁️ 915
為什麼許多歐美白人的臉上都有很多的雀斑?
beat365倍率

為什麼許多歐美白人的臉上都有很多的雀斑?

📅 10-08 👁️ 5820
闪电宝pos机产品功能及优势介绍
beat365倍率

闪电宝pos机产品功能及优势介绍

📅 08-02 👁️ 662