这是一个有经验的问题。我正在尝试在运行时替换/重新加载应用程序的所有资源和/或dex文件,因此当应用程序重新启动时,它会使用新的资源和/或新的dex文件。
dex的加载非常简单,并且有很多代码示例和库可以帮助甚至从apk加载dex,当然存在很多问题,但是大多数问题与未找到的类/方法有关。
我当前的大问题是应用程序资源的加载/替换,包括xml,drawables等,甚至内部使用的Android库资源,这些资源都将在运行时动态添加,因此无论何时加载的dex代码搜索任何可以轻松找到的资源。
我搜索了很多但没有运气,我发现的代码类似于:
protected void loadResources(String dexPath) throws InstantiationException, IllegalAccessException, IllegalArgumentException,
InvocationTargetException, NoSuchMethodException, NoSuchFieldException {
Log.d(LOG_TAG, "MyApplication : loadResources()");
AssetManager am = (AssetManager) AssetManager.class.newInstance();
am.getClass().getMethod("addAssetPath", String.class).invoke(am, dexPath);
mAssetManager = am;
Constructor<?> constructor_Resources = Resources.class.getConstructor(AssetManager.class, cc.getResources().getDisplayMetrics().getClass(), cc.getResources().getConfiguration().getClass());
mResources = (Resources) constructor_Resources.newInstance(am, cc.getResources().getDisplayMetrics(), cc.getResources().getConfiguration());
mTheme = mResources.newTheme(); // mTheme.applyStyle(android.R.style.Theme_Light_NoTitleBar_Fullscreen, true);
mTheme.applyStyle(android.R.style.Theme_DeviceDefault, true);
}
,但是此代码不会使已加载的资源可见/已存在,无法从内部库(例如appCompat lib)访问,而已加载dex的某些AppCompatActivity使用它。并抛出错误:
ResourcesNotFoundException, the searched id is not a Drawable
这是完整的异常日志:
7-19 17:26:36.260 2028-2028/com.example.test E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.test, PID: 2028
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.test/com.example.test.MainActivity}: android.content.res.Resources$NotFoundException: Resource "com.example.test:id/search_mag_icon" (7f070059) is not a Drawable (color or path): TypedValue{t=0x12/d=0x0 a=3 r=0x7f070059}
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2521)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2601)
at android.app.ActivityThread.access$800(ActivityThread.java:178)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1470)
at android.os.Handler.dispatchMessage(Handler.java:111)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5637)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:960)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
Caused by: android.content.res.Resources$NotFoundException: Resource "com.example.test:id/search_mag_icon" (7f070059) is not a Drawable (color or path): TypedValue{t=0x12/d=0x0 a=3 r=0x7f070059}
at android.content.res.Resources.loadDrawableForCookie(Resources.java:2690)
at android.content.res.Resources.loadDrawable(Resources.java:2614)
at android.content.res.Resources.getDrawable(Resources.java:900)
at android.content.Context.getDrawable(Context.java:408)
at android.support.v4.content.ContextCompat.getDrawable(ContextCompat.java:351)
at android.support.v7.widget.AppCompatDrawableManager.getDrawable(AppCompatDrawableManager.java:200)
at android.support.v7.widget.AppCompatDrawableManager.getDrawable(AppCompatDrawableManager.java:188)
at android.support.v7.widget.AppCompatDrawableManager.checkVectorDrawableSetup(AppCompatDrawableManager.java:755)
at android.support.v7.widget.AppCompatDrawableManager.getDrawable(AppCompatDrawableManager.java:193)
at android.support.v7.widget.TintTypedArray.getDrawableIfKnown(TintTypedArray.java:87)
at android.support.v7.app.AppCompatDelegateImplBase.<init>(AppCompatDelegateImplBase.java:128)
at android.support.v7.app.AppCompatDelegateImplV9.<init>(AppCompatDelegateImplV9.java:149)
at android.support.v7.app.AppCompatDelegateImplV11.<init>(AppCompatDelegateImplV11.java:29)
at android.support.v7.app.AppCompatDelegateImplV14.<init>(AppCompatDelegateImplV14.java:54)
at android.support.v7.app.AppCompatDelegate.create(AppCompatDelegate.java:202)
at android.support.v7.app.AppCompatDelegate.create(AppCompatDelegate.java:183)
at android.support.v7.app.AppCompatActivity.getDelegate(AppCompatActivity.java:519)
at android.support.v7.app.AppCompatActivity.onCreate(AppCompatActivity.java:70)
at com.example.test.ui.MainActivity.onCreate(MainActivity.java:61)
at android.app.Activity.performCreate(Activity.java:6100)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1112)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2468)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2601)
at android.app.ActivityThread.access$800(ActivityThread.java:178)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1470)
at android.os.Handler.dispatchMessage(Handler.java:111)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5637)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:960)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
即使setContentView(R.layout.my_layout)
不起作用,您也必须将其更改为
setContentView(View.inflate(getApplicationContext(), R.layout.my_layout, null))
使其正常工作!
我只是想了解问题才能解决。那么对此有什么帮助吗?有什么读数吗?有没有这样做的开源项目?有什么意见吗?