emr*_*duz 7 java java-native-interface android proguard android-ndk
我正试图通过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 );
}
}
Run Code Online (Sandbox Code Playgroud)
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 );
}
Run Code Online (Sandbox Code Playgroud)
我已经尝试将此添加到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 ( *** );
}
Run Code Online (Sandbox Code Playgroud)
编译后,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[]);
}
Run Code Online (Sandbox Code Playgroud)
编辑:问题不在于proguard,而是由于proguard无法不时读取project.txt文件.将整个项目移动到磁盘上的新位置并重新创建该文件.它工作得很好.
您的分析是正确的,您的配置看起来也正确。您应该仔细检查您的类的完全限定名称 (com.emrahgunduz.AppBase.Services.PlayService.players.pDecoders.PDecoderNative)。请注意,您必须使用 '$' 而不是 '.' 分隔内部类(如果适用)。
如果您指定了正确的名称,您将在 ProGuard 在 Android 构建过程中写出的文件 proguard/seeds.txt 中看到它们。
一旦成功,您可以替换-keep为-keepclassmembers. ProGuard 仍然会保留方法名称,但会混淆类名称,这在这种情况下很好。
| 归档时间: |
|
| 查看次数: |
6235 次 |
| 最近记录: |