如何解决有关sendBroadcast的问题

时间:2019-01-02 10:22:49

标签: java android c callback native

我创建了一个android项目,项目是服务,没有UI。 Java层(函数名称为onReceive)将接收广播到startservice。 然后将调用本机c函数(函数名称为startService)。 C函数(函数名称为SendResult)将创建一个线程,该线程将在Java中调用函数(函数名称为SendLaResult)。 Java函数会将sendBroadcast发送到另一个APP。 这是一个主要流程。

以下代码为示例。

    1. start work

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, call funtion in 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 to another 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.When the sendBroadcast is called, the following crash occur.
--------- 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 !!!

SendResult函数中的NewObject在第二次调用时将返回null,第一次调用为successull。并且请忽略该成功字,它是无用的错误号。

我没有从根本上解决此问题的任何线索。 谁可以提供一些指导?

0 个答案:

没有答案