草庐IT

记录Android国际化语言适配部分页面不生效的问题

晖仔Milo 2023-03-28 原文

问题描述

1、App内切换语言(Demo:https://github.com/finddreams/AndroidMultiLanguage),并调用一下代码重启页面

if (getString(R.string.language_zh_cn).equals(iOption.getName())) {
     MultiLanguageUtil.getInstance().updateLanguage(mActivity, LanguageType.LANGUAGE_CHINESE_SIMPLIFIED);
} else if (getString(R.string.language_en).equals(iOption.getName())) {
     MultiLanguageUtil.getInstance().updateLanguage(mActivity, LanguageType.LANGUAGE_EN);
} else if (getString(R.string.use_system).equals(iOption.getName())) {
     MultiLanguageUtil.getInstance().updateLanguage(mActivity, LanguageType.LANGUAGE_FOLLOW_SYSTEM);
} else if (getString(R.string.language_zh_tw).equals(iOption.getName())) {
     MultiLanguageUtil.getInstance().updateLanguage(mActivity, LanguageType.LANGUAGE_CHINESE_TRADITIONAL);
}
 Intent intent = new Intent(mActivity, SplashActivity.class);
 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
 startActivity(intent);
 finish();

2、这时候看到的界面都是正常的,该显示英文的显示英文,该显示繁体的显示繁体。
3、杀掉app,重新打开。神奇的一幕发生了,前面打开的几个界面,都显示的是系统默认语言。而且打印

getResources().getConfiguration().locale

得到的也确实是"zh"。
但同时,之后打开的界面又都正确的显示了修改的语言。

问题:

这就奇怪了,为什么是同一套代码,app杀死重启后的前几个界面没有渲染出我想要的语言呢?

解决:

我参考了别人的demo,发现别人的demo在我手机里运行是正常的,无论如何杀死app都不影响。这就奇怪了不是?所以,开始用排查法对比代码。

开始分析

1、对比切换语言的代码,我是直接copy的,排除;
2、对比调用的代码,Application、BaseActivity等关键位置一致,没有问题,排除;
3、对比依赖,发现我的androidx.appcompat:appcompat与他人正常的版本不同,而BaseActivity继承自此库中的AppCompatActivity,故此推测,它有重大嫌疑

implementation 'androidx.appcompat:appcompat:1.2.0' (我的,有嫌疑版本)
implementation 'androidx.appcompat:appcompat:1.3.0'

动手替换

1、更换依赖,将androidx.appcompat:appcompat改成1.3.0;
2、重新运行app,查看成果;
3、发现无论如何重启app,都可以从头至尾正确的渲染出我想要的语言。

结论

1、这是系统库appcompat的坑,如果你的项目也需要适配多语言,建议使用1.3.0及以上版本。

补充

开篇分享的demo中,通过application.getString(R.string.xx)获取的文案可能不会获取到预期的字符串,需要在Application - attachBaseContext中做出一些调整,具体如下

    @Override
    protected void attachBaseContext(Context base) {
        MultiLanguageUtil.getInstance().saveSystemCurrentLanguage(base);
        super.attachBaseContext(MultiLanguageUtil.attachBaseContext(base));
        //app刚启动getApplicationContext()为空
        MultiLanguageUtil.getInstance().setConfiguration(getApplicationContext());
    }

留言

为什么appcompat:1.2.0会导致多语言设置失效,这其中肯定还有更深层的原因,本人才疏学浅、业务繁多,既无能力、亦无精力深讨此问题根本原因。希望能有高人有幸看到此贴,若是不嫌弃,还请留言指点。

有关记录Android国际化语言适配部分页面不生效的问题的更多相关文章

  1. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  2. ruby - Sinatra:运行 rspec 测试时记录噪音 - 2

    Sinatra新手;我正在运行一些rspec测试,但在日志中收到了一堆不需要的噪音。如何消除日志中过多的噪音?我仔细检查了环境是否设置为:test,这意味着记录器级别应设置为WARN而不是DEBUG。spec_helper:require"./app"require"sinatra"require"rspec"require"rack/test"require"database_cleaner"require"factory_girl"set:environment,:testFactoryGirl.definition_file_paths=%w{./factories./test/

  3. ruby-on-rails - Rails 5 Active Record 记录无效错误 - 2

    我有两个Rails模型,即Invoice和Invoice_details。一个Invoice_details属于Invoice,一个Invoice有多个Invoice_details。我无法使用accepts_nested_attributes_forinInvoice通过Invoice模型保存Invoice_details。我收到以下错误:(0.2ms)BEGIN(0.2ms)ROLLBACKCompleted422UnprocessableEntityin25ms(ActiveRecord:4.0ms)ActiveRecord::RecordInvalid(Validationfa

  4. ruby - 寻找通过阅读代码确定编程语言的ruby gem? - 2

    几个月前,我读了一篇关于ruby​​gem的博客文章,它可以通过阅读代码本身来确定编程语言。对于我的生活,我不记得博客或gem的名称。谷歌搜索“ruby编程语言猜测”及其变体也无济于事。有人碰巧知道相关gem的名称吗? 最佳答案 是这个吗:http://github.com/chrislo/sourceclassifier/tree/master 关于ruby-寻找通过阅读代码确定编程语言的rubygem?,我们在StackOverflow上找到一个类似的问题:

  5. Unity 热更新技术 | (三) Lua语言基本介绍及下载安装 - 2

    ?博客主页:https://xiaoy.blog.csdn.net?本文由呆呆敲代码的小Y原创,首发于CSDN??学习专栏推荐:Unity系统学习专栏?游戏制作专栏推荐:游戏制作?Unity实战100例专栏推荐:Unity实战100例教程?欢迎点赞?收藏⭐留言?如有错误敬请指正!?未来很长,值得我们全力奔赴更美好的生活✨------------------❤️分割线❤️-------------------------

  6. 7个大一C语言必学的程序 / C语言经典代码大全 - 2

    嗨~大家好,这里是可莉!今天给大家带来的是7个C语言的经典基础代码~那一起往下看下去把【程序一】打印100到200之间的素数#includeintmain(){ inti; for(i=100;i 【程序二】输出乘法口诀表#includeintmain(){inti;for(i=1;i 【程序三】判断1000年---2000年之间的闰年#includeintmain(){intyear;for(year=1000;year 【程序四】给定两个整形变量的值,将两个值的内容进行交换。这里提供两种方法来进行交换,第一种为创建临时变量来进行交换,第二种是不创建临时变量而直接进行交换。1.创建临时变量来

  7. 阿里云国际版免费试用:如何注册以及注意事项 - 2

    作为新的阿里云用户,您可以50免费试用多种优惠,价值高达1,700美元(或8,500美元)。这将让您了解和体验阿里云平台上提供的一系列产品和服务。如果您以个人身份注册免费试用,您将获得价值1,700美元的优惠。但是,如果您是注册公司,您可以选择企业免费试用,提交基本信息通过企业实名注册验证,即可开始价值$8,500的免费试用!本教程介绍了如何设置您的帐户并使用您的免费试用版。​关于免费试用在我们开始此试用之前,您还必须遵守以下条款和条件才能访问您的免费试用:只有在一年内创建的账户才有资格获得阿里云免费试用。通过此免费试用优惠,用户可以免费试用免费试用活动页面上列出的每种产品一次。如果您有多个帐

  8. 安卓apk修改(Android反编译apk) - 2

    最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路

  9. ruby-on-rails - 事件记录 : Select max of limit - 2

    我正在尝试将以下SQL查询转换为ActiveRecord,它正在融化我的大脑。deletefromtablewhereid有什么想法吗?我想做的是限制表中的行数。所以,我想删除少于最近10个条目的所有内容。编辑:通过结合以下几个答案找到了解决方案。Temperature.where('id这给我留下了最新的10个条目。 最佳答案 从您的SQL来看,您似乎想要从表中删除前10条记录。我相信到目前为止的大多数答案都会如此。这里有两个额外的选择:基于MurifoX的版本:Table.where(:id=>Table.order(:id).

  10. Ruby 守护进程导致 ActiveRecord 记录器 IOError - 2

    我目前正在用Ruby编写一个项目,它使用ActiveRecordgem进行数据库交互,我正在尝试使用ActiveRecord::Base.logger记录所有数据库事件具有以下代码的属性ActiveRecord::Base.logger=Logger.new(File.open('logs/database.log','a'))这适用于迁移等(出于某种原因似乎需要启用日志记录,因为它在禁用时会出现NilClass错误)但是当我尝试运行包含调用ActiveRecord对象的线程守护程序的项目时脚本失败并出现以下错误/System/Library/Frameworks/Ruby.frame

随机推荐