当前位置: 首页 > wzjs >正文

淘宝客网站模板下载优化设计

淘宝客网站模板下载,优化设计,自在源码网官网,爱山东app下载注册流程1、Android JNI 动态库加载方式 1.1、静态加载 静态加载指的是在java类加载时自动加载本地库,在同一个进程中对同一个库名只会加载一次。有以下特点: 使用System.loadLibrary(),库必须位于APK的jniLibs目录或系统库路径中在类的静态初始化…

1、Android JNI 动态库加载方式

1.1、静态加载

静态加载指的是在java类加载时自动加载本地库,在同一个进程中对同一个库名只会加载一次。有以下特点:

  • 使用System.loadLibrary(),库必须位于APK的jniLibs目录或系统库路径中
  • 在类的静态初始化块中加载,加载时机是在类初始化时
  • 只需指定库名称(不含前缀lib和后缀.so)
public class NativeHelper {// 静态加载方式static {try {System.loadLibrary("native-lib");} catch (UnsatisfiedLinkError e) {Log.e("JNI", "加载本地库失败: " + e.getMessage());}}public native String stringFromJNI();
}

1.2、动态加载

动态加载指的是在运行时根据需要手动加载本地库。有以下特点:、

  • 使用System.load()方法
  • 需要指定库的完整路径
  • 可以在任何时间点加载
  • 更适合插件化或动态功能模块的场景
public class NativeHelper {private boolean isLibLoaded = false;public void loadLibrary(String fullPath) {if (!isLibLoaded) {System.load(fullPath); // 动态加载,如 "/data/data/com.example/app_lib/libnative-lib.so"isLibLoaded = true;}}public native String stringFromJNI();
}

2、JNI函数的两种注册方式

2.1、静态注册(固定命名规则)

通过函数名自动关联Java native方法和本地实现,依赖固定的函数命名规则(Java_包名_类名_方法名,类名中的特殊字符(如 $)需转义),只在首次调用native方法时查找符号。

// Native 层(无需显式注册)
JNIEXPORT void JNICALL
Java_com_example_NativeHelper_helloFromJNI(JNIEnv *env, jobject thiz) {// 实现代码
}

2.2、动态注册(JNI_OnLoad)

加载库后立即调用JNI_OnLoad主动注册本地方法(RegisterNatives),在方法调用前就完成所有注册,更加灵活高效。不强制要求注册所有函数,即使实现了JNI_OnLoad,未注册的函数仍可通过静态注册规则被调用。

以下是使用JNI_OnLoad注册的一个简单的示例:

#include <jni.h>// 本地方法实现
jstring native_hello(JNIEnv *env, jobject thiz) {return (*env)->NewStringUTF(env, "Hello from dynamic registration!");
}// 方法映射表
static JNINativeMethod methods[] = {{"helloFromJNI", "()Ljava/lang/String;", (void *)native_hello}
};// JNI_OnLoad 实现
jint JNI_OnLoad(JavaVM *vm, void *reserved) {JNIEnv *env;// 1. 获取JNI环境指针if (vm->GetEnv((void **)&env, JNI_VERSION_1_6) != JNI_OK) {return JNI_ERR;}// 2. 查找目标Java类jclass clazz = env->FindClass("com/example/NativeHelper");if (clazz == NULL) {return JNI_ERR;}// 3. 注册本地方法if (env->RegisterNatives(clazz, gMethods, sizeof(gMethods)/sizeof(gMethods[0])) < 0) {return JNI_ERR;}// 4. 返回使用的JNI版本return JNI_VERSION_1_6;
}

对代码中内容做一点解释:

