您的位置:首页 > 移动开发 > Android开发

Android高级应用之 换肤 换主题 主题管理

2013-01-28 14:25 295 查看
Android高级应用之 换肤 换主题 主题管理

原创 Kwanvin 叶观平 转载请标明出处:

拿来卖的东西都需要金玉其外、一副好卖相,人靠衣装,鬼要画皮,同样APP也是一样。于是换肤是很多程序的一个很大的功能。

先来看看一个Android的皮肤的结构,我目前看到的应该是有三种:

1. zip压缩包,可以定义成许多不同的后缀,可自定义它的结构。

2. APK,这个其实也是zip,不过与纯粹的zip皮肤包不同的是,他有自己特定的结构。

3. SQLite 或者一个自定义结构的文件等等,我想称之为Datebase方式。

那么换肤有什么可行的思路呢?

联想一下Windows应用程序的换肤:把所有皮肤相关的配置参数和使用的图片、音频等资源都编译在dll(皮肤)里,应用程序通过加载不同的dll以实现加裁不同的皮肤。 又或者自定义一个皮肤结构(相当于自行设计dll的结构),那就更灵活了。 同样Android的App换肤也可以使用这种思路。实现的原理是如果两个APK的签名相同,配置SharedUserId值相同,则可以相互访问任意数据。

上面说的思路没有问题,不过只能针对某个程序自行换肤。试图想像一下这个情景:有个主题管理器设定了皮肤,它是不是得跟每个APP建立协议、协定接口,广播通知给每个APP进行皮肤的重新加载。这样的话每个APP都要增加有关切换皮肤的复杂代码,如果没有某个APP的代码你就无能为力了。

另外一种换肤的思路,是通过理解Android的加载皮肤资源的原理得到的。这也是本文想要记录的重点内容。Android中APP使用资源的步骤是这样的:通过Context得到Resource的指向,通过Resource的接口getDrawable getText getXml等传入资源ID来获得各种类型的资源。 这里说到的资源ID是关键,先加深下印象。

每个APK应用程序在启动时,会New 一个Resource,同时New一个AssetManager对象,AssetManager管理着一个AssetPath数组,可以通过addAssetPath来添加一个Path,通过openAssetPath来打开一个path。没错了,这个path就是资源包的路径。一个APK常常默认就会添加两个资源路径,一个是系统共享资源包,一个是APP本身的资源包。

重复一下这个执行路线: 启动APK->new Resource->new AssetManger->addAssetPath() 这样资源包就随着APK的启动而加载了;

APK使用资源->getResource->getDrawable(Id)->openAssetPath() 通过资源Id找到资源包,从资源包里解析出资源。

了解了这些后,思路很容易出来了,假设APP想加载放在另外一个资源包skin.zip的资源,那么只要在APK启动时为其addAssetPath(skin.zip),这时会返回一个索引cookie,在RunTime加载资源时使用这个cookie去打开skin.zip这个资源包来获取资源,而不是去APK本身的资源包里取。

资源Id蕴含了很多信息,通过资源Id,我们是可以知道其是神马类型的、属于哪个包的等等信息,另外资源Id以0x01开头就是系统资源,否则是属于本身APK的资源。知道这些后,我们就可以加入我们的资源选择策略代码了。 所谓的策略我是指资源应该优先从哪取,取不到怎么办,缺失了怎么办等。

从另一个角度看,上面说的第一种思路是在应用级别的做法,第二种思路是系统API级别的做法。如果改不了Framework的代码不用去折腾第二种。以这个思路可以实现包括Loyout等几乎所有资源的换肤。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: