本帖最后由 tianzry 于 2018-2-24 19:57 编辑

我们都知道,安卓手机是可以系统设置显示的字体大小的,用户可以根据自己的使用习惯,选择不同的字体大小,例如MIUI的字体大小里头有“巨无霸”的选项,选择这个之后,软件界面的字体会变得异常大,随之而来的换行问题,行距问题就出来了。

根据我自己的使用、开发安卓软件过程中,发现很多开发者对于“无障碍”这一块的关注不是很多,大部分都不会适配大字体的系统设置情形,这就导致设置了大字体的系统打开相同的软件时候,出现部分字体重叠、显示不全等问题,这个问题很影响用户体验。左边是没有适配大字体的情况,出现字体重叠的情况。

55fd2b2273b5a8b4531f72773c469d6e.gif

1.jpg (39.6 KB, 下载次数: 1)

2018-2-24 19:50 上传

55fd2b2273b5a8b4531f72773c469d6e.gif

2.jpg (38.87 KB, 下载次数: 1)

2018-2-24 19:50 上传

如果开发者一直没有做这方面的是适配,那么我们可以自己动手,改善一下。下面分享一下自己使用的比较简单的方法,内容基于我前几天修改的斐讯路由器控制软件(链接)来说:

1. 对软件进行反编译;

2. 定位字体显示异常的页面,一般来说,在MainActivity中设置一次就可以了。

我们知道,正常开发情况下,要保证软件界面显示不受系统设置的字体影响,可以在onCreate()方法中的setContentView()之前,执行如下的代码:

[Java] 纯文本查看 复制代码Resources res = super.getResources();

Configuration config = new Configuration();

config.setToDefaults();

res.updateConfiguration(config, res.getDisplayMetrics());

这样,软件界面的字体就不会随着系统设置的字体大小变化而变化了。

那么,换成smali代码,应该怎么写呢。方法很简单,就是在Android studio里面编写好,然后编译成apk,再进行反编译,即可得到对应的smali代码了。

现在的问题是,如何注入到没有源码的apk中实现修改的效果呢?一般来说可以直接将得到的代码粘贴到对应地方就可以了,但是容易出现问题,就是寄存器的申请问题,因为这几行代码用到几个寄存器;还有一个问题就是代码行的问题,因此,可以采用插入方法(method)的方式来避免这些问题,例如,上面几段代码的smali代码为:

[Asm] 纯文本查看 复制代码.method public setDefaultView()V

.locals 3

.prologue

invoke-super {p0}, Landroid/support/v7/app/AppCompatActivity;->getResources()Landroid/content/res/Resources;

move-result-object v1

.local v1, "res":Landroid/content/res/Resources;

new-instance v0, Landroid/content/res/Configuration;

invoke-direct {v0}, Landroid/content/res/Configuration;->()V

.local v0, "config":Landroid/content/res/Configuration;

invoke-virtual {v0}, Landroid/content/res/Configuration;->setToDefaults()V

invoke-virtual {v1}, Landroid/content/res/Resources;->getDisplayMetrics()Landroid/util/DisplayMetrics;

move-result-object v2

invoke-virtual {v1, v0, v2}, Landroid/content/res/Resources;->updateConfiguration(Landroid/content/res/Configuration;Landroid/util/DisplayMetrics;)V

return-void

.end method

然后,我们将上面的代码粘贴到MainActivity.smali最后面,注意删除掉 .line xx 的标号。同时,在MainActivity.smali的onCreate方法中插入自定义的方法:

[Asm] 纯文本查看 复制代码.method protected onCreate(Landroid/os/Bundle;)V

.locals 4

.prologue

.line 107

invoke-super {p0, p1}, Lcom/phicomm/zlapp/base/BaseActivity;->onCreate(Landroid/os/Bundle;)V

invoke-virtual {p0}, Lcom/phicomm/zlapp/activities/MainActivity;->setDefaultView()V

const/4 v3, 0x3

const/4 v2, 0x0

.line 108

const v0, 0x7f04001f

invoke-virtual {p0, v0}, Lcom/phicomm/zlapp/activities/MainActivity;->setContentView(I)V

......

上面的代码“invoke-virtual {p0}, Lcom/phicomm/zlapp/activities/MainActivity;->setDefaultView()V” 就是我们插入的语句。

3. 进行这样的操作之后,重新编译代码,签名,就可以正常安装,观察修改效果了。

最后有一个需要提醒的是,需要明确你修改的app的activity页面继承的是哪个类(Activity、AppCompatActivity、FragmentActivity等),我上面贴的代码就是继承AppCompatActivity的,体现在这一句:invoke-super {p0}, Landroid/support/v7/app/AppCompatActivity;->getResources()Landroid/content/res/Resources;

新手玩smali代码注入,如有说错的,欢迎指出交流。对你有用的记得评一下分哟~

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