Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PerferenceActivity with PreferenceFragment fails on device with proguard okay without proguard

I'm coding my first app targeting ICS (4.0.3 - level 15). I get Action Bars and I think they're great. But I'm trying fragments for the first time, and I'm still not sure if I like 'em or not. The app I'm currently working on doesn't need fragments since it has pretty undynamic on screen requirements. Standard activities are working fine. The big However is that I have to use PreferenceActivity with PreferencFragment and Headers. The old form of the activity straight to the preference definition xml file has been depreciated. So I learned to use preference fragments for the preferences display by force of Google. (By the way, has anybody figured out how to skip displaying headers. I used two for a learning experience. One pointing to a single fragment class would have been sufficient. But it looks bad to have to double select with only one header...)

I have been using the emulator thing until about 3 days ago and everything was working. When I moved testing to the device, I could get the preferences screen that displayed the headers (PreferenceActivity class). But, when I selected a header (which calls the PreferencesFragment class), I received the "sorry your app stopped' message. Back on the emulator, everything worked correctly. It finally dawned on me that I was using Proguard when I generate my APK. Since all the views were driven by standard activities except for my Settings activity most everything worked. When I turned off Proguard, everything worked including Settings. In my Crittercism crash report, the error generated when Proguard is on is class not found. The class not found is the inline PreferenceFragment class.

For instance, using the header

android:fragment="com.mycompany.projectname.FragmentPreferences$SettingsFragment" 

the inline class SettingsFragment is not found by the Android OS running on the device.

Turn off Proguard and reinstall the APK and the above header works fine. With or without Proguard, the PreferenceActivity class FragmentPreferences is always found and the headers display. It fails when selecting a displayed header (invokation of SettingsFragment)...

I tried -dontoptimize and -dontshrink, but my app still wont work with Proguard on. My Proguard settings are standard; i.e., generated when I create a new app using the Eclipse wizard (ADT R20 - latest and greatest). Here are the settings I'm trying to run with:

In project-properties:

proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt

target=Google Inc.:Google APIs:15

In proguard-project:

-keepattributes SourceFile, LineNumberTable

-dontshrink

-dontoptimize

All standard activities (no fragments) work fine with the basic settings. The -dont's were added in an attempt to limit Proguard to obfuscation only. Settings still blowup when the inline fragment class is called.

Currently I'm generating the APK with Proguard turned off. When I'm ready to go production, I would like to turn it back on.

(BTW, I moved the PreferenceFragment classes to external classes and they still don't work when Proguard is invoked.)

I've entered more than enough stuff here and still haven't asked my question. Okay, I'll shut this down with the question:

Does anybody know the correct Proguard settings required to make shared preference fragment classes visible? And if this problem extends to regular fragment use, what are those settings?

like image 841
Howard Hodson Avatar asked Jul 20 '12 17:07

Howard Hodson


2 Answers

I would use -keep class your.package.goes.here.** { *; }, to make sure ProGuard does not get rid of any of your own classes, including your fragments referenced by layouts or other resources instead of code.

Note that I am no ProGuard expert, and so this may be "swatting a fly with a Buick", but it works for me, including my PreferenceFragments.

like image 121
CommonsWare Avatar answered Oct 21 '22 03:10

CommonsWare


Make Changes To Your proguard-project.txt as

-keep public class * extends android.preference.Preference
-keep public class * extends android.preference.PreferenceFragment
-keep public class * extends android.preference.PreferenceActivity
like image 33
Arunkumar Avatar answered Oct 21 '22 05:10

Arunkumar