簡體   English   中英

保持從Android JNI調用java方法

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM