转自: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 2544转载自http://www.cnblogs.com/answe ... -
Android实战技巧:为从右向左语言定义复杂字串
2013-09-04 17:37 1146我们所使用的语言,无论是中文还是英语, ... -
Android 5种方式存储数据:
2013-05-08 17:17 1104Android 提供了5种方式存储数据: --使用Shared ... -
widget的设计与应用
2013-02-02 16:27 9321.AppWidgetProviderInfo对象 ... -
Android实现DES对字符串加密
2012-09-02 14:15 17163import java.io.Unsuppor ... -
android综合
2012-08-02 16:25 15941 ,手动设置横竖屏 TestA ... -
onSaveInstanceState
2012-08-01 17:40 728@Override //存储 public void onSa ... -
处理多个Activity
2012-07-20 09:40 711public class LifecycleManager ... -
bitmap 和drawable 互相转换
2012-07-19 13:37 652// bitmap to drawable; Drawable ... -
设置壁纸的三种方法
2012-07-19 11:46 25331111111111111111111111111111111 ... -
sqlite数据库处理时间问题 和 日期时间函数
2012-06-27 10:36 22845首先,sqlite数据库在时间 ... -
app缓存管理
2012-06-27 10:25 1058无论大型或小型应用, ... -
Uri、UriMatcher、ContentUris类使用介绍&&Android应用间数据共享之ContentProvider
2012-05-24 15:50 4431Android应用开发中我们会经常用Uri进行数据的处理,下面 ... -
getWidth()为0
2012-04-12 10:06 2015一般在刚开始开发android时,会犯一个错误,即在View的 ... -
自定义View 及使用
2012-04-05 14:08 773可能是一直都在做Web的富客户端开发的缘故吧,在接触Andro ... -
搜索手机联系人所有字段
2012-03-28 15:54 1452想取手机联系人的有效字段,但是苦于找不到API表示的字段变量, ... -
Andoid2.X各字段意义
2012-03-28 14:59 1258ContactsContract.Contacts.TIMES ... -
SMS发送流程
2012-03-20 18:07 1262发短信流程: 1 afterTextChanged{mWork ... -
Android telephony MMS 学习笔记
2012-03-14 13:32 2885转载 http://blog.csdn.net/tjy1985 ... -
Android_Mms源代码接受短信流程
2012-03-14 13:27 978短信来了之后framework会发送广播 “android.p ...
相关推荐
3. **数据库操作**:Android系统提供SQLite数据库支持,可以用来存储图书信息。开发者需要创建一个SQLite数据库,定义数据表结构,以及相应的数据库操作类,如增删改查的方法。 4. **内容提供者**(Content ...
这个压缩包文件提供了一个完整的安卓Android平台上的问卷调查系统的设计与实现案例,适用于毕业设计、毕设或课程设计项目。通过分析这个源码,我们可以深入理解Android应用开发中的多个关键知识点。 【描述】: ...
由于文档内容涉及的主题较为集中,接下来我将围绕Android平台的仪器管理系统App的设计与实现展开详细的知识点阐述。 首先,文档标题“基于Android的仪器管理系统App设计与实现”清晰指出了该文档将要探讨的核心内容...
MIUI作为小米公司推出的基于Android系统的操作系统,在主题风格设计上有着独特的思考和技术实现方案。本篇将深入探讨MIUI主题风格的设计思路及其技术实现。 #### 二、“主题”的概念及重要性 1. **主题的概念**:...
系统客户端和服务器端架构技术: 界面层,业务逻辑层,数据层3层分离技术,MVC设计思想! 服务器和客户端数据通信格式:json格式,采用servlet方式 用户信息: 用户名,登录密码,姓名,性别,出生日期,联系电话,邮箱地址...
《基于安卓Android的企业员工管理系统设计与实现》是一个深入探讨如何运用Android技术构建高效、便捷的企业员工管理系统的专题。本文将围绕这一主题,详细介绍系统的设计理念、核心技术、开发流程以及实际应用,旨在...
安卓主题设计 - **用户体验优化**:文章的出发点是满足用户对美观、简洁界面和简单操作的需求,因此在设计安卓主题时,首先会关注用户体验(User Experience,简称UX),并通过设计原则、界面布局、色彩搭配和元素...
在系统实现部分,作者介绍了系统的实现过程,包括服务器端的实现、客户端的实现和数据库的设计。作者还对系统的测试和调试进行了详细的描述,包括功能测试、性能测试和安全测试。 在结论部分,作者对系统的优缺点...
本文档讨论的主题是“基于Android的图像采集及应用服务系统的设计与实现”,旨在通过智能手机终端来解决特定领域的图像采集和服务平台搭建问题。具体而言,该项目针对的是某省考务管理业务中的图像采集需求。 #### ...
总结起来,安卓Android手机主题制作教程是一个全面指导用户如何从零开始创建个性化MIUI主题的指南,涵盖了从准备测试设备、设计界面、安装制作工具到实际替换图片和打包主题的所有步骤。通过这个教程,用户不仅可以...
在本Android课程设计报告中,学生以“新闻客户端”为主题,采用Android Studio等开发工具,利用Java语言,构建了一个能够在线浏览新闻的应用系统。报告详细涵盖了设计要求、背景介绍、需求分析、设计目的、技术介绍...
在APP的设计和实现过程中,我们还运用了Android系统的开源和可开发特性,促使基于Android的应用软件越来越多,且广泛应用于人们的生活、学习和工作。此外,我们还了解到目前国内外多数智能手机都采用Android系统,...
【标题】"基于安卓Android Studio智慧医疗医院预约挂号app设计源码案例设计"是一个实践性的项目,它展示了如何使用Google的Android Studio开发工具来构建一个智能医疗应用,该应用允许用户进行在线预约挂号。...
本主题聚焦于“基于Android平台的通信系统设计与实现”,涵盖了无线通信、网络编程、移动应用开发等多个核心知识点。 首先,理解Android平台的基础架构至关重要。Android是一个以Linux内核为基础的操作系统,为...
本项目以“基于Android Studio开发的安卓信息管理系统”为主题,旨在帮助开发者理解和掌握如何使用Android Studio构建一个功能完善的后台管理系统。 首先,系统的管理员登录模块是整个系统的基础。管理员登录通常...
基于Android Studio实现功能强大的购物商城APP项目源码(毕业设计).zip 已获导师指导并通过的高分毕业设计,代码完整下载即用无需修改,确保可以运行。 基于Android Studio实现功能强大的购物商城APP项目源码...
本资源"安卓Android源码——安卓Android实现Windows风格的Dialog.rar"提供了一种实现方式,帮助开发者在安卓系统上构建出与Windows系统类似风格的对话框。 首先,了解Dialog在Android中的基本使用。在Android SDK中...
这个资源包"安卓Android源码——安卓Android实现Windows风格的Dialog.rar"很可能包含了实现这一功能的完整源代码,包括布局文件、自定义Dialog类和可能的样例用法。研究这些源码可以帮助开发者深入理解如何在Android...
针对这样的实际问题,我们设计了一款图书馆订座系统。主要有四大功能模块,包括预订座位、查看座位、个人信息和我的步数。预订座位可以选3层楼,每层楼座位表不同,每位学生同一时间只能预订一个座位;查看座位的...
该研究的目的是为了设计和实现一个高效、可靠的 Android 手机通讯录系统。 2. 研究方向 本研究的主要方向是设计和实现 Android 手机通讯录的核心模块,包括联系人管理、电话号码管理、短信管理等。同时,还将研究 ...