Android之动态设置App语言环境
来源:互联网 发布:淘宝怎样推广宝贝 编辑:程序博客网 时间:2024/04/28 08:07
首先,为什么会写这篇文章呢?那就是今天端午节,苦日子终于熬出头了,app版本正式交付。O(∩_∩)O哈哈~
进入正题,开发过程中需要动态改变app的语言环境,这个时候就需要用到Android自带的Locale类。也许会说,app的语言的环境不是系统自动寻找values-的文件吗?要知道,这只是系统根据自带语言设置应用资源的搜索策略,即values- → valuse的搜索顺序。但是,要考虑到有时候应用的语言环境要区别于系统语言环境,这个时候,代码中动态改变app语言环境就很有必要。
直接上代码:
/** * 切换应用语言环境 * * @param context */ private void loadAppLanguage(Context context, Locale targtLocal) { //todo 模拟器无法跟随指定语言环境 if (context == null) { throw new NullPointerException("loadAppLanguage failed because context is null"); } lg.e("loadAppLanguage:" + targtLocal); Configuration config = context.getResources().getConfiguration(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { config.setLocale(targtLocal); } else { //noinspection deprecation config.locale = targtLocal; } context.getResources().updateConfiguration(config, context.getResources().getDisplayMetrics()); Locale.setDefault(targtLocal); }
so 简单,有木有~~
好,扔给妹子测试去,我先喝杯吃个水果拼盘先。话说,公司福利还是不错的哈~
然后,~~~咦,怎么屏幕旋转的时候都变成中文了?还有,系统切换语言成繁文的时候,app怎么也跟着变了?
翻阅相关资料后,发现屏幕旋转时或者系统语言变更后都需要重新设置。好,上代码:
//注册语言变更监听器 context.registerReceiver(new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { lg.e("监听到语言变化"); loadAppLanguage(context, locale); } }, new IntentFilter(Intent.ACTION_LOCALE_CHANGED));
关于监听屏幕旋转切换时的监听操作,网上多半是直接重写Activity的onConfigurationChanged方式,但说实话,这种方法弊端很明显,如果是老旧代码遗留的历史债务,改起来就相当恶心。而且我很讨厌到处改代码,信奉的原则是怎么偷懒怎么来。(Application也可以在onConfigurationChanged设置 - 用了,接下来还怎么装*?O(∩_∩)O~ 其实在后面会说明,一个单独的模块,最好不要让开发人员做太多的控制,模块内部把所有的工作都做完最好!)
仔细想想,为什么不直接Hook系统的状态切换呢?分析下,我们只要拿到UI进程的状态通信类,就可以做自己的工作了。Hook UI线程的原理这里就按下不表了,感兴趣的自己去网上查资料,代码贴在下面。
/** * 监听主线程的Handler对象 */ public static void hookActivityThreadHandler(Handler.Callback callback) { if (callback == null) { lg.e("not support hookActivityThreadHandler because Handler.Callback not define"); return; } try { //由于ActivityThread无法直接访问 Class<?> activityThreadClass = Class.forName("android.app.ActivityThread"); Method currentActivityThreadMethod = activityThreadClass.getDeclaredMethod("currentActivityThread"); currentActivityThreadMethod.setAccessible(true); //获取主线程对象 Object activityThreadObj = currentActivityThreadMethod.invoke(null); //获取mH字段q Field mH = activityThreadClass.getDeclaredField("mH"); mH.setAccessible(true); //获取Handler Handler handler = (Handler) mH.get(activityThreadObj); //获取原始的mCallBack字段 Field mCallBack = Handler.class.getDeclaredField("mCallback"); mCallBack.setAccessible(true); //这里设置自定义实现的CallBack接口对象 mCallBack.set(handler, callback); } catch (Exception e) { e.printStackTrace(); } }
好了,入口代码如下,
public void setAppLocale(final Context context, final Locale locale) { //避免多进程重复调用 if (!TempUtils.isUIPid(context)) { return; } loadAppLanguage(context, locale); //注册语言变更监听器 context.registerReceiver(new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { lg.e("监听到语言变化"); loadAppLanguage(context, locale); } }, new IntentFilter(Intent.ACTION_LOCALE_CHANGED)); //监听横竖屏切换 HookUtils.hookActivityThreadHandler(new Handler.Callback() { @Override public boolean handleMessage(Message msg) { //118:@link ActivityThread - CONFIGURATION_CHANGED if (msg.what == 118) { if (msg.obj instanceof Configuration) { lg.e("检测到屏幕旋转,重置app语言环境"); loadAppLanguage(context, locale); } } return false; } }); }
只需要在Application的入口地方直接调用
new LanguageManager().setAppLocale(this,Locale.ENGLISH);
,剩下的所有工作全部自动帮你管理。
小Tips:
1.其实动态设置语言这个东西可以用的很活。比如现在需要把页面布局改下样式然后快速上线,但是又不想对原有的布局以及资源文件进行改动,这个时候完全可以自定义莫须有的语言环境,然后。。。你懂得!!!
- Android之动态设置App语言环境
- android动态设置app当前运行语言
- Android之获取系统语言和设置APP语言
- Android之获取系统语言和设置APP语言
- Android动态设置多语言
- android之设置app背景图片
- android app 动态实现多语言切换
- 解读android源码APP之一 ---- 环境设置
- Android 语言环境设置Locale的设置
- Android 仿支付宝设置app语言
- android设置app支持多语言
- android国际化代码动态更改语言环境
- android app根据系统语言设置应用语言
- Android开发之设置APP全局字体
- android之App的格式设置
- APP语言设置
- android系统语言设置对app本身的影响
- Android之TextView动态设置颜色
- 对于XiyouLinux Group面试题知识点的总结和面试的感受
- Intent的七大属性
- 卡特兰数
- 高精度计算之加法
- U盘未分配空间的释放
- Android之动态设置App语言环境
- cpp-netlib笔记一:编译运行第一个cpp-netlib服务程序
- 我的第一个博文
- 图像情感分析(3):基于卷积神经网络的图像情感分析模型Python实现
- Java完美判断绝对值的两种方法
- 【华为】题目:有两个数组a,b,大小都为n,数组元素的值任意,无序; 要求: 通过交换a,b中的元素,使数组a元素的和与数组b元素的和之间的差最小。
- 每日一题 No.54 最小生成树问题(Kruskal算法)
- 1088 滑雪
- java IO 简介