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等几乎所有资源的换肤。
原创 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等几乎所有资源的换肤。
相关文章推荐
- android开发笔记之高级主题—传感器的简单应用
- Android 应用换肤功能(白天黑夜主题切换)
- Android 应用换肤功能(白天黑夜主题切换)
- Android高级应用开发(基础篇) - stage7 - 学习笔记
- Android 主题切换/换肤方案 研究(二) - 简书
- android ssl双向验证 X509证书信任管理器类的实现及应用
- Android主题应用
- Android应用开发中的风格和主题(style,themes)
- 轻听变色之谜-如何改变Android应用的主题色
- 让你的Android应用能使用多种主题 ( Part 2 )
- 【Android 应用开发】 ActionBar 样式具体解释 -- 样式 主题 简单介绍 Actionbar 的 icon logo 标题 菜单样式改动
- Android电源管理相关应用技巧分享
- Mysql DBA 高级运维学习笔记-mysql数据库常用管理应用
- 【Android 应用开发】 ActionBar 样式详解 -- 样式 主题 简介 Actionbar 的 icon logo 标题 菜单样式...
- 【Android高级】查看手机及应用内存状况的方法
- 【Android开发基础】应用界面主题Theme使用方法
- Android应用界面主题Theme使用方法
- Android应用开发中的风格和主题(style,themes)
- Android开发之应用管理(RecyclerView的不同position使用不同的View)
- Android应用开发---SQLiteOpenHelper管理SQLite数据库、ListView