文档章节

(译)Xposed-替换资源

我爱睡觉
 我爱睡觉
发布于 2017/06/24 17:39
字数 1125
阅读 182
收藏 0

转:http://vbill.github.io/2015/02/12/Xposed-replacing-resources/

这是Xposed在github上的最后一篇教程。原文地址

Xposed使得替换资源,比如:图像和字符串之类的事变得容易。下面是做法:

简单的资源


@Override
public void initZygote(IXposedHookZygoteInit.StartupParam startupParam) throws Throwable {
    XResources.setSystemWideReplacement("android", "bool", "config_unplugTurnsOnScreen", false);
}

@Override
public void handleInitPackageResources(InitPackageResourcesParam resparam) throws Throwable {
    // replacements only for SystemUI
    if (!resparam.packageName.equals("com.android.systemui"))
        return;

    // different ways to specify the resources to be replaced
    resparam.res.setReplacement(0x7f080083, "YEAH!"); // WLAN toggle text. You should not do this because the id is not fixed. Only for framework resources, you could use android.R.string.something
    resparam.res.setReplacement("com.android.systemui:string/quickpanel_bluetooth_text", "WOO!");
    resparam.res.setReplacement("com.android.systemui", "string", "quickpanel_gps_text", "HOO!");
    resparam.res.setReplacement("com.android.systemui", "integer", "config_maxLevelOfSignalStrengthIndicator", 6);
}

这就是“简单”的替换,通过这种方式你可以直接替换值。这种方式可以用于:Boolean, Color, Integer, int[], String and String[]。

如你所见,有几种不同的设置替换资源的方式。对于构成安卓框架一部分的所有地方都应该被替换的资源(对所有的app都可用),你应在initZygote中调用XResources.setSystemWideReplacement(...)方法。对于特定app的资源,你需要核实过你确实在正确的app之后在hookInitPackageResources中调用res.setReplacement。这时你不应使用setSystemWideReplacement因为可能会产生你无法预料的副作用。

替换Drawable也采用相似的办法。然而你不能只使用Drawable作为替换物,因为这可能导致同一个Drawable实例被不同的ImageViews引用。因此,你需要使用包装器:

"com.android.systemui", "drawable", "status_bar_background", new XResources.DrawableLoader() {
    @Override
    public Drawable newDrawable(XResources res, int id) throws Throwable {
        return new ColorDrawable(Color.WHITE);
    }
});

复杂资源


更加复杂的资源(比如动画类型的Drawable)必须从你的模块资源当中被引用。我们假设你想要替换电池图标。下面是代码:

package de.robv.android.xposed.mods.coloredcirclebattery;

import android.content.res.XModuleResources;
import de.robv.android.xposed.IXposedHookInitPackageResources;
import de.robv.android.xposed.IXposedHookZygoteInit;
import de.robv.android.xposed.callbacks.XC_InitPackageResources.InitPackageResourcesParam;

public class ColoredCircleBattery implements IXposedHookZygoteInit, IXposedHookInitPackageResources {
    private static String MODULE_PATH = null;

    @Override
    public void initZygote(StartupParam startupParam) throws Throwable {
        MODULE_PATH = startupParam.modulePath;
    }

    @Override
    public void handleInitPackageResources(InitPackageResourcesParam resparam) throws Throwable {
        if (!resparam.packageName.equals("com.android.systemui"))
            return;

        XModuleResources modRes = XModuleResources.createInstance(MODULE_PATH, resparam.res);
        resparam.res.setReplacement("com.android.systemui", "drawable", "stat_sys_battery", modRes.fwd(R.drawable.battery_icon));
        resparam.res.setReplacement("com.android.systemui", "drawable", "stat_sys_battery_charge", modRes.fwd(R.drawable.battery_icon_charge));
    }
}

你可以随意命名你的替换资源。我选择 batterry_icon 替代 stat_sys_battery 让它们在本文中更好区分。

之后把 “battery_icon” 和 “battery_icon_charge” 这两个Drawable添加到你的模块当中。最简单的情况是添加 “res/drawables/battery_icon.png” 和 “res/drawables/battery_icon_charge.png”。但是你可以使用Android提供的所有方式来定义资源。所以对于动画图标,你可使用带有animation-list和其它Drawable资源引用的XML文件。当然这个XML文件也必须放在你的模块内。

通过这些替换,你能要求Xposed将所有指向特定资源的请求跳到你自己的模块。这同样意味着你可以利用qualifier,比如:如果你对landscape或更低的屏幕密度需要不同的资源。翻译也可以以相同的方式提供。同样,你也许需要这么做如果原来的资源使用qualifier。你不能仅仅替换一段文字的西班牙语版本。正如前面提到的,请求是向前的,所以它会完全被你的模块资源处理,并且不会察觉其它翻译的存在。

这个技巧基本上对所有资源类型都有效。除了极个别的像主题之类的。

修改布局


