Android系统主题设计和实现
- 博客分类:
- android
转自:http://www.apkbus.com/android-84276-1-1.html
智能手机何其多,Symbian、WP、Android...,问题是原生的Android系统不支持主题定制。
于是我等看着花哨的主题资源包在市场上泛滥,前提:你先下载一个运行这些主题资源的应用程序APK包先。
但是...... 原生Android系统是不愿意还是不能够支持主题呢?以后会不会支持呢?
不管了,既然看Android原生主题支持功能不够,本文就来尝试一下如何通过修改Android原生代码来实现主题支持。
============================= 环境与步骤=================================
软件版本:Android JellyBean
步骤:
I.原生Android主题支持需要涉及的部分
II.涉及部分在原生系统中的逻辑及修改
III.对周边模块的影响和支持
=============================原生Android主题支持需要涉及的部分=================================
既然是要支持主题,也就是说系统需要支持和管理多套主题资源包,并且应用可以用相同的资源ID来访问不同资源包中对应的资源。
因此我们首先分析一下Android系统的资源访问流程。
对应用来说,资源访问主要有下面三种方式:
第一、比较普遍的方式是使用xml定义,并且通过AAPT工具生成一个R文件,列出资源的索引来让Android系统自己去遍历整个资源树的方式来访问。
第二、通过Resources接口来访问,使用Resources类的getDrawable、getString等接口来获取资源。
第三、通过AssetManager类的接口去访问,使用这个类的open方法来返回一个InputStream对象得到资源。
其实这三个访问方式只是Android资源访问中整个流程中在不同层次对外提供的三个接口,到底层的实现都是殊途同归的。
第一种的xml定义的资源解析的逻辑在Resources.java文件的loadXmlResourceParser函数中,实际上也是调用的第三类接口,如下图:
因此我们实际上需要修改的部分主干是在访问资源具体路径前,按照当前系统主题设置访问不同资源APK下的文件
即是把原生Android中资源ID和资源文件路径之间一对一的关系改为一对多的关系。
例子如下:如果原有资源ID和资源文件路径关系为:
R.drawable.image01 = 0x7F020001
通过系统的资源查找之后找到文件路径为 /system/app/frameworks-res.apk下的res/drawable_hdpi/icon.png
在AssetManager native中去读取资源并上传。
那么我们需要做的是在传入路径去读取资源时把文件路径替换为/data/app/SystemTheme01.apk下的res/drawable_hdpi/icon.png
=============================涉及部分在原生系统中的逻辑及修改=================================
为了完成上篇所提到的修改,我们依上图分析一下原生系统中从传入资源ID到生成需要访问的资源文件的路径的过程:
Java层:
Resources类:
Android在Java层为应用层访问不同类型的资源提供了一系列接口,这些接口被封装在Resources类中,例如访问字符串资源的接口getString(),访问Drawable类型资源的接口getDrawable()等等。该类还管理着另外两个重要的类:Configuration和AssetManager。
Configuration类:
Configuration类中主要保存了当前的系统配置信息,例如字体、语言等,在应用调用Resources类的接口去获取资源的时候,Resources类会通过Configuration类来读取当前的系统配置信息,再结合接口中收到的应用请求获取的资源ID来获取对应的资源。
AssetManager类:
AssetManager类提供了以数据流的方式访问应用程序资源的方法。它主要是通过Native层的方法来实现访问资源的。AssetManager管理的资源主要有两个来源:一是应用程序的资源,通过访问应用程序的APK文件来得到;另外一个是系统资源,是通过访问包含系统资源的APK文件来获得。
Native层:
AssetManager Native类:
AssetManager Native类提供了对资源文件路径以及资源文件的操作支持,提供了诸如扫描APK的res路径下的文件夹和文件、对APK进行解压缩、维护ResTable类以及部分Cache加速文件的功能。
Asset类:
Asset类是所有类型资源类的基类,它提供了绝大部分对资源的操作实现和定义,是Android资源访问和文件访问层之间的桥梁,也是需要修改主干部分的核心。它封装了整个Android资源访问中对资源文件的路径查找以及资源从文件到数据流的转换过程。在应用传入资源ID来请求资源的时候,AssetManager会使用该类的create函数去生成一个新的资源对象,并使用读出的资源数据流赋给该对象,最后返回给上层应用。
下图列出了系统原有逻辑及需要修改的部分:
2012121023303511.jpg
上面的部分已经分析了资源访问过程中需要修改的部分,但是除了访问流程的主干之外,
系统在以下几个部分对资源访问效率做的优化同样会受到我们修改资源ID对应关系的影响。
系统的预加载资源流程
原有逻辑:
系统在启动的过程中会把系统常用的资源进行预载入,
此逻辑位于frameworks/base/core/java/com/android/internal/os/ZygoteInit.java -- preloadResources函数
在此函数中会调用Resources.java中函数来对com.android.internal.R.array.preloaded_XXX的资源数组中对应的资源进行预载入,
这个流程中会通过for循环预加载三类资源Drawable、ColorStateList、ColorDrawable,
并且存在对应的sPreloadedDrawables、sPreloadedColorStateLists、sPreloadedColorDrawables三个LongSparseArray的数组中。
修改逻辑:
因为主干部分已经对系统资源即framework-res.apk的资源进行了分别的处理,所以开机预载入的部分可以不做处理,
但是在主题变化之后,预载入的资源还是系统启动时候的数据,所以需要对三个数组进行清除或者启动后台服务重新进行预载入流程。
修改文件:Resources.java
实现功能:在系统使用的主题包变化之后清除预载入资源数组即上面提到的三个LongSparseArray数组(可以考虑后台重新载入新主题资源数据到数组中)。
系统访问中的资源缓存机制(清除cache)
原有逻辑:
在系统每次访问资源的过程中,查找资源的顺序是 预载入资源->Cache资源->资源文件
并且在每次通过资源文件的方式查找到资源之后会把此资源加入到Cache中,加速下次访问速度。
修改逻辑:
在主题设置被用户修改之后,原有缓存中的数据是上个主题包的文件内容,需要清除。
============================= 对周边模块的影响和支持=======================================
另:需要提供用户可以管理主题包的应用程序
原有逻辑:(无)
修改逻辑:
用户在安装了主题包之后,需要提供一个应用来维护当前系统上已经存在的资源主题包。
应用需要实现功能:扫描、预览、应用、卸载当前手机上已经安装的主题资源包。
主要涉及:PackageManager接口、systemProperty读写。
主题改变之后通知应用的广播
原有逻辑:
系统原有通知机制是ACTION_CONFIGURATION_CHANGE的Intent来通知应用系统配置改变,
如果应用不处理,系统会默认为应用更新系统配置(Activity资源、布局等的重新载入)。
修改逻辑:
在系统判断是否需要发送CONFIGURATION_CHANGE的逻辑中加入如下逻辑:
如果当前系统主题资源包发生变化,需要发送CONFIGURATION_CHANGE。
智能手机何其多,Symbian、WP、Android...,问题是原生的Android系统不支持主题定制。
于是我等看着花哨的主题资源包在市场上泛滥,前提:你先下载一个运行这些主题资源的应用程序APK包先。
但是...... 原生Android系统是不愿意还是不能够支持主题呢?以后会不会支持呢?
不管了,既然看Android原生主题支持功能不够,本文就来尝试一下如何通过修改Android原生代码来实现主题支持。
============================= 环境与步骤=================================
软件版本:Android JellyBean
步骤:
I.原生Android主题支持需要涉及的部分
II.涉及部分在原生系统中的逻辑及修改
III.对周边模块的影响和支持
=============================原生Android主题支持需要涉及的部分=================================
既然是要支持主题,也就是说系统需要支持和管理多套主题资源包,并且应用可以用相同的资源ID来访问不同资源包中对应的资源。
因此我们首先分析一下Android系统的资源访问流程。
对应用来说,资源访问主要有下面三种方式:
第一、比较普遍的方式是使用xml定义,并且通过AAPT工具生成一个R文件,列出资源的索引来让Android系统自己去遍历整个资源树的方式来访问。
第二、通过Resources接口来访问,使用Resources类的getDrawable、getString等接口来获取资源。
第三、通过AssetManager类的接口去访问,使用这个类的open方法来返回一个InputStream对象得到资源。
其实这三个访问方式只是Android资源访问中整个流程中在不同层次对外提供的三个接口,到底层的实现都是殊途同归的。
第一种的xml定义的资源解析的逻辑在Resources.java文件的loadXmlResourceParser函数中,实际上也是调用的第三类接口,如下图:
因此我们实际上需要修改的部分主干是在访问资源具体路径前,按照当前系统主题设置访问不同资源APK下的文件
即是把原生Android中资源ID和资源文件路径之间一对一的关系改为一对多的关系。
例子如下:如果原有资源ID和资源文件路径关系为:
R.drawable.image01 = 0x7F020001
通过系统的资源查找之后找到文件路径为 /system/app/frameworks-res.apk下的res/drawable_hdpi/icon.png
在AssetManager native中去读取资源并上传。
那么我们需要做的是在传入路径去读取资源时把文件路径替换为/data/app/SystemTheme01.apk下的res/drawable_hdpi/icon.png
=============================涉及部分在原生系统中的逻辑及修改=================================
为了完成上篇所提到的修改,我们依上图分析一下原生系统中从传入资源ID到生成需要访问的资源文件的路径的过程:
Java层:
Resources类:
Android在Java层为应用层访问不同类型的资源提供了一系列接口,这些接口被封装在Resources类中,例如访问字符串资源的接口getString(),访问Drawable类型资源的接口getDrawable()等等。该类还管理着另外两个重要的类:Configuration和AssetManager。
Configuration类:
Configuration类中主要保存了当前的系统配置信息,例如字体、语言等,在应用调用Resources类的接口去获取资源的时候,Resources类会通过Configuration类来读取当前的系统配置信息,再结合接口中收到的应用请求获取的资源ID来获取对应的资源。
AssetManager类:
AssetManager类提供了以数据流的方式访问应用程序资源的方法。它主要是通过Native层的方法来实现访问资源的。AssetManager管理的资源主要有两个来源:一是应用程序的资源,通过访问应用程序的APK文件来得到;另外一个是系统资源,是通过访问包含系统资源的APK文件来获得。
Native层:
AssetManager Native类:
AssetManager Native类提供了对资源文件路径以及资源文件的操作支持,提供了诸如扫描APK的res路径下的文件夹和文件、对APK进行解压缩、维护ResTable类以及部分Cache加速文件的功能。
Asset类:
Asset类是所有类型资源类的基类,它提供了绝大部分对资源的操作实现和定义,是Android资源访问和文件访问层之间的桥梁,也是需要修改主干部分的核心。它封装了整个Android资源访问中对资源文件的路径查找以及资源从文件到数据流的转换过程。在应用传入资源ID来请求资源的时候,AssetManager会使用该类的create函数去生成一个新的资源对象,并使用读出的资源数据流赋给该对象,最后返回给上层应用。
下图列出了系统原有逻辑及需要修改的部分:
2012121023303511.jpg
上面的部分已经分析了资源访问过程中需要修改的部分,但是除了访问流程的主干之外,
系统在以下几个部分对资源访问效率做的优化同样会受到我们修改资源ID对应关系的影响。
系统的预加载资源流程
原有逻辑:
系统在启动的过程中会把系统常用的资源进行预载入,
此逻辑位于frameworks/base/core/java/com/android/internal/os/ZygoteInit.java -- preloadResources函数
在此函数中会调用Resources.java中函数来对com.android.internal.R.array.preloaded_XXX的资源数组中对应的资源进行预载入,
这个流程中会通过for循环预加载三类资源Drawable、ColorStateList、ColorDrawable,
并且存在对应的sPreloadedDrawables、sPreloadedColorStateLists、sPreloadedColorDrawables三个LongSparseArray的数组中。
修改逻辑:
因为主干部分已经对系统资源即framework-res.apk的资源进行了分别的处理,所以开机预载入的部分可以不做处理,
但是在主题变化之后,预载入的资源还是系统启动时候的数据,所以需要对三个数组进行清除或者启动后台服务重新进行预载入流程。
修改文件:Resources.java
实现功能:在系统使用的主题包变化之后清除预载入资源数组即上面提到的三个LongSparseArray数组(可以考虑后台重新载入新主题资源数据到数组中)。
系统访问中的资源缓存机制(清除cache)
原有逻辑:
在系统每次访问资源的过程中,查找资源的顺序是 预载入资源->Cache资源->资源文件
并且在每次通过资源文件的方式查找到资源之后会把此资源加入到Cache中,加速下次访问速度。
修改逻辑:
在主题设置被用户修改之后,原有缓存中的数据是上个主题包的文件内容,需要清除。
============================= 对周边模块的影响和支持=======================================
另:需要提供用户可以管理主题包的应用程序
原有逻辑:(无)
修改逻辑:
用户在安装了主题包之后,需要提供一个应用来维护当前系统上已经存在的资源主题包。
应用需要实现功能:扫描、预览、应用、卸载当前手机上已经安装的主题资源包。
主要涉及:PackageManager接口、systemProperty读写。
主题改变之后通知应用的广播
原有逻辑:
系统原有通知机制是ACTION_CONFIGURATION_CHANGE的Intent来通知应用系统配置改变,
如果应用不处理,系统会默认为应用更新系统配置(Activity资源、布局等的重新载入)。
修改逻辑:
在系统判断是否需要发送CONFIGURATION_CHANGE的逻辑中加入如下逻辑:
如果当前系统主题资源包发生变化,需要发送CONFIGURATION_CHANGE。
发表评论
-
ActivityGroup 替代tabActivity
2013-12-26 16:43 2498转载自http://www.cnblogs.com/answe ... -
Android实战技巧:为从右向左语言定义复杂字串
2013-09-04 17:37 1089我们所使用的语言,无论是中文还是英语, ... -
Android 5种方式存储数据:
2013-05-08 17:17 1060Android 提供了5种方式存储数据: --使用Shared ... -
widget的设计与应用
2013-02-02 16:27 8851.AppWidgetProviderInfo对象 ... -
Android实现DES对字符串加密
2012-09-02 14:15 17098import java.io.Unsuppor ... -
android综合
2012-08-02 16:25 15521 ,手动设置横竖屏 TestA ... -
onSaveInstanceState
2012-08-01 17:40 681@Override //存储 public void onSa ... -
处理多个Activity
2012-07-20 09:40 670public class LifecycleManager ... -
bitmap 和drawable 互相转换
2012-07-19 13:37 622// bitmap to drawable; Drawable ... -
设置壁纸的三种方法
2012-07-19 11:46 23011111111111111111111111111111111 ... -
sqlite数据库处理时间问题 和 日期时间函数
2012-06-27 10:36 22784首先,sqlite数据库在时间 ... -
app缓存管理
2012-06-27 10:25 1016无论大型或小型应用, ... -
Uri、UriMatcher、ContentUris类使用介绍&&Android应用间数据共享之ContentProvider
2012-05-24 15:50 4378Android应用开发中我们会经常用Uri进行数据的处理,下面 ... -
getWidth()为0
2012-04-12 10:06 1964一般在刚开始开发android时,会犯一个错误,即在View的 ... -
自定义View 及使用
2012-04-05 14:08 743可能是一直都在做Web的富客户端开发的缘故吧,在接触Andro ... -
搜索手机联系人所有字段
2012-03-28 15:54 1386想取手机联系人的有效字段,但是苦于找不到API表示的字段变量, ... -
Andoid2.X各字段意义
2012-03-28 14:59 1207ContactsContract.Contacts.TIMES ... -
SMS发送流程
2012-03-20 18:07 1223发短信流程: 1 afterTextChanged{mWork ... -
Android telephony MMS 学习笔记
2012-03-14 13:32 2851转载 http://blog.csdn.net/tjy1985 ... -
Android_Mms源代码接受短信流程
2012-03-14 13:27 930短信来了之后framework会发送广播 “android.p ...
相关推荐
针对这样的实际问题,我们设计了一款图书馆订座系统。主要有四大功能模块,包括预订座位、查看座位、个人信息和我的步数。预订座位可以选3层楼,每层楼座位表不同,每位学生同一时间只能预订一个座位;查看座位的...
本文遵循了软件工程的标准开发流程,经过需求分析、总体设计、详细设计、系统实现和系统测试五大流程,最终完成了整个系统的开发。依据总体分析阶段的成果,本文将整个系统分为了六大功能模块,分别为登录注册模块、...
为了提升游戏体验,设计有背景音乐和系统主题,使玩家在轻松的氛围里进行游戏。目前提供青山鸟鸣和轻音乐两种背景音乐;黑白和清新两种主题。 4.分享功能 通过分享功能,玩家可以将APP链接通过微信等平台分享给其他...
# 安卓Android问卷调查系统设计 系统开发环境: Windows + Myclipse(服务器端) + Eclipse(手机客户端) + mysql数据库 服务器也可以用Eclipse或者idea等工具,客户端也可以采用android studio工具! 系统客户端和...
基于Android 的校园代跑腿系统的设计与实现 ( 源码 + 说明文档 + 演示视频) 4系统设计 14 4.1 系统概述 14 4.2 系统结构设计 14 4.3数据库设计 15 4.3.1 数据库实体 16 5统详细设计 17 5.1客户端主题功能模块 17 ...
系统有10多个页面,主要功能包含:添加、修改、删除和查询主题,主题包含日记、备忘录和联系人;添加、修改、删除和查看日记,在日记中添加图片、心情、天气和定位;对联系人的增删改查和拨号;对相册、相机和SD卡的...
本书内容翔实,从基础概念、工具环境的说明,Android系统框架的介绍,到骨架(skeleton)应用的探索以及一些相关高级主题的展开,适合不同背景的Android编程人员,是一本不错的Andorid编程指南。 如何才能构建设计...
毕业设计论文是学生完成学业的重要部分,这篇论文的主题是基于Android平台的图书管理系统手机客户。在这篇论文中,我们将介绍该系统的设计和实现,包括系统的需求分析、系统的架构设计、系统的功能模块、系统的测试...
基于android框架的客户端和基于servlet为服务端的物流配送系统地开发为主题的毕业设计,我开始对android的技术整合有新的认识,也熟悉对后端跟安卓端交互的过程与数据的对接。在做后端管理系统的时候。我又有学习到...
作为基于Linux的开源手机平台,Android包括一部手机工作所需的全部软件——操作系统、用户界面和应用程序,而且不存在任何以往阻碍移动产业创新的专有权障碍。谷歌公司与开放手机联盟合作开发了Android,这个联盟...
4.系统设计实现 25 4.1 开发环境搭建 25 4.1.1 window系统安装java 26 4.1.2安装配置Android Studio 30 4.1.3创建Android Studio工程 30 4.2 设计思路 31 4.2.1产生符合数独规则的初始矩阵 31 4.2.2 获胜条件 32 ...
本书内容翔实,从基础概念、工具环境的说明,Android系统框架的介绍,到骨架(skeleton)应用的探索以及一些相关高级主题的展开,适合不同背景的Android编程人员,是一本不错的Andorid编程指南。 如何才能构建设计...
基于B_S模式的网络教学辅助系统的设计与实现,我觉得作者写的不错
安卓Android问卷调查系统设计 系统开发环境: Windows + Myclipse(服务器端) + Eclipse(手机客户端) + mysql数据库 服务器也可以用Eclipse或者idea等工具,客户端也可以采用android studio工具! 系统客户端和...
Android系统概述,Android系统的开发综述,Android的Linux内核与驱动程序,Android的底层库和程序,Android的JAVA虚拟机 和JAVA环境,Android的GUI系统,Android的Audio系统,Android的Video 输入输出系统,Android的多媒体...
安卓Android新闻发布系统app 系统开发环境: Windows + Myclipse(服务器端) + Eclipse(手机客户端) + mysql数据库 服务器也可以用Eclipse或者idea等工具,客户端也可以采用android studio工具! 系统客户端和服务器...
Android系统概述,Android系统的开发综述,Android的Linux内核与驱动程序,Android的底层库和程序,Android的JAVA虚拟机 和JAVA环境,Android的GUI系统,Android的Audio系统,Android的Video 输入输出系统,Android的多媒体...
基于Android的电子签到模块的设计与实现 (源码 + 说明文档 + 演示视频) 4开发环境和系统设计 12 4.1 系统概述 12 4.2 系统结构设计 12 4.3开发环境搭建 13 4.3.1 java配置 13 4.3.2 HBuilder实例开发 14 5统详细...
## 系统客户端和服务器端架构技术: 界面层,业务逻辑层,数据层3层分离技术,MVC设计思想! ## 服务器和客户端数据通信格式: XML格式(用于传输查询的记录集)和json格式(用于传输单个的对象信息) 实验室管理、实验...