  • JavaVM 指针:
    • JavaVM是JNI提供的虚拟机接口,全局唯一,在整个进程生命周期内有效;
    • 由系统在调用JNI_OnLoad时传入,用于获取当前线程的JNIEnv
  • JNIEnv:
    • JNIEnv是一个指向JNI函数表的指针,包含了所有JNI接口函数(如FindClass、NewStringUTF等)。因此,在使用任何JNI功能前(如注册 Native 方法、查找类),必须先获取JNIEnv
    • JNIEnv是线程局部的,不同线程的JNIEnv不同,因此必须为当前线程获取该指针
  • JNINativeMethod是一个结构体:
typedef struct {const char* name;      // Java中的方法名const char* signature; // 方法签名void*       fnPtr;     // 本地函数指针
} JNINativeMethod;

2.3、JNINativeMethod中的方法签名

方法签名的基本格式为:“(参数类型)返回类型”。参数类型分为三种:基本数据类型、引用数据类型,数组类型,分别有不同的签名方式。

多个参数直接拼接,如"(IJLjava/lang/String;)V"表示"void (int, long, String)"。

2.3.1、基本数据类型签名

Java类型JNI签名
booleanZ
byteB
charC
shortS
intI
longJ
floatF
doubleD
voidV

2.3.2、引用数据类型签名

Java类型JNI签名
StringLjava/lang/String;
ObjectLjava/lang/Object;
Class<?>Ljava/lang/Class;
ThrowableLjava/lang/Throwable;

引用类型必须用"L"开头,并用";“结尾,如"Ljava/lang/String;”。

如果是内部类,需要用$,比如"Landroid/media/MediaCodec$CryptoInfo;"

2.3.3、数组类型签名

Java类型JNI签名
int[][I
String[][Ljava/lang/String;
int[][][[I
Object[][Ljava/lang/Object;

数组类型用"[“开头,如”[I"表示"int[]"。

2.4、JNI函数

本地方法的前两个参数具有固定的含义,它们由JVM自动传递,用于提供环境上下文和调用对象信息。

实例方法:

JNIEXPORT 返回类型 JNICALL
Java_包名_类名_方法名(JNIEnv *env, jobject thiz, ...) {// 实现代码
}
  • 第一个参数(JNIEnv *env):JNI 环境指针,用于调用 NI函数(如创建Java对象、调用Java方法等)。每个线程有独立的JNIEnv,不可跨线程传递。
  • 第二个参数(jobject thiz):对Java对象的引用,表示调用该方法的实例(相当于 Java中的this)。

静态方法:

JNIEXPORT 返回类型 JNICALL
Java_包名_类名_方法名(JNIEnv *env, jclass clazz, ...) {// 实现代码
}
  • 第一个参数(JNIEnv *env):JNI环境指针。
  • 第二个参数(jclass clazz):对Java类的引用,表示调用该静态方法的类(相当于 Java中的Class对象)。

3、常见的JNIEnv方法

JNI数据类型映射

Java类型JNI类型说明
booleanjboolean无符号8位
bytejbyte有符号8位
charjchar无符号16位(UTF-16)
shortjshort有符号16位
intjint有符号32位
longjlong有符号64位
floatjfloat32位浮点
doublejdouble64位浮点
voidvoid无返回值
int[]jintArray数组类型,其他基本类型数组类似
Stringjstring字符串
Objectjobject任意Java对象(包含自定义)
String[]jobjectArray字符串数组
Object[]jobjectArray任意Java对象数组

JNI的基础类型与C/C++原生类型无缝对接,可以像使用普通变量一样操作它们。只有在处理Java对象、字符串、数组等引用类型时,才需要调用JNIEnv提供的方法。

3.1、类和对象操作方法

以下方法用于类的查找、对象的创建以及方法和字段的访问

  • jclass FindClass(const char* name):能够查找Java类。
  • jclass GetObjectClass(jobject obj):可获取对象的类。
  • jmethodID GetMethodID(jclass clazz, const char* name, const char* sig):能获取方法ID。
  • void CallVoidMethod(jobject obj, jmethodID methodID, …):用于调用返回void类型的实例方法,此外根据返回值类型还有 CallIntMethod、CallObjectMethod等变体。
  • jmethodID GetStaticMethodID(jclass clazz, const char* name, const char* sig):可获取静态方法 ID。
  • void CallStaticVoidMethod(jclass clazz, jmethodID methodID, …):用于调用静态方法,此外根据返回值类型还有CallStaticIntMethod、CallSTaticObjectMethod等变体。
  • jfieldID GetFieldID(jclass clazz, const char* name, const char* sig):能获取字段ID。
  • jint GetIntField(jobject obj, jfieldID fieldID):可获取 int 类型的实例字段,另外根据字段类型有不同变体GetObjectField、GetLongField 等。
  • jobject NewObject(jclass clazz, jmethodID methodID, …):用于创建新对象。
  • void SetIntField(jobject obj, jfieldID fieldID, jint value):设置实例字段值,有SetObjectField等变体

3.2、字符串操作方法

用于Java字符串与本地字符串的转换:

  • jstring NewStringUTF(const char* bytes):能创建 Java 字符串。
  • const char * GetStringUTFChars(jstring string, jboolean* isCopy):可获取字符串的 UTF-8 编码形式。
  • void ReleaseStringUTFChars(jstring string, const char* utf):用于释放字符串资源。

从本地字符串创建Java字符串,返回的是java堆上的对象(jstring),由JVM的垃圾回收机制管理,本地代码只需将jstring返回给Java层或传递给其他JNI方法,无需额外释放。

从Java字符串获取本地字符串,用完jstring之后必须配对调用ReleaseStringUTFChars,防止本地内存泄漏(当 JNI 复制字符串内容时),阻止 Java 字符串被 GC 回收(当 JNI 持有内部引用时)。必须复制通过 GetStringUTFChars获取的字符串才能在JNI资源释放后继续使用。

3.3、数组操作方法

这些方法用于数组的创建、访问和修改:

  • jintArray NewIntArray(jint length):可创建 int 类型的数组,此外还有 NewByteArray、NewObjectArray 等变体。
  • void SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject value); 根据设置类型有不同变体
  • jint * GetIntArrayElements(jintArray array, jboolean* isCopy):能获取数组元素。
  • void ReleaseIntArrayElements(jintArray array, jint* elems, jint mode):用于释放数组资源。
  • jsize GetArrayLength(jarray array):可获取数组长度。

3.4、全局引用和局部引用操作方法

用于管理对象引用:

  • jobject NewGlobalRef(jobject obj):可创建全局引用。
  • void DeleteGlobalRef(jobject obj):用于删除全局引用。
  • jobject NewLocalRef(jobject obj):能创建局部引用。
  • void DeleteLocalRef(jobject obj):用于删除局部引用。
  • jobject NewWeakGlobalRef(jobject obj):创建全局弱引用
  • void DeleteWeakGlobalRef(jobject obj):删除全局弱引用

在JNI中,绝大多数JNI函数创建的都是局部引用,只有NewGlobalRef和NewWeakGlobalRef会创建全局引用。

以下示例是局部引用:

jstring str = (*env)->NewStringUTF(env, "Hello");  // 创建局部引用
jobject obj = (*env)->NewObject(env, cls, ctor);   // 创建局部引用
jobject arr = (*env)->GetObjectField(env, obj, fieldID);  // 创建局部引用

一般来说局部引用会自动释放,如果重复使用某个变量,可以手动调用DeleteLocalRef。

要注意的是FindClass返回的jclass是局部引用,如果要长期使用需要转为全局引用:

static jclass stringClass; // 全局变量jclass localCls = env->FindClass("java/lang/String"); // 局部引用
stringClass = env->NewGlobalRef(localCls); // 转为全局引用

jmethodID和jfieldID不是对象引用,而是方法/字段的标识符,无需创建全局引用!

以MediaCodec为例:frameworks/base/media/jni/android_media_MediaCodec.cpp

创建JMediaCodec时,传入了jobject,将它设置为全局弱引用,

mObject = env->NewWeakGlobalRef(thiz);

之后直接获取JNIEnv,调用mObject的回调方法postEventFromNative

JNIEnv *env = AndroidRuntime::getJNIEnv();env->CallVoidMethod(mObject, gFields.postEventFromNativeID,EVENT_FIRST_TUNNEL_FRAME_READY, arg1, arg2, obj);

将JMediaCodec存储到java对象的字段中:

env->CallVoidMethod(thiz, gFields.setAndUnlockContextID, (jlong)codec.get());

我们实际在使用弱引用之前要使用以下两个方法判断是否被回收

if (env->IsSameObject(weakGlobalRef, NULL)) {// 弱全局引用已被回收
} else {// 弱全局引用仍有效
}jobject liveObj = (*env)->NewLocalRef(env, weakGlobalRef);
if (liveObj == NULL) {// 对象已被回收
}
http://www.dtcms.com/wzjs/378275.html

相关文章:

  • 2023今天的新闻联播游戏优化大师下载安装
  • 衡水电子商务网站建设故事式的软文广告例子
  • 中山独立站优化seo怎么做优化
  • 阿坝州网站制作seo网站优化助理
  • 泰国网站的域名app推广赚钱平台
  • p2p网站建设公司排名网站seo入门基础教程
  • 怎么用Visio studio做网站网络软文怎么写
  • 动漫做暧视频在线观看网站上海百度搜索优化
  • 哪个网站可以做推手优化公司怎么优化网站的
  • 做网站需要工商执照吗友情链接例子
  • asp网站建设教程广州seo快速排名
  • 艺客网站首页网站流量查询网站统计查询
  • 360免费wifi怎么连接西安区seo搜索排名优化
  • 各类东莞微信网站建设b站推广网站2024
  • 广东建设安全协会网站代运营公司靠谱吗
  • 外贸免费建设网站制作百度一下就知道百度首页
  • 做网站资源知乎整站优化和关键词优化的区别
  • 外贸型网站建设公司盘多多网盘搜索
  • 成功卡耐基网站建设企业管理8大系统
  • 做私服网站电话nba赛程排名
  • 网站建设技术进行开发网络推广服务费
  • 页面设计制作网站网址之家
  • 上海网站运营上海外包seo
  • 企业门户网站模板html上线抚州seo排名
  • 陕西营销型手机网站建设seo国外英文论坛
  • 网站建设修改教程视频教程seo教程seo官网优化详细方法
  • 大连投诉网站网络营销心得体会300字
  • 网址大全下载安装短视频seo软件
  • ai网站seo站内优化
  • 网站怎么做公司百度网页版下载安装