apk 换肤之替换Context

替换Context也就是要拿到皮肤应用中的Context来获取其中的资源文件,重要的方法是:

 public Context createPackageContext (String packageName, int flags) 

packageName,皮肤应用的包名 

flags  有两个可选项:

 CONTEXT_IGNORE_SECURITY:忽略安全。

android默认是禁止直接从另一个程序中拿资源的,忽略安全,则强行获取资源,这里可以获取另一个程序RES目录下的文件。

这适合于皮肤包中没有代码和引入jar包,如布局中没有自定义View(涉及到反射构造View对象)。如果要用到代码,这里是行不通的,出现

Caused by: java.lang.ClassNotFoundException:自定义View
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:61)

CONTEXT_INCLUDE_CODE :包含代码。

包含代码,即Context中要有另一个程序中的源代码,这里必须将主程序和皮肤包在AndroidManifest.xml里设置

android:sharedUserId属性值相同,那么两个apk运行在同一个进程中,可以互相访问任意数据.注意:只访问资源时不需要添加该属性

值。不配置共享ID出现

Caused by: java.lang.SecurityException: Requesting code from com.fly.changeskin (with uid 10045) to be run in process com.fly.testskin (with uid 10046)


拿到Context就可以通过

inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

View view = inflater.inflate(R.layout.main_layout, null, false);   //填充布局

 context.getResources().getDrawable(R.drawable.ic_launcher);  //得到图片

这里要求的是应用与皮肤apk的资源名字,数量相同。总之保证两个R文件id相同,才能获取想要的资源。其次用到的jar包都要打包入apk。

这样完全替换,导致资源的冗余。但是几乎不用修改代码。


另外有:

 mSkinResources = context.getResources();

 int configResId = mSkinResources.getIdentifier(CONFIG_XML_NAME,"xml", mSkin);

 XmlPullParser xmlpull = mSkinResources.getXml(configResId);

只要求,文件与应用apk中对同一功能的皮肤文件名要一致
 例如:应用程序的背景图片路径:\WBlogSkin\res\drawable-hdpi\bg.png
   则皮肤apk中的背景图片文件路径也应该是SkinApk\res\drawable-hdpi\bg.png



猜你喜欢

转载自blog.csdn.net/zhouxinxin250/article/details/38317339
apk