I try to obfuscate my code by ProGuard, but when I do that, it does not even find the initial Activity defined in AndroidManifest anymore (ClassNotFoundException).
This is how the Activity looks:
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();
}
}
My proguard.cfg looks like this:
-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;
}
For testing I added
-keep class com.myproject.** { *; }
then, the app works, but it's not obfuscated (which is clear). Any ideas how to obfuscated properly? Actually this is something ProGuard has to care about, right?
This is the error message while starting the app:
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]
If I add
-keep public class com.mydomain.myapp.LoadingActivity
it starts, but then it doesn't find the next Activity, because it searches in AndroidManfest for the obfuscated Activities?
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)
proguard.config
parameter should be
proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
or for optimization,
proguard.config=${sdk.dir}/tools/proguard/proguard-android-optimize.txt:proguard-project.txt
This way necessary settings are included, such as:
# 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);
}
At the moment I'm partly confident with the following solution, but I'd prefer a better obfuscation:
-dontoptimize
-dontshrink
-verbose
-flattenpackagehierarchy
-keepnames class com.mydomain.myapp.** { *; }
#...and some more classes for Google Services API
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.