说明:在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中,代码会出现红色的显示,不用担心是正常现象。

android nativate 动态注册 静态注册的更多相关文章

  1. Android中的BroadCast静态注册与动态注册

    1.静态注册 新建MyBroadcast类继承BroadcastReceiver,实现onReceive方法 /** * Author:JsonLu * DateTime:2015/9/21 16:4 ...

  2. BroadcastReceiver(广播)的静态注册和动态注册 --Android开发

    BroadcastReceiver是安卓四大组件之一,本例通过代码的方式演示静态注册和动态注册. 1.静态注册 静态注册只需要AndroidManifest.xml中进行配置: AndroidMani ...

  3. Oracle监听静态注册和动态注册

    静态注册和动态注册总结 一.什么是注册? 注册就是将数据库作为一个服务注册到监听程序.客户端不需要知道数据库名和实例名,只需要知道该数据库对外提供的服务名就可以申请连接到数据库.这个服务名可能与实例名 ...

  4. Oracle监听器—静态注册

    注册就是将数据库作为一个服务注册到监听程序.客户端不需要知道数据库名和实例名,只需要知道该数据库对外提供的服务名就可以申请连接到数据库.这个服务名可能与实例名一样,也有可能不一样. 注册分: 1. 静 ...

  5. BroadcastReceiver的两种注册方式之------静态注册

    activity_main.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android&qu ...

  6. Android开发4: Notification编程基础、Broadcast的使用及其静态注册、动态注册方式

    前言 啦啦啦~(博主每次开篇都要卖个萌,大家是不是都厌倦了呢~) 本篇博文希望帮助大家掌握 Broadcast 编程基础,实现动态注册 Broadcast 和静态注册 Broadcast 的方式以及学 ...

  7. Android(java)学习笔记173:BroadcastReceiver之 静态注册 和 动态注册

    1. 广播接受者>什么是广播.收音机.电台:对外发送信号.收音机:接收电台的信号. >在android系统里面,系统有很多重要的事件: 电池电量低,插入充电器,sd卡被移除,有电话打出去, ...

  8. Android(java)学习笔记116:BroadcastReceiver之 静态注册 和 动态注册

    1. 广播接受者>什么是广播.收音机.电台:对外发送信号.收音机:接收电台的信号. >在android系统里面,系统有很多重要的事件: 电池电量低,插入充电器,sd卡被移除,有电话打出去, ...

  9. Android只能动态注册的广播Action

    只能动态注册的广播(部分): android.intent.action.SCREEN_ON android.intent.action.SCREEN_OFF android.intent.actio ...

  10. Android实现AppWidget、Broadcast静态注册

    Android实现AppWidget.Broadcast静态注册 本篇博客是基于我上一篇博客继续修改的,详情请看Android实现AppWidget.Broadcast动态注册 开发工具:Andori ...

随机推荐

  1. k8s-ingress配置websocket支持

    具体来说,使用的ingress-controller不一样,有关的设置也不太一样 Kubernetes Ingress Controller (k8s官方) 参考 http://github.com/ ...

  2. 基于ELK Nginx日志分析

    配置Nginx 日志 Nginx 默认的access 日志为log格式,需要logstash 进行正则匹配和清洗处理,从而极大的增加了logstash的压力 所以我们Nginx 的日志修改为json ...

  3. 10_SpringBoot更加详细

    一. 原理初探 1.1 自动装配 1.1.1 pom.xml spring-boot-dependencies: 核心依赖在父工程中 我们在写入或者引入一些SpringBoot依赖的时候, 不需要指定 ...

  4. 一个终端工具竟然有AI功能?使用了1天我立马把其他终端全卸载了!太香了!

    前言 平常工作需要频繁使用终端工具,有一个好的命令行终端工具是非常重要的. 尤其是使用mac的小伙伴,估计不少人都觉得iterm2才是最好的终端工具. 其实起初我也是这么觉得的,但是最近直到我使用了这 ...

  5. 代码随想录第十三天 | 150. 逆波兰表达式求值、239. 滑动窗口最大值、347.前 K 个高频元素

    第一题150. 逆波兰表达式求值 根据 逆波兰表示法,求表达式的值. 有效的算符包括 +.-.*./ .每个运算对象可以是整数,也可以是另一个逆波兰表达式. 注意 两个整数之间的除法只保留整数部分. ...

  6. 齐博x1模板中常用的TP标签数据处理

    上图是比较常用的, 而下图是比较特殊的场合,比如幻灯片可能会用到 下图使用了TP的循环标签. 上图只使用了条件判断标签 上图不存在 val="xxx" 这个参数,所以会自动循环输出 ...

  7. 制作一个windows垃圾清理小程序

    制作一个windows垃圾清理小程序: 把下列代码保存为.bat文件(如垃圾清理.bat) 双击它就能很快地清理垃圾文件,大约一分钟不到. 就是下面的文字(这行不用复制)=============== ...

  8. CSS 渐变锯齿消失术

    在 CSS 中,渐变(Gradient)可谓是最为强大的一个属性之一. 但是,经常有同学在使用渐变的过程中会遇到渐变图形产生的锯齿问题. 何为渐变锯齿? 那么,什么是渐变图形产生的锯齿呢? 简单的一个 ...

  9. Vue 实现小小记事本

    1.实现效果 用户输入后按回车,输入的内容自动保存,下方会显示记录的条数,鼠标移动到文字所在div上,会显示删除按钮,点击按钮,相应记录会被删除,下方的记录条数会相应变化,点击clear,所有记录会被 ...

  10. Java多线程的几种创建方式

    方法一:继承Thread类,重写run方法,直接调用start方法开启线程. /** * 继承Thread类,直接调用start方法开启线程. * @author LuRenJia */ public ...