版权声明:本文为博主原创文章,未经博主允许不得转载。

最近整理了几篇在乐视实习时写的文章,都是一些简单的技术调研,Android夜间模式是当时做技术分享的内容,供大家参考,欢迎一起讨论~

一.夜间模式的简单介绍

随着人们夜间阅读的需求越来越扩大化,许多应用也都在设置中增加了“夜间模式”这个选项。关于夜间模式的实现,有很多种方法。在此介绍几种比较常见的夜间模式的实现方法。

首先,夜间模式是Android换肤的一种,如果应用中的夜间模式是多种皮肤的其中之一,则可以从apk外部加载皮肤资源,通过下载额外的apk文件,然后获取该apk文件中的资源文件。从实现难度上来讲,换肤的实现会比夜间模式更复杂些,但是实现方式思路也已经比较成熟。两个比较常见的应用的夜间模式实现效果如下:

知乎夜间模式.png

简书夜间模式.png

可以有一些APP是深蓝底色,有些则是黑色,字体一般为灰色。总体来说都要以暗色为底色,降低亮度和对比度。

二.夜间模式的实现方案——应用换肤技术

1.zip压缩包式皮肤

应用可设置一个默认路径。如果用户选择某个皮肤,则解压该皮肤.zip到这个文件夹中。该皮肤也可以自定义扩展名,但是都为zip格式(例如墨迹天气皮肤扩展名是mja,搜狗输入法的皮肤扩展名是sga)

实现技术: 该技术重点在于如何去读取zip文件中的资源以及皮肤文件存放策略。

实现方案:

如果每次启动都读取SD卡上的皮肤文件,就会影响APP执行速度。最好是提供设置皮肤的界面,把用户选择的皮肤文件解压缩到皮肤路径(例如”/data/data/[package name]/skin” )下,这样不需要跨存储器读取,速度较快,而且不需要每次都去zip压缩包中读取

下面是一些关于处理zip文件的方法

public void doZip(String srcFile, String destFile) {

// zipDirectoryPath:需要压缩的文件夹名

File zipDir;

String dirName;

zipDir = new File(srcFile);

dirName = zipDir.getName();

try {

this.zipOut = new ZipOutputStream(

new BufferedOutputStream(

new FileOutputStream(destFile)));

//设置压缩的注释

zipOut.setComment("comment");

//设置压缩的编码,如果要压缩的路径中有中文,就用下面的编码

zipOut.setEncoding("GBK");

//启用压缩

zipOut.setMethod(ZipOutputStream.DEFLATED);

//压缩级别为最强压缩

zipOut.setLevel(Deflater.BEST_COMPRESSION);

handleDir(zipDir, this.zipOut,dirName);

this.zipOut.close();

} catch (IOException ioe) {

ioe.printStackTrace();

}

}

public void unZip(String unZipfile, String destFile) {

FileOutputStream fileOut;

File file;

InputStream inputStream;

try {

this.zipFile = new ZipFile(unZipfile);

for (Enumeration entries = this.zipFile.getEntries();

entries .hasMoreElements();) {

ZipEntry entry = (ZipEntry) entries.nextElement();

file = new File(destFile+File.separator+entry.getName());

if (entry.isDirectory()) {

file.mkdirs();

} else {

// 如果指定文件的目录不存在,则创建之.

File parent = file.getParentFile();

if (!parent.exists()) {

parent.mkdirs();

}

inputStream = zipFile.getInputStream(entry);

fileOut = new FileOutputStream(file);

while ((this.readedBytes = inputStream.read(

this.buf)) > 0) {

fileOut.write(this.buf, 0, this.readedBytes);

}

fileOut.close();

inputStream.close();

}

}

this.zipFile.close();

} catch (IOException ioe) {

ioe.printStackTrace();

}

}

/**

* 获得压缩文件内文件列表

*

* @param zipFile 压缩文件

* @return 压缩文件内文件名称

* @throws ZipException 压缩文件格式有误时抛出

* @throws IOException 当解压缩过程出错时抛出

*/

