Broadcasting intents from native code

2,196 views
Skip to first unread message

dbax

unread,
Jan 21, 2011, 12:46:14 PM1/21/11
to android-ndk
I'd like to broadcast intents from native code. I'm doing some kind of
image processing based on the live camera stream and depending on the
changes from frame to frame I'd like to send different kinds of
intents.

I managed to send the intent in a init-method, but in a different
method it is not working and it crashes when I'm invoking the
sendBroadcast(Intent i) method. (Although, occasionally it was working
for up until 5 times until it eventually crashed.)

I'll explain what I'm doing in the code:

----------------------------------
In Java I have declared a native method:

private native void init();
-----------------------------------

In C++ a have defined the JNI Interface:

JNIEXPORT void JNICALL
...._init(JNIEnv* env, jobject obj)
{
JniClass::getInstance->init(env, obj);
}

-----------------------------------

The init method saves pointers the method IDs will need for sending
intents.

void JniClass::init(JNIEnv* env, jobject obj)
{
this->env = env;
this->obj = obj;

jclass activityClass = env->GetObjectClass(obj);

jmethodID appGetContextId = env->GetMethodID(activityClass,
"getApplicationContext", "()Landroid/content/Context;");
if(appGetContextId == 0) return;

this->appContext = env->CallObjectMethod(obj, appGetContextId);
if(this->appContext == 0) return;

jclass contextClass = env->FindClass("android/content/Context");
if(contextClass == 0) return;

this->sendBroadcastMethodId = env->GetMethodID(contextClass,
"sendBroadcast", "(Landroid/content/Intent;)V");
if(this->sendBroadcastMethodId == 0) return;

this->intentClass = env->FindClass("android/content/Intent");
if(intentClass == 0) return;

this->intentConstructorMethodId = env->GetMethodID(intentClass,
"<init>", "()V");
if(intentConstructorMethodId == 0) return;

this->intentSetActionMethodId = env->GetMethodID(intentClass,
"setAction", "(Ljava/lang/String;)Landroid/content/Intent;");
if(this->intentSetActionMethodId == 0) return;
}
-----------------------------------

The same class offers a method for creating new intents. This method
uses pointers created in the init-method.

jobject JniClass::createNewIntent(char* intentType)
{
LOG_INFO("Creating new intent.."

jstring intentString = env->NewStringUTF(intentType);
LOG_INFO("Intent String created");

jobject intentObject = env->NewObject(intentClass,
intentConstructorMethodId);
LOG_INFO("New Intent Object created");

env->CallVoidMethod(intentObject, intentSetActionMethodId,
intentString);
LOG_INFO("Intent.setAction executed");
}

-------------

Also there is a method for finally broadcasting the intent created
before.

void JniClass::sendBroadcast(jobject intentObject)
{
LOG_INFO("Broadcasting intent..");
env->CallVoidMethod(appContext, sendBroadcastMethodId, intentObject);
LOG_INFO("Intent broadcasted");
}

--------------

With this code I should then be able to send intents:

JniClass* j = JniClass::getInstance();
char* intent = "com.example.TEST";
j->sendBroadcast(j->createNewIntent(intent));

-----------------------------------------

Everything is working except for finally sending the intent.
This is log I get:
I/JNI ( 6733): Preparing Intent..
I/JNI ( 6733): Creating new intent..
I/JNI ( 6733): Intent String created
I/JNI ( 6733): New Intent Object created
I/JNI ( 6733): Intent.setAction executed
I/JNI ( 6733): Broadcasting intent..
I/DEBUG ( 5035): *** *** *** *** *** *** *** *** *** *** *** *** ***
*** *** ***
I/DEBUG ( 5035): Build fingerprint: 'tmo_at/htc_bravo/bravo/bravo:
2.2/FRF91/232610:user/release-ke
ys'
I/DEBUG ( 5035): pid: 6733, tid: 6765 >>>
com.example.TestApplication <<<

-----------------------------------------

So everything seems to be ok until I finally invoke sendBroadcast.

Any ideas what the problem could be and how I can solve it?





alan

unread,
Jan 25, 2011, 4:01:39 AM1/25/11
to andro...@googlegroups.com
if you are keeping objects around for some time (e.g your classes) then they need to be stored in global references to prevent garbage collection. if creating objects within a native methd that doesm't return immediately you need to delete the local references. log cat will likely tell you which problem you are experiencing
Reply all
Reply to author
Forward
0 new messages