android jni动态注册,Android NDK-动态注册jni方法

概要

作者上一文通过Cmake的编译方式对Android开发NDK调用三方so库进行了演示,这里主要讲一下在NDK开发中,怎么样去动态的注册C++里面的native方法,主要步骤如下:

java中定义Native方法

编写C++文件,实现jni接口方法,以及JNI_OnLoad方法

编译生成so

java加载so库,调用native方法

1.创建加载native方法的java类

package com.example.testndk2;

public class NativeApi {

static {

System.loadLibrary("nativelib");

}

public static native String getHello();

}

2.编写C++代码

#include

#include

#include

#include

extern "C" { //因为是jni默认是调用C的代码,这里由于开发语言是C++,为了兼容C,一定要用到 extern “C”

JNIEXPORT jstring JNICALL get_hello(JNIEnv *env, jclass clazz) {

return env->NewStringUTF("hello jni");

}

static JNINativeMethod g_methods[] = {

{ "getHello", "()Ljava/lang/String;", (void*)get_hello}

};

JNIEXPORT int JNICALL JNI_OnLoad(JavaVM *vm,void *reserved) {

JNIEnv *env;

if (vm->GetEnv((void **) &env,JNI_VERSION_1_6) != JNI_OK) {

return JNI_ERR;

}

const char* class_path = "com/example/testndk2/NativeApi";//这里对应native的java类

jclass javaClass = env->FindClass(class_path);

if (javaClass == NULL){

return JNI_ERR;

}

int method_count = sizeof(g_methods) / sizeof(g_methods[0]);

if (env->RegisterNatives(javaClass, g_methods, method_count) < 0) {

return JNI_ERR;

}

return JNI_VERSION_1_6;

}

}

3.编译生成so库

这里采用上一篇文章的方式,分别创建Android.mk、Application.mk,这里还是贴一下相应的代码:

Android.mk

#Android.mk

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := nativelib

LOCAL_SRC_FILES := NativeApi.cpp

NDK_APP_DST_DIR := ../../libs/$(TARGET_ARCH_ABI)

include $(BUILD_SHARED_LIBRARY)

Application.mk

#Application.mk

APP_STL:=c++_shared

APP_PLATFORM := android-16

APP_CPPFLAGS:=-frtti -fexceptions

APP_ABI := all

4.加载so库,并调用方法

在模块级的build.gradle文件中配置lib库目录

sourceSets{

main{

jniLibs.srcDirs = ['libs']

}

}

在MainActivity里面调用native方法,拿到数据,显示到TextView上

package com.example.testndk2;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

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

tv.setText(NativeApi.getHello());

}

}

注意

如果是用C++代码编写so库,一定要记得加extern 'C'

C++代码中,env->FindClass(class_path)方法,class_path一定要和java类的包名和类名对应上

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值