首页 > 其他分享 >android nativate 动态注册 静态注册

android nativate 动态注册 静态注册

时间:2022-12-07 13:23:14浏览次数:36  
标签:main nativate 注册 sample LOGD env android onCreate id

说明:在java函数的入口比较容易分析,

  把activity的生命周期或者关键函数通过放在so层,分析起来就困难多了

 

1、在MainActivity中

package com.demo.nativate;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.widget.TextView;

import com.demo.nativate.databinding.ActivityMainBinding;

public class MainActivity extends AppCompatActivity {

    // Used to load the 'nativate' library on application startup.
    static {
        System.loadLibrary("nativate");
    }

    private ActivityMainBinding binding;

//    @Override
    protected native void onCreate(Bundle savedInstanceState);
//    {
//        super.onCreate(savedInstanceState);
//        setContentView(R.layout.activity_main);
//        // Example of a call to a native method
//        TextView tv = findViewById(R.id.sample_text);
//        tv.setText(stringFromJNI());
//    }

    /**
     * A native method that is implemented by the 'nativate' native library,
     * which is packaged with this application.
     */
    public native String stringFromJNI();
}

 

 

2、静态注册

#include <jni.h>
#include <string>
#include <android/log.h>

#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, "Tag->", __VA_ARGS__)

extern "C" JNIEXPORT jstring JNICALL
Java_com_demo_nativate_MainActivity_stringFromJNI(
        JNIEnv *env,
        jobject /* this */) {
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
}
extern "C"
JNIEXPORT void JNICALL
Java_com_demo_nativate_MainActivity_onCreate(JNIEnv *env, jobject thiz,
                                             jobject saved_instance_state) {
    // TODO: implement onCreate()
    LOGD("静态注册  MainActivity  OnCreate be called!");
    //super.onCreate(savedInstanceState);
    jclass MainActivityClass = env->GetObjectClass(thiz);
    jclass AppCompatActivityClass = env->GetSuperclass(MainActivityClass);
    jmethodID onCreate = env->GetMethodID(AppCompatActivityClass, "onCreate",
                                          "(Landroid/os/Bundle;)V");
    env->CallNonvirtualVoidMethod(thiz, AppCompatActivityClass, onCreate,
                                  saved_instance_state); //调用父类方法
    LOGD("静态注册  super.onCreate(savedInstanceState) be called!");
//    setContentView(R.layout.activity_main);
    jmethodID setContentView_id = env->GetMethodID(MainActivityClass, "setContentView", "(I)V");
    jclass layoutClass = env->FindClass("com/demo/nativate/R$layout");
    jfieldID activity_main_id = env->GetStaticFieldID(layoutClass, "activity_main", "I");
    jint id_txt_main = env->GetStaticIntField(layoutClass, activity_main_id);
    env->CallVoidMethod(thiz, setContentView_id, id_txt_main);
    LOGD("静态注册  setContentView(R.layout.activity_main); be called!");
//    TextView tv = findViewById(R.id.sample_textFId);
    jmethodID findViewById_mid = env->GetMethodID(MainActivityClass, "findViewById",
                                                  "(I)Landroid/view/View;");
    jclass RIdClass = env->FindClass("com/demo/nativate/R$id");
    jfieldID sample_textFId = env->GetStaticFieldID(RIdClass, "sample_text", "I");
    jint sample_textF = env->GetStaticIntField(RIdClass, sample_textFId);
    LOGD("静态注册  TextView tv = findViewById(R.id.sample_textFId); be called!");
    jobject tvobject = env->CallObjectMethod(thiz, findViewById_mid, sample_textF);
//    tv.setText(stringFromJNI());
    jclass tvClass = env->GetObjectClass(tvobject);
    jmethodID setText_mid = env->GetMethodID(tvClass, "setText", "(Ljava/lang/CharSequence;)V");
    jstring text = env->NewStringUTF("onCreate-->Native success by c++ !!!");
    env->CallVoidMethod(tvClass, setText_mid, text);
    env->DeleteLocalRef(text);
    LOGD("静态注册  tv.setText(stringFromJNI());; be called!");
}

  

3、动态注册

#include <jni.h>
#include <string>
#include <android/log.h>

#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, "Tag->", __VA_ARGS__)