public static ArrayList getEntriesNames(File zipFile) throws ZipException, IOException {

ArrayList entryNames = new ArrayList();

Enumeration> entries = getEntriesEnumeration(zipFile);

while (entries.hasMoreElements()) {

ZipEntry entry = ((ZipEntry) entries.nextElement());

entryNames.add(new String(getEntryName(entry).getBytes("GB2312"), "8859_1"));

}

return entryNames;

}

/**

* 获得压缩文件内压缩文件对象以取得其属性

*

* @param zipFile 压缩文件

* @return 返回一个压缩文件列表

* @throws ZipException 压缩文件格式有误时抛出

* @throws IOException IO操作有误时抛出

*/

public static Enumeration> getEntriesEnumeration(File zipFile) throws ZipException,

IOException {

ZipFile zf = new ZipFile(zipFile);

return zf.entries();

}

具体demo可见 https://github.com/luozheng1985/skin_demo

这种方式的优点是:皮肤资源的格式定义很随意可以是zip也可以是自定义的格式,只要程序中能够解析到资源就行,缺点是需要读取并解析文件,导致效率上会比较差。

2.apk文件换肤

这种方法通过获取其他程序的context来获取皮肤资源。我们知道android程序中要获取drawable、layout等资源,都要通过context.getResources().getXXX的方式。那么如果我们可以拿到其他程序的context,那么那个程序就可以作为皮肤程序来提供资源给主程序使用了。android中两个程序相互读取数据的条件是:两个程序的共享用户id相同,通过AndroidManifest.xml中的android:sharedUserId属性配置;两个程序签名相同。想要改变皮肤时,改变提供资源的context为皮肤程序的context,然后刷新即可。

具体实现步骤如下:

在主应用程序 和 皮肤资源程序的AndroidManifest.xml中配置相同sharedUserId。

android:sharedUserId是指共用一个uid,也就是,凡是这个属性相同的工程,都会共用同一个uid

*为了让用户无感知,需要安装后皮肤APk后,让自己不可以打开,且不生成桌面图标,因此要去掉AndroidManifest.xml的如下代码:

皮肤资源apk 与 主应用apk中对同一功能的皮肤资源文件名要一致。

在主程序中 获取到皮肤资源apk对应的Context,

Context skinContext = createPackageContext("皮肤资源包名",Context.CONTEXT_IGNORE_SECURITY);

通过返回的context对象就可以访问到皮肤资源apk中的任何资源

如 :

Drawable drawable =skinContext.getResources().getDrawable(R.drawable.bg_title)

(皮肤资源Apk 无需包含任何UI Activity,只需要包含需要更换皮肤的res资源文件)

优点:可定期提供换肤包供下载,换肤方式灵活,同时效率比较高。

缺点:如需使用某个皮肤,必须安装该皮肤。但其实现起来还是用代码的方式来提供置换的。同时,让两个工程来共享一个进程,这样做十分的危险。此外,安装了很多皮肤后,应用程序列表里面会有很多皮肤程序。在主程序卸载后,皮肤工程不能同样的卸载。如卸载腾讯微博之后,安装的皮肤apk没有被卸载。

