andorid ndk 各种坑啊 记录下

android jni代码回调java的问题
由于多线程原因会导致找不到java类,无法call函数的问题
问题1找不到java类
在JNI_OnLoad的时候 保存下来

JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved)
{
    g_vm = vm;
    JNIEnv* env = NULL;
    jint result = -1;
    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
        return -1;
    }
    assert(env != NULL);

    register_location_methods(env);
    result = JNI_VERSION_1_4;
    return result;
}
int register_location_methods(JNIEnv *env)
{
    jniEnv = env;
    jclass clazz;
    clazz = env->FindClass("com/TongBan/Chat/NetBilling");
    if (clazz == NULL) {
        return -1;
    }
    JNetBilling = clazz;

    onReceivedMsgType = env->GetStaticMethodID(clazz,
                    "OnReceivedMsgType", "(I)V");
//    env->CallStaticVoidMethod(JNetBilling, onReceivedMsgType, 1);
    return 0;
}

问题2多线程回调call函数
此处生成的JNIEnv无法获取到class 函数 等 需要之前保存好的全局变量

bool isAttacked = false;
    JNIEnv* env;
    int status = g_vm->GetEnv((void **) &env, JNI_VERSION_1_4);
    if (status < 0) {
        status = g_vm->AttachCurrentThread(&env, NULL);
        if (status < 0) {
            return len;
        }
        isAttacked = true;
    }
    env->CallStaticVoidMethod(JNetBilling,onReceivedMsgType,iMsgType);
    if (isAttacked) {
        g_vm->DetachCurrentThread();
    }

输出问题由于还是比较喜欢cout就百度了个cout输出到logCat日志的

int iMsgType = MSG_PACKET::GetMsgType(kBuffer);

    StreamBuf g_StreamBuf;
    std::cout.rdbuf(&g_StreamBuf);
    std::cout << iMsgType;//即可显示到logCat
#include <iostream>
#include <streambuf>

class StreamBuf : public std::streambuf
{
    enum
    {
        BUFFER_SIZE = 255,
    };

public:
    StreamBuf()
    {
        buffer_[BUFFER_SIZE] = '\0';
        setp(buffer_, buffer_ + BUFFER_SIZE - 1);
    }

    ~StreamBuf()
    {
        sync();
    }

protected:
    virtual int_type overflow(int_type c)
    {
        if (c != EOF)
        {
            *pptr() = c;
            pbump(1);
        }
        flush_buffer();
        return c;
    }

    virtual int sync()
    {
        flush_buffer();
        return 0;
    }

private:
    int flush_buffer()
    {
        int len = int(pptr() - pbase());
        if (len <= 0)
            return 0;

        if (len <= BUFFER_SIZE)
            buffer_[len] = '\0';

#ifdef ANDROID
        android_LogPriority t = ANDROID_LOG_INFO;
        __android_log_write(t, "JNI_DEBUG", buffer_);
#else
        printf("%s", buffer_);
#endif

        pbump(-len);
        return len;
    }

private:
    char buffer_[BUFFER_SIZE + 1];
};

到这里 终于可以 互动了 android->服务器->android

展开阅读全文

没有更多推荐了,返回首页