Android Add-in APK resource resources introduction
How do I load a resource file from an APK that is not installed? We found from the source code of Android.content.res.AssetManager.java, it has a private method addassetpath, just need to pass the APK path as a parameter, we can get the corresponding Assetsmanager object, then we can use a The Ssetsmanager object, creates a resources object, and then accesses the resource in the APK from the resource object. Summarized as follows:
- 1. Create a new Assetmanager object
- 2. Calling the Addassetpath method through reflection
- 3. Create the Resources object with the Assetsmanager object as a parameter.
The code is as follows:
Packagenet.mobctrl.hostapk;ImportJava.io.File;ImportAndroid.content.Context;ImportAndroid.content.res.AssetManager;ImportAndroid.content.res.Resources;/** * @Author Zheng haibo * @PersonalWebsite http://www.mobctrl.net * @version $Id: Loader Resmanager.java, v 0.1 December 11, 2015 PM 7:58:59 MOCHUAN.ZHB * EXP $ * @Description Dynamically loading the resource's manager */ Public class bundlerresourceloader { Private StaticAssetmanagerCreateassetmanager(String Apkpath) {Try{Assetmanager Assetmanager = AssetManager.class.newInstance ();Try{AssetManager.class.getDeclaredMethod ("Addassetpath", String.class). Invoke (Assetmanager, Apkpath); }Catch(Throwable th) {System.out.println ("Debug:createassetmanager:"+th.getmessage ()); Th.printstacktrace (); }returnAssetmanager; }Catch(Throwable th) {System.out.println ("Debug:createassetmanager:"+th.getmessage ()); Th.printstacktrace (); }return NULL; }/** * Get resources in bundle * @param context * @param apkpath * @return */ Public StaticResourcesGetbundleresource(Context context) {assetsmanager.copyallassetsapk (context); File dir = Context.getdir (Assetsmanager.apk_dir, context.mode_private); String Apkpath = Dir.getabsolutepath () +"/bundleapk.apk"; System.out.println ("Debug:apkpath ="+apkpath+", exists="+(NewFile (Apkpath). exists ()); Assetmanager Assetmanager = Createassetmanager (Apkpath);return NewResources (Assetmanager, Context.getresources (). Getdisplaymetrics (), Context.getresources (). GetConfiguration ()); }}
DEMO
Note: When we use the resources object, we must pass the ID of the resource that corresponds to the R file in the offline apk when we get the resource. If you use the Getidentifier method, the first parameter is the resource name, the second parameter is the resource type, the third parameter is the package name of the offline apk, and the third parameter is remembered.
Resources resources = Bundlerresourceloader.getbundleresource (Getapplicationcontext ()); ImageView = (ImageView) Findviewbyid (R.ID.IMAGE_VIEW_IV);if(Resources! =NULL) {String str = resources.getstring (Resources.getidentifier ("Test_str","string","net.mobctrl.normal.apk")); String Strbyid = resources.getstring (0x7f050001);//Note, ID reference bundle APK in R fileSystem.out.println ("Debug:"+STR); Toast.maketext (Getapplicationcontext (), Strbyid, Toast.length_short). Show (); drawable drawable = resources.getdrawable (0x7f020000);//Note, ID reference bundle APK in R fileImageview.setimagedrawable (drawable); }
The above code is the string and drawable resources loaded in the offline apk, then the layout resource?
Problem Introduction
We use Layoutinflate objects, which are generally used in the following ways:
null);
Which, r.layout.main_fragment we can get their ID by the above method, then the key step is how to generate a context? It is not possible to pass directly to the current context.
The solution has 2:
-1. Create a contextimpl,override of its own method.
-2. Directly replace the Mresources private member variable of the current context through reflection. <>br
Of course, we are using the second scenario:
@Override protected void Attachbasecontext(Context context) {replacecontextresources (context);Super. Attachbasecontext (context); }/** * Using the resource object of the bundle, replace the Mresources object of the context with a reflection * @param context * * Public void replacecontextresources(Context context) {Try{Field field = Context.getclass (). Getdeclaredfield ("Mresources"); Field.setaccessible (true); Field.set (context, mbundleresources); System.out.println ("Debug:repalceresources succ"); }Catch(Exception e) {System.out.println ("Debug:repalceresources Error"); E.printstacktrace (); } }
We replace the context Mresources in the Attachbasecontext method of the activity so that we can load the layout in the offline apk.
Packaging process for resource files
If you want to plug-in, you need to understand the Android resource file packaging process, so that each plug-in can be numbered, and then follow the rules to generate r files. For example, take Ctrip dynamicapk as an example, it will plug-in R files according to the following rules:
- The 1.R file is of type int, and the first 8 bits represent the ID of the plugin, of which two special id:host are the 0x7f,android system that comes with the start of 0x01.
- 2. The following 8-bit is a resource-sensitive type, such as layout,id,string,dimen, etc.
- 3. The back 16 bits are the number of the resource
Follow the above rules to generate the corresponding plugin apk. Then, at run time, we can write a ResourceManager class that inherits from the resource object, and then all the activity changes the Mresource member variable of its context to the ResourceManager class, Then override its method and then, when loading the resource, look for the resource of the corresponding plug-in based on the prefix of the different IDs. In other words, a class is used for distribution.
Android Plugin related data
- 1.Android Dynamic loading basic classloader working mechanism http://segmentfault.com/a/1190000004062880
- 2.Android Dynamic loading Black technology dynamically create activity mode http://segmentfault.com/a/1190000004077469
- 3.Android Plugin Framework GitHub Summary Https://github.com/liaohuqiu/android-dynamic-load-awesome
- 4. Ctrip Dynamic loading framework source code Https://github.com/CtripMobile/DynamicAPK
- 5. Ctrip Android App plugin and dynamic loading practice http://www.infoq.com/cn/articles/ctrip-android-dynamic-loading
- 6.dex Sub-package deformation record http://mp.weixin.qq.com/s?__biz=MzA3NTYzODYzMg==&mid=401345907&idx=1http://mp.weixin.qq.com/ s?__biz=mza3ntyzodyzmg==&mid=401345907&idx=1&sn=debdddf25950aaaa10f575472629b557
- 7. The major hot patch solution analysis and comparison http://blog.zhaiyifan.cn/2015/11/20/HotPatchCompare/
- 8.Android App on-line heat repair solution http://lirenlong.github.io/hotfix/
- 9.Android Hot Patch Dynamic Repair Framework Summary http://blog.csdn.net/lmj623565791/article/details/49883661
- 10.Android Thermal Update Implementation principle http://blog.csdn.net/lzyzsd/article/details/49843581
- 11. "New skill get" lets apps publish new versions like the Web http://bugly.qq.com/blog/?p=781
- 12.Android Dynamic Loading Technology Series index http://segmentfault.com/a/1190000004086213
- 13.Android load http://blog.csdn.net/dzg1977/article/details/41683173 for third-party class library runtime
- 14. about how Android dynamically loads res http://nobodycare.me/2014/11/07/about-loading-res-from-apk-directly/
- 15.Android application Resource Compilation and packaging process analysis http://blog.csdn.net/luoshengyang/article/details/8744683
- 16.Android Application Explorer (Asset Manager) creation Process Analysis http://blog.csdn.net/luoshengyang/article/details/8791064
- 17.Android Auto Compile, package build apk file 1-command line mode http://blog.csdn.net/androiddevelop/article/details/10948639
Android Plugin (iii) load plugin APK for resource resources