尽管理论上你可以用之前提到的技巧彻底替换布局,但这有很多坏处。你必须从原有布局中复制整个布局,这会降低对其它ROM的兼容性。主题也许回丢失。只有一个模块可以代替布局。如果两个模块都尝试这么做,后者将会胜出。最重要的是,其它资源的ID和引用是很难定义的。因此,我不推荐这样做。

作为一种好的选择,你可以使用后填充的hook。下面是你怎么做:

@Override
public void handleInitPackageResources(InitPackageResourcesParam resparam) throws Throwable {
    if (!resparam.packageName.equals("com.android.systemui"))
        return;

    resparam.res.hookLayout("com.android.systemui", "layout", "status_bar", new XC_LayoutInflated() {
        @Override
        public void handleLayoutInflated(LayoutInflatedParam liparam) throws Throwable {
            TextView clock = (TextView) liparam.view.findViewById(
                    liparam.res.getIdentifier("clock", "id", "com.android.systemui"));
            clock.setTextColor(Color.RED);
        }
    }); 
}

每当“status_bar”布局被填充时,回调方法handleLayoutInflated就被调用。在你以参数形式得到的LayoutInflatedParam对象中,你可以找到刚被创建的View并在需要时修改它。你同样会得到resNames用来鉴别这个方法因哪个布局而被调用(万一你对多个布局使用同一种方法),还有variant,比如可能包含layout-land,如果它就是被加载的布局的版本的话。res帮助你以布局从同一个来源得到ID或额外的资源。

分享到 評論

本文转载自:http://blog.csdn.net/zhangmiaoping23/article/details/54891457

我爱睡觉
粉丝 3
博文 2120
码字总数 0
作品 0
南昌
私信 提问
那些年Android黑科技②:欺骗的艺术

“我的能量无穷无尽,只有强大暗能量才能统治Android界。 受屎吧!!! =≡Σ((( つ•̀ω•́)つ ” -- 来自暗世界android工程师 前言: 这是黑科技系列的第二篇,是Android知识正营中较有深...

猴亮屏
2017/10/24
133
0
Xposed 集成 Android 6.0.1环境中,总结

  由于工作需要,需要将xposed集成到android源码中,生成新的ROM就自带xposed的功能。 下面大体上说一下步骤和遇到的问题。 1、下载,并编译android源码,成功。 2、下载 https://github.c...

Supper_litt
05/27
0
0
Xposed开发初体验

盗个图 本篇文章具体是Xposed开发,如何安装Xposed需自行上网查找,本文同步更新于旺仔的个人博客,访问可能有点慢,多刷新几次。 Xposed 什么是Xposed呢? “Xposed是一个适用于Android的框架...

叫我旺仔
2017/10/08
0
0
Xposed简介以及小米去桌面广告的简单实现

最先发表于个人博客 guolei1130.github.io/ 提起Xposed,大多数Android开发者都听过或者用过,甚至有一些开发过比较炫酷的模块。这是我前段时间在公司的分享内容,分享给大家。 Xposed简介 ...

_StriveG
2017/11/18
0
0
Xposed (一) Android hook框架入门

原理 Xposed替换了/system/bin/app_process可执行文件,在启动Zygote时加载额外的jar文件(/data/data/de.robv.android.xposed.installer/bin/XposedBridge.jar),并执行一些初始化操作(执行...

pseudo
2015/06/26
17.3K
3

没有更多内容

加载失败,请刷新页面

加载更多

rime设置为默认简体

转载 https://github.com/ModerRAS/ModerRAS.github.io/blob/master/_posts/2018-11-07-rime%E8%AE%BE%E7%BD%AE%E4%B8%BA%E9%BB%98%E8%AE%A4%E7%AE%80%E4%BD%93.md 写在开始 我的Arch Linux上......

zhenruyan
今天
5
0
简述TCP的流量控制与拥塞控制

1. TCP流量控制 流量控制就是让发送方的发送速率不要太快,要让接收方来的及接收。 原理是通过确认报文中窗口字段来控制发送方的发送速率,发送方的发送窗口大小不能超过接收方给出窗口大小。...

鏡花水月
今天
10
0
OSChina 周日乱弹 —— 别问,问就是没空

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @tom_tdhzz :#今日歌曲推荐# 分享容祖儿/彭羚的单曲《心淡》: 《心淡》- 容祖儿/彭羚 手机党少年们想听歌,请使劲儿戳(这里) @wqp0010 :周...

小小编辑
今天
1K
11
golang微服务框架go-micro 入门笔记2.1 micro工具之micro api

micro api micro 功能非常强大,本文将详细阐述micro api 命令行的功能 重要的事情说3次 本文全部代码https://idea.techidea8.com/open/idea.shtml?id=6 本文全部代码https://idea.techidea8....

非正式解决方案
今天
5
0
Spring Context 你真的懂了吗

今天介绍一下大家常见的一个单词 context 应该怎么去理解,正确的理解它有助于我们学习 spring 以及计算机系统中的其他知识。 1. context 是什么 我们经常在编程中见到 context 这个单词,当...

Java知其所以然
昨天
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部