友盟SDK 混淆 问题

集成友盟的意见反馈和统计SDK,混淆后出现如下问题:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.shenzy.boke/com.umeng.fb.ConversationActivity}: java.lang.IllegalArgumentException: ResClass is not initialized. Please make sure you have added neccessary resources. Also make sure you have com.shenzy.boke.R$* configured in obfuscation. field=umeng_fb_activity_conversation


说明resource找不到的问题。究其原因,由于SDK需要引用导入工程的资源文件,通过了反射机制得到资源引用文件R.java,但是在开发者通过proguard等混淆/优化工具处理apk时,proguard可能会将R.java删除。

详见其官网FAQ:http://dev.umeng.com/analytics/reference/faq


这里涉及到的一个问题是 jar包里面通过反射机制获取资源文件。

做jar,jar代码获取资源不能直接引用 R.xx.name,

有两种方法:

1.通过方法: int android.content.res.Resources.getIdentifier(String name, String defType, String defPackage)

2.通过反射

第一种方法比较常见,主要看第二种方法:


[java] view plain copy
  1. publicclass ResoureExchange {

  2. privatestaticfinal String TAG = ResoureExchange.class.getName();

  3. privatestatic ResoureExchange self;

  4. private Context mContext;

  5. privatestatic Class<?> CDrawable = null;

  6. privatestatic Class<?> CLayout = null;

  7. privatestatic Class<?> CId = null;

  8. privatestatic Class<?> CAnim = null;

  9. privatestatic Class<?> CStyle = null;

  10. privatestatic Class<?> CString = null;

  11. privatestatic Class<?> CArray = null;

  12. publicstatic ResoureExchange getInstance(Context context){

  13. if(self == null){

  14. self = new ResoureExchange(context);

  15. }

  16. return self;

  17. }

  18. private ResoureExchange(Context context){

  19. this.mContext = context.getApplicationContext();

  20. try{

  21. CDrawable = Class.forName(this.mContext.getPackageName() + ".R$drawable");

  22. CLayout = Class.forName(this.mContext.getPackageName() + ".R$layout");

  23. CId = Class.forName(this.mContext.getPackageName() + ".R$id");

  24. CAnim = Class.forName(this.mContext.getPackageName() + ".R$anim");

  25. CStyle = Class.forName(this.mContext.getPackageName() + ".R$style");

  26. CString = Class.forName(this.mContext.getPackageName() + ".R$string");

  27. CArray = Class.forName(this.mContext.getPackageName() + ".R$array");

  28. }catch(ClassNotFoundException e){

  29. Log.i(TAG,e.getMessage());

  30. }

  31. }

  32. publicint getDrawableId(String resName){

  33. return getResId(CDrawable,resName);

  34. }

  35. publicint getLayoutId(String resName){

  36. return getResId(CLayout,resName);

  37. }

  38. publicint getIdId(String resName){

  39. return getResId(CId,resName);

  40. }

  41. publicint getAnimId(String resName){

  42. return getResId(CAnim,resName);

  43. }

  44. publicint getStyleId(String resName){

  45. return getResId(CStyle,resName);

  46. }

  47. publicint getStringId(String resName){

  48. return getResId(CString,resName);

  49. }

  50. publicint getArrayId(String resName){

  51. return getResId(CArray,resName);

  52. }

  53. privateint getResId(Class<?> resClass,String resName){

  54. if(resClass == null){

  55. Log.i(TAG,"getRes(null," + resName + ")");

  56. thrownew IllegalArgumentException("ResClass is not initialized. Please make sure you have added neccessary resources. Also make sure you have " + this.mContext.getPackageName() + ".R$* configured in obfuscation. field=" + resName);

  57. }

  58. try {

  59. Field field = resClass.getField(resName);

  60. return field.getInt(resName);

  61. } catch (Exception e) {

  62. Log.i(TAG, "getRes(" + resClass.getName() + ", " + resName + ")");

  63. Log.i(TAG, "Error getting resource. Make sure you have copied all resources (res/) from SDK to your project. ");

  64. Log.i(TAG, e.getMessage());

  65. }

  66. return -1;

  67. }

  68. }




你可能感兴趣的:(resource,混淆,友盟SDK)