[英]Keeping java methods called from Android JNI
我正試圖通過Proguard混淆Android應用程序代碼。 在使用proguard處理后,應用程序自行工作,但是從c到java的本機調用失敗了java.lang.NoSuchMethodError
。
此代碼來自本機部分,其中調用java類實例,名為EngineStarted:
void callEngineStarted( JNIEnv* env, bool isStreamOne )
{
jclass cls;
if(isStreamOne == true) {
cls = ( *env )->GetObjectClass( env, currentObjectOne );
} else {
cls = ( *env )->GetObjectClass( env, currentObjectTwo );
}
jmethodID midCallBack = ( *env )->GetMethodID( env, cls, "EngineStarted", "(I)V" );
if (0 == midCallBack) {
LOGW("Could not find EngineStarted method in class");
return;
}
if(isStreamOne == true) {
( *env )->CallVoidMethod( env, currentObjectOne, midCallBack, 1 );
} else {
( *env )->CallVoidMethod( env, currentObjectTwo, midCallBack, 0 );
}
}
java有這個方法。 它只從本機部分調用,而不是其他任何地方。 因此,proguard正在刪除該方法。
public void EngineStarted ( int isStreamOne )
{
Log.v( "decoderService", "PDecoder - Engine started, using stream " + ( isStreamOne == 1 ? "one" : "two" ) );
this.isStreamOne = isStreamOne == 1;
// Initialize the player
InitializePlayer( isStreamOne );
}
我已經嘗試將此添加到proguard-project.txt,但沒有解決問題。
-keep class com.emrahgunduz.AppBase.Services.PlayService.players.pDecoders.PDecoderNative {
void EngineStarted( int );
void PositionChanged( int );
void SetDuration( int );
void Completed();
void CompletedWithFade();
void Spectrum ( *** );
}
編譯后,mapping.txt不包含這些方法,我懷疑proguard會刪除它們。 如何保持這些方法被刪除和/或重命名?
編輯/解決方案:
我能夠通過使用通配符更改完整位置來解決問題。 這節省了一些方法,但還不夠。 不知道為什么但被傾銷的那個調用的另一個方法( void InitializePlayer(int)
)也被拋棄了,它以某種方式產生了連鎖反應。 添加此方法解決了剩余的遺漏方法。 最終的解決方案成了
-keepclassmembers class **.PDecoderNative {
native <methods>;
void InitializePlayer(int);
void EngineStarted(int);
void PositionChanged(int);
void SetDuration(int);
void Completed();
void CompletedWithFade();
void Spectrum(float[]);
}
編輯:問題不在於proguard,而是由於proguard無法不時讀取project.txt文件。 將整個項目移動到磁盤上的新位置並重新創建該文件。 它工作得很好。
您的分析是正確的,您的配置也是正確的。 您應該仔細檢查類的完全限定名稱(com.emrahgunduz.AppBase.Services.PlayService.players.pDecoders.PDecoderNative)。 請注意,您必須使用'$'而不是'。' 如果適用,將內部類別分開。
如果您指定了正確的名稱,您將在ProGuard在Android構建過程中寫出的文件proguard / seeds.txt中看到它們。
一旦這個工程,你可以替換-keep
通過-keepclassmembers
。 然后ProGuard仍會保留方法名稱,但會混淆類名,在這種情況下這很好。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.