动态替换/重新加载所有应用资源

时间:2018-07-19 17:14:41

标签: android dynamic-loading

这是一个有经验的问题。我正在尝试在运行时替换/重新加载应用程序的所有资源和/或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))

使其正常工作!


我只是想了解问题才能解决。那么对此有什么帮助吗?有什么读数吗?有没有这样做的开源项目?有什么意见吗?

0 个答案:

没有答案