2012-11-29 60 views
1

如何從Android應用程序註冊回調JNI?我的要求是,我想從Android應用程序中創建一個JNI調用,並且想要註冊一個回調,以便我可以從JNI獲取Java應用程序的回調。回電JNI

謝謝

+0

註冊本地回調,並從該回調函數通過JNI調用java。 – Flavio

+0

不要忘記'AttachCurrentThread',否則你將無法回撥給Java。 –

+0

感謝您提供的信息......其實我對JNI和原生編程有所瞭解......請分享一些鏈接或代碼片段以供參考? – user1844484

回答

0

首先,檢查Swig。它將C++封裝在Java中,並且具有「導演」功能,可以更輕鬆地從Java調用C++方法。

用生JINI,你不能直接做到這一點。儘管可以使RegisterNatives()調用綁定本地方法,但不能更改它。如果你想通過指針調用C函數,你需要分兩步來完成。我對此非常感興趣,因爲JNI非常冗長乏味。基本的技巧是,將C函數指針包裝在一個java long中。

首先聲明一個Java類:

對類文件
public class Callback { 
    public Callback(long cMethodPointer) { this.cMethod = cMethod; } 
    public void doCallback() { callCMethod(cMethod); } 
    public static native void callCMethod(long cMethod); 
    public long cMethod; 
} 

運行JAVAH,你會得到一個存根頭產生的,看起來像:

JNIEXPORT void JNICALL Java_Callback_callCMethod 
    (JNIEnv *, jclass, jlong); 

在DLL中實現該方法/ so:

typedef void (*FP)(); 
JNIEXPORT void JNICALL Java_Callback_callCMethod 
    (JNIEnv *, jclass, jlong pointer) { 
    ((FP)(void*)pointer)(); 
} 

並在您的Java main()方法中調用該DLL上的System.loadLibrary()。

最後,從C/C++代碼,你將需要創建通過JNI回調對象的實例,並通過指向一個實際的方法吧:

void MyFunction() { ... } 
void Register() { 
    jclass cls = env->FindClass("Callback"); 
    jmethodID mid = env->GetMethodID(cls, "<init>", "(J)V"); 
    jvalue arg; 
    arg.j = (jlong)(void*)MyFunction; 
    jobject callback = env->NewObjectA(confCls, mid, &arg); 
} 

所以這給你一個全新的Callback對象,指向您的C函數!但是,那麼,你如何做到這一點?那麼,你必須通過JNI(步驟省略)傳遞迴調對象到Java,讓您的Java代碼中有回調對象從中調用你的C方法:

public class Foo { 
    public Callback callback; 
    public void doSomeStuff() { 
     ... 
     callback.doCallback(); 
    } 
}