android C++ 和 jni,根据JNIEnv的FindClass获取java类,包括多线程
java代码
TestC.java
package com.example.testnativejava;
import android.util.Log;
public class TestC {
private final static String tag = "TestC";
}
TestNativeJava.java
package com.example.testnativejava;
import android.util.Log;
public class TestNativeJava {
private final String tag = "TestNativeJava";
public TestNativeJava() {
Log.d(tag, "new TestNativeJava");
}
public void ShowLog() {
Log.d(tag, "show log entry");
System.load("libtest_c_java.so");
SayHello();
Log.d(tag, "show log exit");
}
// jni 接口
public native int SayHello();
}
下面是C++代码
c++ 代码
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "test_c_java.h"
#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "Test_c_java", __VA_ARGS__))
static JavaVM *g_JavaVM;
static bool stop = false;
static JNIEnv* jniEnv;
static void Run() {
LOGI("%s, entry", __FUNCTION__);
g_JavaVM->AttachCurrentThread(&jniEnv, NULL);
const char *classStr = "android/net/Proxy";
LOGI("find class 1 str = %s, !!!!!", classStr);
jclass p = jniEnv->FindClass(classStr);
LOGI("find class 2 str = %s, !!!!!", classStr);
if(p != NULL){
jniEnv->DeleteLocalRef(p);
LOGI("find class testC is success");
}
g_JavaVM->DetachCurrentThread();
stop = true;
LOGI("%s, exit", __FUNCTION__);
}
static void TestEnv1(JNIEnv *env) {
LOGI("%s, entry", __FUNCTION__);
const char *classStr = "android/net/Proxy";
LOGI("find class 1 str = %s, !!!!!", classStr);
jclass p = env->FindClass(classStr);
LOGI("find class 2 str = %s, !!!!!", classStr);
if(p == NULL){
LOGI("find class is error!!!!!");
LOGI("%s, exit", __FUNCTION__);
return;
}
env->DeleteLocalRef(p);
LOGI("%s, success exit", __FUNCTION__);
}
static void TestEnv2(JNIEnv *env) {
LOGI("%s, entry", __FUNCTION__);
const char *classStr = "com/example/testnativejava/TestC";
LOGI("find class testC 1 str = %s, !!!!!", classStr);
jclass TestC = env->FindClass(classStr);
LOGI("find class testC 2 str = %s, !!!!!", classStr);
if(TestC == NULL){
LOGI("find class testC is error!!!!!");
return;
}
env->DeleteLocalRef(TestC);
LOGI("%s, success exit", __FUNCTION__);
}
jint Java_com_example_testnativejava_TestNativeJava_SayHello(JNIEnv *env, jobject thiz) {
LOGI("%s, entry", __FUNCTION__);
TestEnv1(env);
TestEnv2(env);
std::thread t(Run);
while (1) {
if (stop)
break;
std::this_thread::sleep_for (std::chrono::seconds(1));
}
t.join();
LOGI("%s, exit", __FUNCTION__);
return 0;
}
jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) {
LOGI("%s, entry", __FUNCTION__);
g_JavaVM = vm;
LOGI("%s, exit", __FUNCTION__);
return JNI_VERSION_1_4;
}
void JNI_OnUnload(JavaVM* vm, void* reserved) {
LOGI("%s, exit", __FUNCTION__);
}
JNI_OnLoad在apk加载时就会被调用,用于保存Java的虚拟机实例,JavaVM,在android下是不能自己创建的。
以上有3次使用FindClass去获取jclass,是在java层由jni接口SayHello 调用的
1.TestEnv1 测试android的java 类,具体可以查看类似我的sdk\sources\android-19\android\net\Proxy.java 去查找
2.TestEnv2 测试是自己的apk中java 类,我只从SayHello的入参 env中可以获取到;如果使用JavaVM->AttachCurrentThread(&env, NULL); 使用FindClass是获取不到的,应该是env的classpath不对,应该把AttachCurrentThread的第二个参数 NULL 替换掉,具体换成什么,请自己查看怎么创建JavaVM,当然这个是我的猜测,最好是使用android jni传下的入参。
3. 起线程在run中获取android 的java 类。
以上测试都是成功的。
总结困难:
1.如果获取JavaVM,android 居然不能自己创建,真TNND的CaoDan。
2.测试在线程中如何查找Java类,路径必须要精确到类名,否则是找不到的。
第一篇android的博客终于写完了,花了2天时间终于搞完了。
付出不一定有回报,但不付出一定不会有回报,嘎嘎嘎~
更多相关文章
- 判断可用的intent和更改Drawable的透明度
- Android(安卓)Google 地图学习
- Android中获取和设置手机的壁纸
- unity3d 获取剩余空间大小 android and ios
- android API Demo之使用ViewFlipper制作轮播广告
- 箭头函数的基础使用
- NPM 和webpack 的基础使用
- Python list sort方法的具体使用
- 【阿里云镜像】使用阿里巴巴DNS镜像源——DNS配置教程