gpt4 book ai didi

java - 保留从 Android JNI 调用的 java 方法

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:02:34 25 4
gpt4 key购买 nike

我正在尝试通过 Proguard 混淆 Android 应用程序代码。使用 proguard 处理后,应用程序自行运行,但是从 c 到 java 的 native 调用失败并显示 java.lang.NoSuchMethodError

此代码来自 native 部分,其中调用了名为 EngineStarted 的 java 类实例:

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有这个方法。它只从 native 部分调用,而不是其他任何地方。因此,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)) 也被转储,这不知何故产生了链式 react 。添加此方法解决了剩余的缺失方法。最终的解决方案变成了

-keepclassmembers class **.PDecoderNative {
native <methods>;
void InitializePlayer(int);
void EngineStarted(int);
void PositionChanged(int);
void SetDuration(int);
void Completed();
void CompletedWithFade();
void Spectrum(float[]);
}

编辑: 问题不在于混淆器,而是混淆器无法不时读取 project.txt 文件。将整个项目移动到磁盘上的新位置并重新创建文件。它运行良好。

最佳答案

您的分析是正确的,您的配置看起来也是正确的。您应该仔细检查您的类的完全限定名称 (com.emrahgunduz.AppBase.Services.PlayService.players.pDecoders.PDecoderNative)。请注意,您必须使用“$”而不是“.”。分隔内部类(如果适用)。

如果您指定了正确的名称,您将在 ProGuard 在 Android 构建过程中写出的文件 proguard/seeds.txt 中看到它们。

一旦成功,您可以将 -keep 替换为 -keepclassmembers。 ProGuard 随后仍会保留方法名称,但会混淆类名称,这在这种情况下很好。

关于java - 保留从 Android JNI 调用的 java 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24910171/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com