extern "C" JNIEXPORT jstring JNICALL
Java_com_demo_nativate_MainActivity_stringFromJNI(
        JNIEnv *env,
        jobject /* this */) {
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
}
extern "C"
JNIEXPORT void JNICALL
Java_com_demo_nativate_MainActivity_onCreate(JNIEnv *env, jobject thiz,
                                             jobject saved_instance_state) {
    // TODO: implement onCreate()
    LOGD("静态注册  MainActivity  OnCreate be called!");
    //super.onCreate(savedInstanceState);
    jclass MainActivityClass = env->GetObjectClass(thiz);
    jclass AppCompatActivityClass = env->GetSuperclass(MainActivityClass);
    jmethodID onCreate = env->GetMethodID(AppCompatActivityClass, "onCreate",
                                          "(Landroid/os/Bundle;)V");
    env->CallNonvirtualVoidMethod(thiz, AppCompatActivityClass, onCreate,
                                  saved_instance_state); //调用父类方法
    LOGD("静态注册  super.onCreate(savedInstanceState) be called!");
//    setContentView(R.layout.activity_main);
    jmethodID setContentView_id = env->GetMethodID(MainActivityClass, "setContentView", "(I)V");
    jclass layoutClass = env->FindClass("com/demo/nativate/R$layout");
    jfieldID activity_main_id = env->GetStaticFieldID(layoutClass, "activity_main", "I");
    jint id_txt_main = env->GetStaticIntField(layoutClass, activity_main_id);
    env->CallVoidMethod(thiz, setContentView_id, id_txt_main);
    LOGD("静态注册  setContentView(R.layout.activity_main); be called!");
//    TextView tv = findViewById(R.id.sample_textFId);
    jmethodID findViewById_mid = env->GetMethodID(MainActivityClass, "findViewById",
                                                  "(I)Landroid/view/View;");
    jclass RIdClass = env->FindClass("com/demo/nativate/R$id");
    jfieldID sample_textFId = env->GetStaticFieldID(RIdClass, "sample_text", "I");
    jint sample_textF = env->GetStaticIntField(RIdClass, sample_textFId);
    LOGD("静态注册  TextView tv = findViewById(R.id.sample_textFId); be called!");
    jobject tvobject = env->CallObjectMethod(thiz, findViewById_mid, sample_textF);
//    tv.setText(stringFromJNI());
    jclass tvClass = env->GetObjectClass(tvobject);
    jmethodID setText_mid = env->GetMethodID(tvClass, "setText", "(Ljava/lang/CharSequence;)V");
    jstring text = env->NewStringUTF("onCreate-->Native success by c++ !!!");
    env->CallVoidMethod(tvClass, setText_mid, text);
    env->DeleteLocalRef(text);
    LOGD("静态注册  tv.setText(stringFromJNI());; be called!");
}

void dynamicRegister(JNIEnv *env, jobject thiz, jobject saved_instance_state) {
    LOGD("动态注册  MainActivity  OnCreate be called!");
    //super.onCreate(savedInstanceState);
    jclass MainActivityClass = env->GetObjectClass(thiz);
    jclass AppCompatActivityClass = env->GetSuperclass(MainActivityClass);
    jmethodID onCreate = env->GetMethodID(AppCompatActivityClass, "onCreate",
                                          "(Landroid/os/Bundle;)V");
    env->CallNonvirtualVoidMethod(thiz, AppCompatActivityClass, onCreate,
                                  saved_instance_state); //调用父类方法
    LOGD("动态注册  super.onCreate(savedInstanceState) be called!");
//    setContentView(R.layout.activity_main);
    jmethodID setContentView_id = env->GetMethodID(MainActivityClass, "setContentView", "(I)V");
    jclass layoutClass = env->FindClass("com/demo/nativate/R$layout");
    jfieldID activity_main_id = env->GetStaticFieldID(layoutClass, "activity_main", "I");
    jint id_txt_main = env->GetStaticIntField(layoutClass, activity_main_id);
    env->CallVoidMethod(thiz, setContentView_id, id_txt_main);
    LOGD("动态注册  setContentView(R.layout.activity_main); be called!");
//    TextView tv = findViewById(R.id.sample_textFId);
    jmethodID findViewById_mid = env->GetMethodID(MainActivityClass, "findViewById",
                                                  "(I)Landroid/view/View;");
    jclass RIdClass = env->FindClass("com/demo/nativate/R$id");
    jfieldID sample_textFId = env->GetStaticFieldID(RIdClass, "sample_text", "I");
    jint sample_textF = env->GetStaticIntField(RIdClass, sample_textFId);
    LOGD("动态注册  TextView tv = findViewById(R.id.sample_textFId); be called!");
    jobject tvobject = env->CallObjectMethod(thiz, findViewById_mid, sample_textF);
//    tv.setText(stringFromJNI());
    jclass tvClass = env->GetObjectClass(tvobject);
    jmethodID setText_mid = env->GetMethodID(tvClass, "setText", "(Ljava/lang/CharSequence;)V");
    jstring text = env->NewStringUTF("onCreate-->Native success by c++ !!!");
    env->CallVoidMethod(tvClass, setText_mid, text);
    env->DeleteLocalRef(text);
    LOGD("动态注册  tv.setText(stringFromJNI());; be called!");

}


