JNI静态注册

Android  NDK  2023年6月27日 pm7:51发布1年前 (2023)更新 91es.com站长
104 0 0

前言

之前其实写过,代码不见了,为了走一下流程,重新简单的写了一个。

PS:设计NDK环境配置这里不介绍哈

正文

静态注册

先由Java得到本地方法的声明,然后再通过JNI实现该声明方法。

  1. 优点: 理解和使用方式简单, 属于傻瓜式操作, 使用相关工具按流程操作就行, 出错率低

  2. 缺点: 当需要更改类名,包名或者方法时, 需要按照之前方法重新生成头文件, 灵活性不高

实战

定义Hello.java

加载Hello.so和native方法

package com.biumall.jni.one;
public class Hello {
    //1. load Hello.so
    static {
        System.loadLibrary("Hello");
    }
    // 2. define native hello()
    public static native String hello();
}
javac编译class

PS:javac对自定义对象不行,需要手动,可以看《JNI之类型介绍》和《JNI之自定义对象使用

通过javac编译Hello.class,然后javah编译

进入Hello.java目录

#当前位置:BiuJniStatic\src\main\java\com\biumall\jni\one
javac Hello.java

会在当前目录下生成

Hello.class
javah编译.h头文件

回退到 java目录

#当前位置:BiuJniStatic\src\main\java
javah com.biumall.jni.one.Hello

会在当前目录生成

com_biumall_jni_one_Hello.h
创建JNI

工程更目录创建JNI目录

BiuJniStatic/jni

把上面com_biumall_jni_one_Hello.h头文件拷贝到jni目录,并改名为

Hello.h

Hello.h拷贝一份为Hello.c

Hello.c也可以改为Hello.cpp,cpp中需要用C++写,否则会报错。

如果Hello.c中用了C++语法就会提示

error: member reference base type 'JNIEnv' (aka 'const struct JNINativeInterface *') is not a structure or union]

反过了Hello.cpp中用C语言写也会有类似的提示。

编写Hello.c

下面代码新增log打印,新增的活修改的都有备注

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_biumall_jni_one_Hello */

//----  add start -----
#include <android/log.h>
//----  add end   -----

#ifndef _Included_com_biumall_jni_one_Hello
#define _Included_com_biumall_jni_one_Hello
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_biumall_jni_one_Hello
 * Method:    hello
 * Signature: ()Ljava/lang/String;
 */
//----  modify start  -----

//LOG_TAG
#define LOG_TAG "from_static_jni_"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)

JNIEXPORT jstring JNICALL Java_com_biumall_jni_one_Hello_hello
  (JNIEnv * env , jclass jclazz){
    // [hello.c如果用C]
    LOGE("Java_com_biumall_jni_one_Hello_hello()");
    return (*env)->NewStringUTF(env, "Hello World !!!! --- from JNI ");
    // [hello.cpp如果用C++]
    // 如果hello.c中用了这个,无法build过,提示[error: member reference base type 'JNIEnv' (aka 'const struct JNINativeInterface *') is not a structure or union]
    //return env->NewStringUTF((char *)"Hello World !---from JNI");
};
//----  modify end   -----

#ifdef __cplusplus
}
#endif
#endif

PS : 上面---- 等备注的都是有更新的地方,其他的都是Hello.h一样。

配置Application.mk和Android.mk
Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_LDLIBS := -llog
LOCAL_MODULE    := Hello
LOCAL_SRC_FILES := Hello.c
include $(BUILD_SHARED_LIBRARY)
  1. LOCAL_MODULE : 为生成so库的名字

  2. LOCAL_SRC_FILES : 为需要编译的源文件

Application.mk
APP_ABI := all

all表示全部平台,可编译出如下so库

├─arm64-v8a
├─armeabi
├─armeabi-v7a
├─mips
├─mips64
├─x86
└─x86_64

当然,可以指定编译指定平台的so。

