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

广告也精彩

前言

简单记录一下,方便自己查阅。

PS: Android jni开发主要依赖Android开发平台,sdk和ndk三个部分

Android SDK : Version 31
JAVA Sdk    : java1.8
NDK         : android-ndk-r21d

上面只是举个例子,具体环境需要自己搭建。

静态注册

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

  1. 优点: 理解和使用方式简单, 属于傻瓜式操作, 使用相关工具按流程操作就行, 出错率低
  2. 缺点: 当需要更改类名,包名或者方法时, 需要按照之前方法重新生成头文件, 灵活性不高

动态注册

动态注册:动态注册JAVA的Native方法,使得c/c++里面方法名 可以和 java 的Native方法名可以不同, 动态注册是将将二者方法名关联起来,以后在修改Native方法名时,只需修改动态注册关联的方法名称即可

  1. 优点: 灵活性高, 更改类名,包名或方法时, 只需对更改模块进行少量修改, 效率高
  2. 缺点: 对新手来说稍微有点难理解, 同时会由于搞错签名, 方法, 导致注册失败

正文

直入正题。本文介绍的是JNI静态注册。

第一步

新建一个Android 工程,这里命令为MyDeviceABI

然后新增一个DeviceABI.java

package com.biumall.mydeviceabi;

public class DeviceABI {
    static {
        //so库名也定义为DeviceABI
        System.loadLibrary("DeviceABI");
    }

    // 定义一个接口
    public static native String getDeviceABI();
}

第二步

使用Android Studio的Terminal

进入DeviceABI.java所在的目录,然后:

javac DeviceABI.java

然后退到MyDeviceABI\src\main目录下,执行

javah com.biumall.mydeviceabi.DeviceABI

生成

com_biumall_mydeviceabi_DeviceABI.h

我这里会改名字,具体看自己

DeviceABI.h

第三步

在MyDeviceABI工程根目录中创建jni目录

MyDeviceABI\jni

把DeviceABI.h(这里是生成的,没有改变)放入jni。

然后在jni目录中创建DeviceABI.c文件(从DeviceABI.h复制再改动的)

DeviceABI.h,完整版如下:

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

#ifndef _Included_com_biumall_mydeviceabi_DeviceABI
#define _Included_com_biumall_mydeviceabi_DeviceABI
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_biumall_mydeviceabi_DeviceABI
 * Method:    getDeviceABI
 * Signature: ()Ljava/lang/String;
 */
 
 // 此处开始有改动,其他的都是拷贝DeviceABI.h
 
JNIEXPORT jstring JNICALL Java_com_biumall_mydeviceabi_DeviceABI_getDeviceABI
  (JNIEnv * env){

    #if defined(__arm__)
      #if defined(__ARM_ARCH_7A__)
        #if defined(__ARM_NEON__)
          #if defined(__ARM_PCS_VFP)
            #define ABI "armeabi-v7a/NEON (hard-float)"
          #else
            #define ABI "armeabi-v7a/NEON"
          #endif
        #else
          #if defined(__ARM_PCS_VFP)
            #define ABI "armeabi-v7a (hard-float)"
          #else
            #define ABI "armeabi-v7a"
          #endif
        #endif
      #else
       #define ABI "armeabi"
      #endif
    #elif defined(__i386__)
       #define ABI "x86"
    #elif defined(__x86_64__)
       #define ABI "x86_64"
    #elif defined(__mips64)  /* mips64el-* toolchain defines __mips__ too */
       #define ABI "mips64"
    #elif defined(__mips__)
       #define ABI "mips"
    #elif defined(__aarch64__)
       #define ABI "arm64-v8a"
    #else
       #define ABI "unknown"
    #endif

    return (*env)->NewStringUTF(env, "Compiled with ABI " ABI ".");
  }
// 改动结束
#ifdef __cplusplus
}
#endif
#endif

PS: 如果你要复制,请记得改变函数名,这里函数涉及到包名。

第四部

这部分主要是新增Android.mk和Application.mk文件。

Android.mk
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := DeviceABI
LOCAL_SRC_FILES := DeviceABI.c

include $(BUILD_SHARED_LIBRARY)
Application.mk
APP_ABI := all

具体配置就不细说,后续会总结、

第五步

进入 MyDeviceABI\jni> 然后执行 ndk-build

如果程序或者配置没问题,就编译正常。

E:\MyDeviceABI\jni>ndk-build

[arm64-v8a] Compile        : DeviceABI <= DeviceABI.c
[arm64-v8a] SharedLibrary  : libDeviceABI.so
[arm64-v8a] Install        : libDeviceABI.so => libs/arm64-v8a/libDeviceABI.so
[x86_64] Compile        : DeviceABI <= DeviceABI.c
[x86_64] SharedLibrary  : libDeviceABI.so
[x86_64] Install        : libDeviceABI.so => libs/x86_64/libDeviceABI.so
[mips64] Compile        : DeviceABI <= DeviceABI.c
[mips64] SharedLibrary  : libDeviceABI.so
[mips64] Install        : libDeviceABI.so => libs/mips64/libDeviceABI.so
[armeabi-v7a] Compile thumb  : DeviceABI <= DeviceABI.c
[armeabi-v7a] SharedLibrary  : libDeviceABI.so
[armeabi-v7a] Install        : libDeviceABI.so => libs/armeabi-v7a/libDeviceABI.so
[armeabi] Compile thumb  : DeviceABI <= DeviceABI.c
[armeabi] SharedLibrary  : libDeviceABI.so
[armeabi] Install        : libDeviceABI.so => libs/armeabi/libDeviceABI.so
[x86] Compile        : DeviceABI <= DeviceABI.c
[x86] SharedLibrary  : libDeviceABI.so
[x86] Install        : libDeviceABI.so => libs/x86/libDeviceABI.so
[mips] Compile        : DeviceABI <= DeviceABI.c
[mips] SharedLibrary  : libDeviceABI.so
[mips] Install        : libDeviceABI.so => libs/mips/libDeviceABI.so

我的编译成功后,libs中出现对应的so库等。

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

因为我的存在libs,最后一步配置就是直接引用。

第六步

配置 so库,网上很多种,看自己习惯。

在工程中的build.gradle,新增如下内容:

android {
    compileSdkVersion 31

    // 

    sourceSets {
        main {
            jniLibs.srcDirs = ['libs']
        }
    }
}

参考文章

  1. android JNI 开发之第一个 JNI 实例
  2. Android jni 开发详细流程

广告也精彩
版权声明:125la.com站长 发表于 2022年5月27日 上午8:08。
转载请注明:[NDK开发]Android JNI 开发之静态注册 | 125啦读书导航

相关文章

广告也精彩

暂无评论

暂无评论...