static int registerNativates(JNIEnv *env) {
    jclass mainActivityClass = env->FindClass("com/demo/nativate/MainActivity");
    if (mainActivityClass == nullptr) {
        return JNI_FALSE;
    }
    JNINativeMethod methods[] = {
            {"onCreate", "(Landroid/os/Bundle;)V", (void *) dynamicRegister}
    };
    int methodsNum = sizeof(methods) / sizeof(methods[0]);
    if (env->RegisterNatives(mainActivityClass, methods, methodsNum) < 0) {
        return JNI_FALSE;
    }
    return JNI_TRUE;
}

jint JNI_OnLoad(JavaVM *vm, void *reserved) {
    LOGD("调用的 JNI_Onload函数");
    //获得JNI环境
    JNIEnv *env = nullptr;
    if ((vm->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_6)) != JNI_OK) {
        return -1;
    } else {
        if (!registerNativates(env)) {
            return -1;
        }
    }
    return JNI_VERSION_1_6;
}

  

4、小结

        当动静态注册同时存在时,会使用动态注册。

        在android studio中,代码会出现红色的显示,不用担心是正常现象。

标签:main,nativate,注册,sample,LOGD,env,android,onCreate,id
From: https://www.cnblogs.com/caomengqi/p/16962792.html

相关文章

  • 如何注册ChatGPT
    需要稳定的节点邮箱一个大约1块多的rmb步骤注册ChatGPT网址:https://chat.openai.com/auth/login点击signup->createanOpenAIaccount输入邮箱然后......
  • Abp自动注册的坑
    在abp开发中遇到一个大坑就是service的名称必须与接口名”I“后面的名称完全一致,否则不会注入如:publicclassAccountService:ApplicationService,IAccountsService......
  • android 平台移植sfdisk mkfs.ext4等工具使用
    1、mount-orw,remount/ chmod-R777sbin/mkfs.ext4chmod-R777sbin/mkfs.fatchmod-R777sbin/mtoolschmod-R777sbin/sfdiskchmod-R777sbin/yes.coreutilsch......
  • android 中对apache httpclient及httpurlconnection的选择
    在官方blog中,android工程师谈到了如何去选择apacheclient和httpurlconnection的问题:原文见http://android-developers.blogspot.com/2011/09/andro......
  • Android如何优化启动时间(boot time)
    尽可能地减少LA的启动时间在USER的构建。并假设我们有一个非常稳定的USER构建软件,没有任何错误,甚至警告消息存在于启动阶段。首先,我们需要检查驱动程序的初始化时间是否合......
  • 医疗类产品美国FDA注册流程
    什么是FDA?FDA由美国国会即联邦**授权,是专门从事食品与药品管理的最高执法机关。全称:食品药品监督管理局(FoodandDrugAdministration)严格来讲并没有FDA认证的叫法,这个FDA......
  • gym——1自定义Gym环境并注册
    gym1——自定义Gym环境并注册目录gym1——自定义Gym环境并注册感谢开始Step0新建文件夹Step1:新建环境文件xxEnv.pyStep2:在env下的__init__.py下注册**Step3**......
  • android驱动之设备树
    使用DeviceTree之后,可以实现不改动内核代码(不改动zImage)的情况下,不同产品,只更换相应的*.dtb文件即可启动系统。即相同的zImage使用不同的*.dtb文件,可以启动不同的产品。......
  • SpringCloud-Eureka服务注册中心
    1什么是EurekaNetflix在涉及Eureka时,遵循的就是API原则.Eureka是Netflix的有个子模块,也是核心模块之一。Eureka是基于REST的服务,用于定位服务,以实现云端中间件层服务发......
  • android开发新版Android studio使用新版logcat是过滤条件规则
    有四个常用的过滤关键字,分别是tag,package,level,message,line前面四个关键字过滤可以单独使用也可以组合使用最后那个line应该是指整行的意思,范围包括前面四个-tag:ex......