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          // std::chrono::seconds

#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天时间终于搞完了。


付出不一定有回报,但不付出一定不会有回报,嘎嘎嘎~

更多相关文章

  1. Android Media Recorder录音播放源代码
  2. android实现自动关机代码
  3. Android 用源代码写layout布局
  4. 记录代码合并时产生的bug
  5. Android常用功能代码块
  6. Android拍照上传代码样例
  7. android打开联系人的代码
  8. Android 监听WiFi的开关状态实现代码

随机推荐

  1. Android libyuv应用系列(二)libyuv在Androi
  2. android消息机制(handler运行机制)解析
  3. Android:模拟器使用命令安装apk
  4. android 再按一次退出程序
  5. Android 桌面角标在各大品牌机型上的实现
  6. 【Android】Android Studio实战快速高效
  7. Android 的 selector--背景选择器
  8. 在eclipse上开发Android应用程序
  9. 穿越之旅之--android中如何执行java命令
  10. NDK开发历程(一):android native code的调试