Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Android Studio 简单生成so文件并调用「建议收藏」

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

作者头像
全栈程序员站长
发布于 2022-11-04 12:46:25
发布于 2022-11-04 12:46:25
5.4K00
代码可运行
举报
运行总次数:0
代码可运行

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

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

平台:windows IDEAndroid Studio 下载好ndk:下载地址 https://developer.android.com/ndk/downloads/index.html

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

MyJni.java

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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
代码运行次数:0
运行
AI代码解释
复制
javah -jni -classpath D:\github\JniHelloWorld\app\build\intermediates\classes\debug com.brotherd.jnihelloworld.MyJni

就会在这个jni文件夹下生成一个.h文件,com_brotherd_jnihelloworld_MyJni.h,文件内容如下。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* 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
代码运行次数:0
运行
AI代码解释
复制
#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
代码运行次数:0
运行
AI代码解释
复制
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE := MyJni
LOCAL_SRC_FILES := Test.c
include $(BUILD_SHARED_LIBRARY)

Application.mk

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
APP_ABI := all

第4步,关联下载好的ndk包,我的解压好的路径是C:\android-ndk-r14b

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

第5步,调用so文件。 在app的bulid文件中加入如下代码,然后build project

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
android {
    ...
    sourceSets {
        main() {
            jniLibs.srcDirs = ['src/main/libs']
            jni.srcDirs = [] //屏蔽掉默认的jni编译生成过程
        }
    }
}

在MainActivity中调用

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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
代码运行次数:0
运行
AI代码解释
复制
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
代码运行次数:0
运行
AI代码解释
复制
#include <jni.h>
#include <string>
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
代码运行次数:0
运行
AI代码解释
复制
# 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
代码运行次数:0
运行
AI代码解释
复制
//...
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'
}
}
}