android官方夜间模式,Android实现夜间模式的方法(一)相关推荐

  1. android 官方说明文档,Android官方文档翻译-Accessibility

    标签元素 向用户提供解释每个可互动元素的意义和目的有用且形象的标签是非常重要的.这些标签允许屏幕阅读者(比如 TalkBack )正确向用户解释每个控制器的功能. 你可以使用一下两个方法提供元素的标签 ...

  2. android官方技术文档翻译——Android Lint

    本文译自androd官方技术文档<Android Lint>,原文地址:http://tools.android.com/tips/lint. 本文地址:http://blog.csdn. ...

  3. android官方架构组件,Android 架构组件官方文档01——LifeCycle

    使用生命周期感知组件处理生命周期 支持生命周期的组件执行操作以响应另一个组件(例如Activity和fragment)的生命周期状态更改.这些组件可帮助您生成组织性更好,并且通常更轻量的代码,这些代码 ...

  4. Android官方建议关于Android APP UI界面设计的一些参考原则

    下面是来自于Android官网给出了关于Android APP UI界面设计的一些参考原则,希望对广大ui设计师能带来帮助,尤其是在进行Andriod相关界面设计的时候. 一.清晰是UI界面第一位,也 ...

  5. android 官方默认动画,Android动画一:Activity过渡动画详细实现原理

    虽然 Android 5.0 之后推出了新的过渡动画方式,但通常只是用于特定的场合使用,activity.overridePendingTransition() 通用方式的过渡动画还是很常用. 原理分 ...

  6. android官方架构room,Android 官方架构组件介绍之 Room(翻译)

    持久库Room Room在SQLite上提供了一个抽象层,以便在利用SQLite的全部功能的同时使流畅的数据库访问. 需要处理一些重要的结构化数据的App通常会从本地的持久数据中受益匪浅.最常见的就是 ...

  7. android 官方jar,提取 Android.jar 源码和文档

    #!/bin/sh # # Create a source jar with all relevant android java sources. # Create JavaDoc for all j ...

  8. Android官方模拟器root,Android Studio 自带模拟器获取root权限

    准备工作 http://www.supersu.com/download 从这里下载SuperSU.apk和SuperSU-v2.82-201705271822.zip 我下载的是2.8.2版本. 一 ...

  9. android官方转圈圈,android 弹出之后,一直转圈圈??

    flutter version: version: 1.0.0+1 environment: sdk: ">=2.1.0 <3.0.0" photo: 0.4.5 + ...

  10. 【Android CPU 优化】Android CPU 调优 ( Trace 文件分析 | Android Profiler 工具 | CPU Profiler 工具 )

    文章目录 一.Android CPU 优化 二.CPU Profiler 工具 三.相关资源 一.Android CPU 优化 在 Android 中 , 出现 动画掉帧 , 页面切换白屏 , 卡顿 ...

最新文章

  1. 取代C语言的标准输入输出:cin 和 cout【C++标准输入输出】
  2. 使用 autossh 建立反向 SSH 隧道管理个人计算机
  3. bash3与bash4数组结构
  4. ASP应用之模板采用
  5. 《Head First设计模式》 读书笔记16 其余的模式(二) 蝇量 解释器 中介者
  6. Latex 修改公式的的大小
  7. python增量赋值是什么意思_关于python中的增量赋值的理解
  8. teamviwer安装提示 Verification of your Teamviewer version failed!.
  9. 谷歌同意向法国支付近10亿美元罚款 以了结4年前的财务欺诈调查
  10. python2和3切换_python2和python3切换
  11. Linux镜像资源收集
  12. Html常用正则表达式
  13. HTML5游子吟网页的完整代码,游子吟
  14. Python 的输出矩阵的一些常用设置
  15. iOS9.3描述文件怎么安装
  16. java毕业设计总结
  17. jeecms系统使用介绍——jeecms中的内容、栏目、模型之间的关系
  18. 西门子伺服驱动器6SE70上电无显示故障分析
  19. Docker之Docker概述
  20. 什么是公共语言运行时(CLR)

热门文章

  1. 【设置版本号】React Native 通过配置文件package.json设置 Android安卓和iOS版本号
  2. python坦克大战
  3. creo打不开stp文件_为什么stp网站打不开 creo打不开stp文件
  4. java rest 图_java – Serenity Rest服务
  5. 什么样的鞋影响骨骼生长
  6. Java各个版本区别
  7. 数据的准确性对模型效果的重要性
  8. osEye.Net:离别是为了将来的重逢
  9. 神经网络 和 NLP —— 语言模型和词向量
  10. 如何定位前后端Bug