繁体   English   中英

如何在回调函数中发送广播

[英]How to sendbroadcast in callback function

我创建了一个 android 项目,项目是一个服务,没有 UI。 Java 层(函数名称为 onReceive)将接收广播以启动服务。 并且将调用本机 c 函数(函数名称为 startService)。 C 函数将创建一个线程,在该线程中,它将调用 Java 中的函数(函数名称为 SendLaResult(native) 和 SendLaResult(java))。 并且java函数将sendBroadcast发送到另一个APP。 这是一个主要的流程。 以下代码是示例。

1.开始工作

public void onReceive(final Context context, final Intent intent) {
...
          new Thread() {
            public void run() {
                try {
                    String str="test";
                    startService(str);
                    Log.i(TAG, "startService end!!!");
                }
                catch(Exception e) {
                    e.printStackTrace();
                }
            }
        }.start();
...
}

2. native-lib.cpp,在java中调用函数。

void SendResult( LaResult         laResult)
{
    bool isAttached = false;
    if(!isAttached) {
        int getEnvStat = g_JavaVM->GetEnv((void **)&g_env, JNI_VERSION_1_6);
        if(getEnvStat < 0) {
            jint status = g_JavaVM->AttachCurrentThread(&g_env, NULL);
            if(status >= 0) {
                isAttached = true;
            }
        }
    }
    if(g_env == NULL) {
        LOGE("g_env is NULL!!!");
    }

    jshort conf = laResult.conf ;
    jshort nls = laResult.nls ;
    jshort egoln = laResult.egoln ;

    g_laresult_constructor = g_env->GetMethodID(g_callback_laresult,"<init>","(SSSI[S)V");
    if(g_laresult_constructor == NULL) {
        LOGE("GetMethodID laresult error!!!");
    }

    jobject jparams = g_env->NewObject(g_callback_laresult, g_laresult_constructor, conf, nls, egoln);
    if(jparams == NULL) {
        char * str=strerror(errno);
        LOGE("NewObject jparams error %s !!!" ,str);
    }

    g_mid_sendlaresult = g_env->GetMethodID(g_callback_laservice, "SendLaResult", "(Lcom/xxx/xxx/xxxx/LaResult;)V");
    if(g_mid_sendlaresult == NULL) {
        LOGE("GetMethodID g_mid_sendlaresult error!!!");
    }

    jobject serviceobject = g_env->AllocObject(g_callback_laservice);
    if(serviceobject == NULL) {
        LOGE("AllocObject serviceobject error!!!");
    }

    g_env->CallVoidMethod(serviceobject, g_mid_sendlaresult, jparams);

    g_env->DeleteLocalRef(jparams);
    if(isAttached ) {
        g_JavaVM->DetachCurrentThread();
    }

    return;
}

3.LaService.java,sendBroadcast到另一个APK

public void SendLaResult(LaResult laresult) {
    Intent intent = new Intent();
    intent.setAction( "com.xxx.xxx.xxx.LA_RESULT" );
    intent.putExtra( "conf", laresult.conf);
    Log.d( "confidence", Integer.toString(laneresult.confidence) );
    intent.putExtra( "nls", laresult.nls);
    Log.d( "nLanes", Integer.toString(laneresult.nLanes) );
    intent.putExtra( "egoln", laresult.egoln);

    sendBroadcast( intent );
}

4、调用sendBroadcast时,出现如下崩溃。

--------- beginning of crash
01-02 18:05:11.505 13501-13537/com.xxx.xxx.xxxxx
E/AndroidRuntime: FATAL EXCEPTION: Thread-9
Process: com.xxx.xxx.xxxx, PID: 13501
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.content.Context.sendBroadcast(android.content.Intent)' on a null object reference
at android.content.ContextWrapper.sendBroadcast(ContextWrapper.java:431)
at com.xxx.xxx.xxxxx.xxxxxx.SendLaResult(LaService.java:94)

我发现sendBroadcast是异步的,最后被系统调用,立即返回。 所以我删除了函数 SendResult 中的以下源代码。

g_JavaVM->DetachCurrentThread();

不会发生崩溃,但是会出现以下错误日志,请参阅函数 SendResult 中的源代码。

01-02 18:15:03.696 13707-13743/com.xxx.xxx.xxxx
E/native-lib: NewObject jparams error Success !!!

如何解决第一个问题(sendBroadcast 崩溃)或如何解决发送问题(NewObject return null) 请给出一些建议。

我解决了这个问题。 不要在函数 SendLaResult 中发送广播,将每个 LaResult 存储到一个列表中,在 Oncreate 中创建另一个线程,在该线程中发送列表中的每个项目。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM