DIY Android之一--原生Android系统主题支持的设计和实现
口号:Android只是个Demo。
智能手机何其多,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函数去生成一个新的资源对象,并使用读出的资源数据流赋给该对象,最后返回给上层应用。
下图列出了系统原有逻辑及需要修改的部分:
上面的部分已经分析了资源访问过程中需要修改的部分,但是除了访问流程的主干之外,
系统在以下几个部分对资源访问效率做的优化同样会受到我们修改资源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。
草草完成Demo设计和实现,仅仅算是把功能实现了,欢迎大家继续优化、讨论。
转载于:https://www.cnblogs.com/mobile-veterans/archive/2012/12/10/2758963.html
DIY Android之一--原生Android系统主题支持的设计和实现相关推荐
- 原生android怎么安装到手机,如果谷歌强推手机安装原生安卓系统你支持吗?
如果要问大家国产手机想要发展,一直以来受到的最大阻碍是什么,很多人可能会说零配件总是被国外厂商卡脖子,比如一些国产手机就经常因为受到零配件供应短缺方面的牵制而出现问题,其实这都不是最主要,谷歌才是最让 ...
- android os适配机型,系统和支持机型对比
系统和支持机型对比 操作平台:Watch OS对阵Android Wear 在发布之前,很多人认为,Apple Watch可能采用精简版的iOS 8操作系统,事实是它采用的是Watch 0S这一全新的 ...
- android wear 支付,中兴智能手表曝光 Android Wear 2.0系统且支持NFC支付
3月22日消息,此前就有消息称国内厂商中兴计划在今年晚些时候推出智能手表ZTE Quartz来与Fitbit等其他厂商来进行竞争.现在,外媒曝光了一组ZTE Quartz智能手表的真机照片还确认了一些 ...
- Android 刷原生Google系统
https://download.pixelexperience.org/ https://download.lineageos.org/
- oppo三年Android更新,OPPO Find X3系列将提供3年系统更新支持
原标题:OPPO Find X3系列将提供3年系统更新支持 据最新的消息显示,OPPO Find X3系列新机将会有着3年的系统更新支持,这意味着OPPO至少会提供至少2个Android大版本的系统更 ...
- android原生插件,适用于 Android 的原生 (C++) 插件
扩展 UnityPlayerActivity Java 代码 使用 Java 或 Kotlin 源文件作为插件 适用于 Android 的原生 (C++) 插件 Unity 支持用 C/C ++ 编写 ...
- Android名片扫描识别系统SDK
Android名片扫描识别系统SDK 一.Android名片扫描识别系统应用背景 这些年,随着移动互联的发展,APP应用成爆发式的增长,在很多APP中都涉及到对名片信息的录入,如移动CRM.移动端OA ...
- chrome android 85,终于!安卓版Chrome 85将升级到原生64位:支持Android 10及以上系统...
原标题:终于!安卓版Chrome 85将升级到原生64位:支持Android 10及以上系统 安卓对64位的支持是从2014年的Android 5.0开始的.可时至今日,谷歌自己的Chrome for ...
- 国内支持原生android吗,定制安卓和原生Android到底有哪些不同之处?彻底真相了...
相信大家都知道最近在搞机圈有个大新闻,就是小米即将于8月份推出MIUI 9.近日小米MIUI市场副总监@黄龙中 就在微博上征求米粉意见,暗示MIUI 9可能长下面这样. 小米最新官方主题<几何& ...
最新文章
- 在中间层 .NET 应用程序中通过授权管理器使用基于角色的安全
- codeforces 547B【单调栈】
- IDEA----破解
- mybatis完整增删改查入门实例
- 使用 Chrome 开发者工具分析内存问题
- 角反射器的功能及应用
- mysql 需要什么硬件配置_如何来给指定的硬件环境配置一份比较合理的MySQL配置文件-爱可生...
- 七步从Angular.JS菜鸟到专家(1):如何开始【转】
- day22 java的枚举
- C语言实现可变参数列表的system接口:宏__VA_ARGS__
- uC/OS-II源码分析(六)
- 【2019银川网络赛D:】Take Your Seat(概率--递推+思维)
- turtle fillcolor_Python编程:使用海龟turtle画图制作可爱的哆啦A梦,你也可以的。
- 《Java语言程序设计》(基础篇原书第10版)第四章复习题答案
- DNS欺骗的艺术 | 域名劫持和网页挂马
- ctfmon.exe
- 网络设备的区分(自顶向下)
- 超市扫码器应该怎么使用
- asp big5 gb2312 转 Unicode
- 怎样用matlab做复数运算,MATLAB面向复数运算的设计.doc
热门文章
- 微型计算机从外观上看可以分为,《计算机主机维修》1章.doc
- FANUC机器人点动模式JOG相关警告代码含义及处理办法
- Win10 右下角电源图标怎么删除
- 蓝桥杯 试题 算法提高 P0402 猴子吃桃问题 Java
- 施工投标风险控制中的有效竞争(转)
- 【机器学习】推荐系统、机器学习面试题整理
- 此生此月不常好,明年明月何处看
- 计算机图形学笔记十三:Ray Tracing3(辐射度量学,渲染方程)
- SpringBoot 运行报log4j:WARN No appenders could be found for logger
- Vehicle Re-Identification Using Quadruple Directional Deep Learning Features