# 指定生成armeabi-v7a
APP_ABI := armeabi-v7a
# 或者指定多个[多个用空格分开]
APP_ABI := armeabi-v7a arm64-v8a
编译JNI

进入

BiuJniStatic/jni

输入

ndk-build

如果ndk配置没问题,根目录会出现libs目录,也就生成对应的so库。

build.gradle配置so库
# BiuJniStatic/build.gradle
android {
    compileSdkVersion 31
    // 略
    sourceSets {
        main {
            jniLibs.srcDirs = ['libs']
        }
    }
}

编译运行,就可以测试Java调用JNI方法了。

参考文章

  1. [NDK开发]Android JNI 开发之静态注册

  2. [NDK开发]Android JNI 中新增JNI层日志打印

  3. NDK之使用第三方so库

 历史上的今天

  1. 2024: TextView.setWidth()竟然失效了(0条评论)
  2. 2024: 老舍:理想的生活,不是房子车子票子(0条评论)
  3. 2021: Android的apk组成结构(0条评论)
  4. 2021: 席慕容:独白(0条评论)
  5. 2021: 嫣然若雪:余生,看淡所有,珍惜拥有(0条评论)
版权声明 1、 本站名称: 91易搜
2、 本站网址: 91es.com3xcn.com
3、 本站内容: 部分来源于网络,仅供学习和参考,若侵权请留言
3、 本站申明: 个人流水账日记,内容并不保证有效

暂无评论

暂无评论...

随机推荐

[摘]Android图片加载框架之Glide和Picasso的区别

前言Glide和Picasso在实际中很常用,也容易忘记各个的优缺点。此文整理很全,因此摘抄于此,方便自己查阅。本文摘抄《Android图片加载框架之(Glide和Picasso的区别,Glide的简单使用)》)。正文Glide,一个被google所推荐的图片加载库,常见的还有Picas...

张定浩:我喜爱一切不彻底的事物

我喜爱一切不彻底的事物。细雨中的日光,春天的冷,秋千摇碎大风,堤岸上河水游荡。总是第二乐章 在半开的房间里盘桓;有些水果不会腐烂,它们干枯成轻盈的纪念品。 我喜爱一切不彻底的事物。琥珀里的时间,微暗的火,一生都在半途而废,一生都怀抱热望。 ...

史铁生:秋天的怀念

双腿瘫痪后,我的脾气变得暴怒无常。望着望着天上北归的雁阵,我会突然把面前的玻璃砸碎;听着听着收音机里甜美的歌声,我会猛地把手边的东西摔向四周的墙壁。这时,母亲就悄悄地躲出去,在我看不见的地方偷偷地注意着我的动静。当一切恢复沉寂,她又悄悄地进来,眼圈红红地看着我。“听说北海的花儿都开了,我推着你去走走...

[代码片段]Java获取某目录下文件总大小

前言代码功能:获取某目录下文件总大小项目中不仅需要判断磁盘大小,还需要限制拷贝目录大小。正文思路:递归目录下的所有文件,累加文件大小。当然,这种递归方式不是很好,因为存在目录层级复杂和文件多,导致耗时。 /** * * @param file * @...

[摘]Android横屏和竖屏的方法

前言本文摘抄,方便自己查阅。正文AndroidManifest.xml配置在指定的要设置的Activity对应的标签中加入android:screenOrientation相关属性。unspecified:默认值 由系统来推断显示方向.判定的策略是和设备相关的,所以不同的设备会有不同的...

柴静:真实的人性有无尽的可能

1几年前我采访过一个人。他被诬陷嫖妓,证据是卖淫者的供述,他被拘留了42天,放了。校长当不了了,儿子的婚事也吹了“他爹是个大流氓,人还能好么?”他告了十六年,路上带不了两个钱还叫人掏包了,捡人家饭吃。我问他最难受的是什么。“最难忍受就是开党员会的时候我不是党员了”他说。2我们找到了当...