RePlugin
RePlugin copied to clipboard
插件中 getIdentifier("status_bar_height", "dimen", "android")获取状态栏高度抛出ResoureNotFound
问题详细描述 Detailed description of the problem
int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android"); return context.getResources().getDimensionPixelSize(resourceId); 如上使我们常见的获取系统状态栏高度的一种做法,我的插件中刚好有这样的代码。然后编译运行就会报.Resources$NotFoundException
我去掉build.gradle中的apply plugin: 'replugin-plugin-gradle'之后,就不会报错。
目前我已经发现通过反射来获取就不会报错, Class<?> clazz = Class.forName("com.android.internal.R$dimen"); Object object = clazz.newInstance(); int id = Integer.parseInt(clazz.getField("status_bar_height") .get(object).toString()); statusBarHeight = context.getResources().getDimensionPixelSize(id);
复现问题步骤 Steps to reproduce the problem
- 在插件中的AppcompatActivtiy中使用如上获取状态栏高度的代码
- 编译成apk,然后运行到这里就会报错,说找不到资源
- 如果不使用插件编译就不会报错
其它重要信息 Other important information
replugin-host-lib/gradle Version:2.2.0 rePlugin-plugin-lib/gradle Version:2.2.0
Android API Version: Android 手机型号&ROM(Phone model & ROM): 测试过的手机 华为 ,小米
Logcat上下文 Logcat context
FATAL EXCEPTION: main Process: com.sohu.kuaizhan.z4394396021, PID: 1009 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.sohu.kuaizhan.z4394396021/com.sohu.kuaizhan.z4394396021.loader.a.ActivityN1NRNTS1}: android.content.res.Resources$NotFoundException: Resource ID #0x0 at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2451) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2511) at android.app.ActivityThread.access$900(ActivityThread.java:165) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1375) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:150) at android.app.ActivityThread.main(ActivityThread.java:5621) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:794) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:684) Caused by: android.content.res.Resources$NotFoundException: Resource ID #0x0 at android.content.res.Resources.getValue(Resources.java:1384) at android.content.res.Resources.getDimensionPixelSize(Resources.java:725) at lib.kuaizhan.sohu.com.baselib.util.StatusBarUtil.getStatusBarHeight(StatusBarUtil.java:409) at com.kuaizhan.live.activity.LiveBeginActivity.initView(LiveBeginActivity.java:78) at com.kuaizhan.live.activity.LiveBeginActivity.onCreate(LiveBeginActivity.java:53) at android.app.Activity.performCreate(Activity.java:6367) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1110) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2404) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2511) at android.app.ActivityThread.access$900(ActivityThread.java:165) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1375) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:150) at android.app.ActivityThread.main(ActivityThread.java:5621) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:794) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:684)
你尝试用宿主的上下文试试,你这好像是插件的上下文
出现这个问题的原因是,Gradle插件,在编译期对插件中 Resource.getIdentifier() 的使用做了替换,详见:
https://github.com/Qihoo360/RePlugin/blob/dev/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/injector/Injectors.groovy https://github.com/Qihoo360/RePlugin/tree/dev/replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/injector/identifier
下一版本我们会修复这个问题。
请先使用反射的方式吧 。
感谢。
@pngfi @lizhanzhishang
这个问题,在2.3.0上获取到的状态栏高度为0
@cundong 可否提供一下解决思路,我们自己修改下你们的代码。
修改 plugin gradle 如果第三个参数是 android 则不替换成插件的包名
1.方法一,使用反射宿主里的工具类
try { /* 在宿主里创建Utils类 public class Utils { public static int getIdentifier(Context context,String name, String defType, String defPackage){ if (context == null) return 0; return context.getResources().getIdentifier(name,defType,defPackage); } } */ float barHeight = -1; Class claz = RePlugin.getHostClassLoader().loadClass("com.zcm.host.demo.Utils"); Method method = claz.getMethod("getIdentifier", Context.class,String.class,String.class,String.class); Object heightId = method.invoke(null,getBaseContext(),"status_bar_height", "dimen", "android"); int heightIdInt = Integer.valueOf(heightId+""); if (heightIdInt != 0){ barHeight = getResources().getDimension(heightIdInt); } Log.i("ZCM_plugin","heightId:"+heightId+",barHeight:"+barHeight); }catch (Exception e){ e.printStackTrace(); }
2.方法二 修改gradle 插件 replugin-plugin-gradle/src/main/groovy/com/qihoo360/replugin/gradle/plugin/injector/identifier/GetIdentifierExprEditor.groovy 修改为 m.replace('{ $3 = "android".equalsIgnoreCase($3)? $3 : "' + CommonData.appPackage + '"; ' + '$_ = $proceed($$);' + ' }')
@zhangcb666 大佬修改gradle插件怎么编译啊