我尝试通过ProGuard对我的代码进行模糊处理,但是当我这样做时,它甚至都找不到AndroidManifest中定义的初始Activity(ClassNotFoundException)。
这是活动的外观:
public class LoadingActivity extends Activity
{
private static final String TAG = LoadingActivity.class.getSimpleName();
private int effectiveWidth;
private int effectiveHeight;
private AsyncTask<Void, Void, Void> bitmapLoaderTask;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_loading);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
initSpecs();
}
@Override
protected void onPause()
{
super.onPause();
if (bitmapLoaderTask != null)
{
bitmapLoaderTask.cancel(true);
}
}
@Override
protected void onStart()
{
super.onStart();
if (ResizedBitmapMapping.isStillHoldingAllImages())
{
Logger.log(TAG, "ResizedBitmapMapping still contains all images, skip loading...", LogController.isLoggingEnabled(), Log.DEBUG);
startMenu();
}
else
{
bitmapLoaderTask = new BitmapLoaderTask(getResources(), effectiveWidth, effectiveHeight, this);
bitmapLoaderTask.execute();
}
}
@SuppressWarnings("deprecation")
private void initSpecs()
{
PackageNameHolder.setPackageName(getPackageName());
WindowManager windowManager = (WindowManager)this.getSystemService(Context.WINDOW_SERVICE);
Point size = new Point();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2)
{
windowManager.getDefaultDisplay().getSize(size);
effectiveWidth = size.x;
effectiveHeight = size.y;
}
else
{
Display display = windowManager.getDefaultDisplay();
effectiveWidth = display.getWidth();
effectiveHeight = display.getHeight();
}
}
public void startMenu()
{
final Intent gameIntent = new Intent(this, MenuActivity.class);
startActivity(gameIntent);
overridePendingTransition(0, 0);
}
public void cancel()
{
finish();
}
}
我的proguard.cfg看起来像这样:
-dontoptimize
-dontshrink
-verbose
-keep class com.chartboost.** { *; }
-keep class * extends java.util.ListResourceBundle {
protected Object[][] getContents();
}
-keep public class com.google.android.gms.common.internal.safeparcel.SafeParcelable {
public static final *** NULL;
}
-keepnames @com.google.android.gms.common.annotation.KeepName class *
-keepclassmembernames class * {
@com.google.android.gms.common.annotation.KeepName *;
}
-keepnames class * implements android.os.Parcelable {
public static final ** CREATOR;
}
为了测试,我添加了
-keep class com.myproject.** { *; }
然后,该应用程序工作,但它没有混淆(很明显)。任何想法如何正确混淆?实际上这是ProGuard必须关心的事情,对吧?
这是启动应用时的错误消息:
10-25 00:29:04.600: E/AndroidRuntime(3299): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.mydomain.myapp/com.mydomain.myapp.LoadingActivity}: java.lang.ClassNotFoundException: com.mydomain.myapp.LoadingActivity in loader dalvik.system.PathClassLoader[/data/app/com.mydomain.myapp-2.apk]
10-25 00:29:04.600: E/AndroidRuntime(3299): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1680)
10-25 00:29:04.600: E/AndroidRuntime(3299): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1784)
10-25 00:29:04.600: E/AndroidRuntime(3299): at android.app.ActivityThread.access$1500(ActivityThread.java:123)
10-25 00:29:04.600: E/AndroidRuntime(3299): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:939)
10-25 00:29:04.600: E/AndroidRuntime(3299): at android.os.Handler.dispatchMessage(Handler.java:99)
10-25 00:29:04.600: E/AndroidRuntime(3299): at android.os.Looper.loop(Looper.java:130)
10-25 00:29:04.600: E/AndroidRuntime(3299): at android.app.ActivityThread.main(ActivityThread.java:3835)
10-25 00:29:04.600: E/AndroidRuntime(3299): at java.lang.reflect.Method.invokeNative(Native Method)
10-25 00:29:04.600: E/AndroidRuntime(3299): at java.lang.reflect.Method.invoke(Method.java:507)
10-25 00:29:04.600: E/AndroidRuntime(3299): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:864)
10-25 00:29:04.600: E/AndroidRuntime(3299): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:622)
10-25 00:29:04.600: E/AndroidRuntime(3299): at dalvik.system.NativeStart.main(Native Method)
10-25 00:29:04.600: E/AndroidRuntime(3299): Caused by: java.lang.ClassNotFoundException: com.mydomain.myapp.LoadingActivity in loader dalvik.system.PathClassLoader[/data/app/com.mydomain.myapp-2.apk]
10-25 00:29:04.600: E/AndroidRuntime(3299): at dalvik.system.PathClassLoader.findClass(PathClassLoader.java:240)
10-25 00:29:04.600: E/AndroidRuntime(3299): at java.lang.ClassLoader.loadClass(ClassLoader.java:551)
10-25 00:29:04.600: E/AndroidRuntime(3299): at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
10-25 00:29:04.600: E/AndroidRuntime(3299): at android.app.Instrumentation.newActivity(Instrumentation.java:1021)
10-25 00:29:04.600: E/AndroidRuntime(3299): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1672)
10-25 00:29:04.600: E/AndroidRuntime(3299): ... 11 more
[UPDATE]
如果我添加
-keep public class com.mydomain.myapp.LoadingActivity
它开始了,但它没有找到下一个Activity,因为它在AndroidManfest中搜索模糊的Activity?
10-25 13:20:16.159: E/AndroidRuntime(3195): android.content.ActivityNotFoundException: Unable to find explicit activity class {com.mydomain.myapp/com.mydomain.myapp.G}; have you declared this activity in your AndroidManifest.xml?
10-25 13:20:16.159: E/AndroidRuntime(3195): at com.mydomain.myapp.LoadingActivity.a(Unknown Source)
10-25 13:20:16.159: E/AndroidRuntime(3195): at com.mydomain.myapp.e.a.a(Unknown Source)
10-25 13:20:16.159: E/AndroidRuntime(3195): at com.mydomain.myapp.e.a.onPostExecute(Unknown Source)
答案 0 :(得分:3)
proguard.config
参数应为
proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
或用于优化,
proguard.config=${sdk.dir}/tools/proguard/proguard-android-optimize.txt:proguard-project.txt
这种方式包括必要的设置,例如:
# We want to keep methods in Activity that could be used in the XML attribute onClick
-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}
答案 1 :(得分:0)
目前,我对以下解决方案充满信心,但我更喜欢更好的混淆:
-dontoptimize
-dontshrink
-verbose
-flattenpackagehierarchy
-keepnames class com.mydomain.myapp.** { *; }
#...and some more classes for Google Services API