参考链接:

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年9月19日 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
VLAN及Trunk,重要!看瑞哥如何讲的明明白白!
对于一台二层交换机来说,缺省时整机的所有接口属于一个广播域。这意味着,只要连接到这个交换机的PC都配置在同一个IP子网内,即可直接进行互相访问,而且更重要的一点是,处于同一个广播域内的某个节点只要发送一个广播数据帧,在这个广播域内的所有其他节点都会收到这个数据帧,并且耗费资源来处理(即使它可能并不需要这个数据帧)。当这个广播域变得特别大(交换机上连接的用户数量特别多)时网络就非常有可能被大量的广播消耗掉大量资源。
网络技术联盟站
2020/11/04
21.4K0
VLAN及Trunk,重要!看瑞哥如何讲的明明白白!
H3C配置常用命令
超级用户终端登陆交换机 SYS进入                              //sys进入系统视图 输入以下命令 #  sysname lyz_xmc_bgl                    //sysname 系统名称 #  super password level 3 cipher pass          //superpassword 管理员密码,level3权限为3级,cipher输入密码为隐藏,缺省状态为可见,pass密码字符
py3study
2020/01/07
1.6K0
H3C交换机配置常用命令「建议收藏」
转载自:https://blog.csdn.net/EbowTang/article/details/79964980
全栈程序员站长
2022/09/06
3.1K0
VLAN解说
VLAN(Virtual Local Area Network)的中文名为"虚拟局域网"。虚拟局域网(VLAN)是一组逻辑上的设备和用户,这些设备和用户并不受物理位置的限制,可以根据功能、部门及应用等因素将它们组织起来,相互之间的通信就好像它们在同一个网段中一样。学生时代的学习笔记分享给大家,设备用的是H3C。
用户6184845
2019/10/14
1.2K0
VLAN解说
H3C华三2025最新交换机常用70条指令,分10类整理
ICT系统集成阿祥
2025/04/18
6550
H3C华三2025最新交换机常用70条指令,分10类整理
亦大自学总结STP——H3C
[SW1]# STP instance 1 priority 0 (优先级数字越小
py3study
2020/01/09
7680
H3CNE实验(Vlan/Ftp/DHC
2、SW1的Ethernet1/0/1和 Ethernet1/0/5分别属于Vlan1 和Vlan2
py3study
2020/01/06
6220
H3CNE实验(Vlan/Ftp/DHC
h3c vlan配置
[SWA-vlan10]port Ethernet1/0/1 #向当前VLAN添加端口
py3study
2020/01/10
9840
华为ensp中Hybrid接口原理和配置命令
Hybrid接口是ENSP虚拟化中的一种重要技术,它既可以连接普通终端的接入链路,又可以连接交换机间的干道链路。Hybrid接口允许多个VLAN(虚拟局域网)的帧通过,并可以在出接口方向将某些VLAN帧的标签剥掉。
神秘泣男子
2024/06/03
1.4K0
华为ensp中Hybrid接口原理和配置命令
H3CNE实验系列 | 三层交换&GVRP
实现不同 VLAN 间通信,其中 PC1 在 VLAN10,PC2 在 VLAN20。
网络技术联盟站
2019/07/23
4710
H3CNE实验专栏连载—VLAN配置实验,Access和Trunk
本实验任务通过在交换机上配置 Access 链路端口而使 PC 间处于不同 VLAN,隔离 PC 间 的访问,从而使大家加深对 Access 链路端口的理解。
网络技术联盟站
2021/04/25
1.7K0
当一个数据帧在经过Access、trunk链路的时候分别经历了什么样的过程?
这一篇来详细了解下整个数据在该网络中是如何传递的,对于我们深入了解access以及Trunk的处理过程是非常有帮助的。(建议先看一遍,自己看是否能够去理解,然后配合视频在看一次,反复看,直到理解为止)
网络之路一天
2024/01/08
8680
当一个数据帧在经过Access、trunk链路的时候分别经历了什么样的过程?
H3C三层交换机之IRF虚拟化技术详解及配置
一、IRF是什么? 目前,网络中主要存在两种结构的通信设备,固定盒式设备和模块框式分布式设备。固定盒式设备成本低廉,但没有高可用性支持;模块框式分布式设备具有高可用性、高性能、高端口密度的优点,但投入成本高。针对盒式设备和模块框式分布式设备的这些特点,一种结合了两种设备优点的IRF虚拟化技术应运而生。 . IRF称之为智能弹性架构,是H3C自主研发的硬件虚拟化技术,它的核心思想是将多台设备通过IRF物理端口连接在一起,进行必要的配置后,虚拟化成一台“分布式设备”。使用这种虚拟换技术可以集合多台设备的硬件资源和软件处理能力,实现多台设备的协同工作、统一管理和不间断维护(简单说,IRF技术就是“硬件虚拟化技术”,将多个硬件设备虚拟化出一台更大的硬件设备)。 二、IRF技术的优点 1、简化管理
小手冰凉
2019/11/05
2K1
华为ensp实验——DHCP
定义:DHCP动态主机配置协议是通过C/S框架构成,无需主机配置IP地址,动态分配IP地址,掩码,网关,DNS。
冷影玺
2023/10/12
1.2K0
华为ensp实验——DHCP
VLAN 的高级应用 QinQ
由于IEEE 802.1Q中定义VLAN ID 只有12bit ,仅能4096个VLAN ID ,除去0 和 4095 ,可用ID 为1 至 4094,无法满足日益增加的业务需求
运维小路
2024/11/01
1740
VLAN 的高级应用 QinQ
华为网络工程师 | 高级vlan再难咱也不怕,看完这篇文章,原理理解喽,命令也会敲喽!
sw2 创建vlan 并将相应接口划入相应vlan 和sw1 相连的接口配置trunk
网络技术联盟站
2019/07/30
1.1K0
h3c交换机-初级命令
参考文档 H3C_S3600_v1510 手册 H3C_S5000E 手册 网上其他热心网友的配置文档 ##########################################################################################
py3study
2020/01/06
1.2K0
网工必备技术,VLAN端口类型详解
VLAN(Virtual Local Area Network,虚拟局域网)技术可以把一个物理LAN划分成多个逻辑的LAN——VLAN,每个VLAN是一个广播域。处于同一VLAN的主机能够直接互通,而处于不同VLAN的主机不能够直接互通。
网络技术联盟站
2021/02/22
1.9K0
VLAN 基本配置
交换机的VLAN端口可以分为Access、Trunk和Hybrid3种类型。Access 端口是交换机上用来直接连接用户终端的端口,它只允许属于该端口的缺省VLAN的帧通过。Access端口发往用户终端的帧一定不带VLAN标签。Trunk端口是交换机上用来连接其他交换机的端口,它可以允许属于多个VLAN的帧通过。Hybrid 端口是交换机上既可以连接用户终端,又可以连接其他交换机的端口。Hybrid端口也可以允许属于多个 VLAN的帧通过,并且可以在出端口的方向上将某些VLAN 帧的标签剥掉。
可惜已不在
2024/10/17
1550
VLAN 基本配置
H3C AC+FIT完全设置
       用户采用PON线路,动态分配地址,无固定IP,每月1088元,如果带有固定IP,则需要每月7088元,采用较经济的方式,每次用户查询ip138得到公网IP后远程管理。
py3study
2020/01/08
1.6K0
推荐阅读
相关推荐
VLAN及Trunk,重要!看瑞哥如何讲的明明白白!
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验