2014-06-18 26 views
2

我正在移植我的應用程序,因此大部分工作都是在應用程序的本地部分完成的,而Java方面純粹是爲了我的UI。Android NDK對Java活動的回調

我想在這一刻實現的是一個ProgressBar,它將顯示本地線程的操作狀態。 UI由不同的活動組成,我打算從這些活動中顯示ProgressBars。

問題是:我該怎麼做?我有一些本地代碼,如下所示:

jclass clazz = emv->FindClass("com/example/myapp/MainActivity"); 

對clazz返回null。我意識到當時沒有實際顯示MainActivity活動 - 它是我的SettingsActivity的一個實例,所以我試着相應地更改上面的行,但它仍然返回null。

從本地代碼調用FindClass()來檢索Activity類是不可能的?

最終什麼,我想我需要做的是調用一個方法,如下面:

public void ProgressUpdateFromNative(int i) 
    { 
    runOnUiThread(new Runnable() 
    { 
     @Override 
     public void run() 
     { 
     DisplayProgressUpdate(); 
     } 
    }); 
    } 

..和那就是我的活動之一中的一個方法。

jmethodID ProgressUpdateFromNative = env->GetMethodID(clazz, "ProgressUpdateFromNative", "(I)V"); 
env->CallObjectMethod(g_pObj, ProgressUpdateFromNative, 1) ; 

我從的onLoad()JNI呼叫檢索在JavaVM指針和稱爲JavaVM-> AttachCurrentThread()來檢索上面使用的ENV指針。

有人可以告訴我我失蹤了什麼 - 即 - 爲什麼我得到從FindClass返回的null類,或者如果我正在做的是完全錯誤的話,請將我放在不同的軌道上。我打算閱讀處理程序,但我認爲我還沒有那麼深入。

注意:我意識到我可以從Java UI輪詢一些本地變量,但我更喜歡回調/事件處理實現而不是輪詢。

+0

如何是你的原生代碼,你做'的findClass()'調用來調用? –

+0

@Hans Kratz:我有一個pthread正在運行處理從Java活動發送到本地線程的消息。本地線程在循環中連續運行,並處理從Java UI獲取的所有消息。 – SparkyNZ

回答

2

如果您的代碼沒有從Java方法調用,它將使用僅知道Android系統類的FindClass()中的系統類加載器。

我建議使用獲得對JNI_OnLoad中類的引用,通過NewGlobalRef創建一個對該類的全局引用,並將其傳遞給您的線程或將其存儲在全局變量中。有關此行爲

更多信息:http://markmail.org/message/25rrwp4va443rjuk#query:+page:1+mid:2u5wlkjyugwp75qa+state:results

+0

我認爲你得到了正確的答案。只要看看我的NDK食譜,我注意到在OnLoad()函數內的MainActivity上調用了FindClass()。我不知道NewGlobalRef做什麼,但我會做一些閱讀和搜索。 – SparkyNZ

+1

在JNI中對Java對象(例如類)的引用通常只在獲取它們的幀是生命時纔有效。爲了延長生命期,您需要創建一個全局引用。請注意,這會阻止您創建全局引用的對象被垃圾收集。這就是爲什麼在通過普通對象的'DeleteGlobalRef'完成引用時刪除引用非常重要。 –

+0

@手克拉茨:謝謝你。所以如果我想獲得一個Activity的全局引用,這將是一件非常糟糕的事情嗎?我的MainActivity總是保持不變,但是如果設備被旋轉了,那麼它將被重新創建 - 所以我最終會得到2個Activity對象持久化,是否正確? - 即使只有一個活動有效且最新。我很早就想知道,如果它可能以某種方式在我的本地代碼「重新」創建時「註冊」一個Activity? – SparkyNZ