2013-09-26 24 views
3

在處理此問題幾天之後,我目前正在將我的桌子撞上。對於在運行時從jar文件中加載的類的FindClass

我的原生android應用程序在運行時加載一個類,這個工程我遵循this tutorial從資產文件夾中獲取dexed jar,並已加載該類併成功調用它的靜態方法。

但是,如果我跑......

env->FindClass("TheClass"); 

...它拋出一個Java異常。

這裏的代碼

//this works find and gives me a usable class 
jclass shim_class = helper.LoadClassFromAssetsJar("test.jar","TheClass"); 
// this throws the exception  
jclass refound_shim_class = jni->FindClass("TheClass"); 

任何幫助將是令人難以置信的,鄉親們的歡呼聲

+1

它與類加載器有關 - 您可能需要在JNI_OnLoad中執行所有「FindClass」調用,或者使用正確的類加載器以及「FindClass」調用。 – krsteeve

+1

有關如何解決[FindClass問題](http://developer.android.com/)的示例,請參見http://stackoverflow.com/questions/13263340/findclass-from-any-thread-in-android-jni guide/practices/jni.html#faq_FindClass)。我會說:如果你已經從你的裝載機上得到了這個課程,那就留待將來使用! –

回答

1

的相關位好有東西真正的範圍在這裏。

首先,@Alex Cohn表示,我們需要保留使用'global references'輕鬆完成的類,這將使得jobject(或jclass等)不會被重新分配,直到它被釋放。我正在考慮這個效果是線程局部的,因爲這是一些早期的Android版本(據我所知)

接下來,出於原因,我不會讓你在這裏,我們是使用DexClassloader,因爲我們正在加載我們的apk文件到資產文件夾(see here for how that works),所以我們也需要保持這一點。 FindClass只能在它自己的上下文中工作,它用於加載系統類(though you can load your own if you do this)

現在我們需要能夠在每個線程中使用apk類,所以我們在使用pthread_key爲每個線程創建緩存時運行declassloader.loadclass。這樣我們就可以在任何地方獲得類,並且通過keythread回調自動發生釋放。

無論如何這就夠了。祝你好運!

p.s.一個側面說明,一旦一個jni方法拋出了一個無用的異常,你不能保證任何其他調用都可以工作......有些會,有些不會,有些會導致段錯誤...因此,從java方面慷慨解囊,保護本地的Java免受噪音!

相關問題