Android7.0反射类找不到的问题

Java中使用反射的地方较多,尤其是各种框架中。最近在Android7.0的项目中遇到个问题很奇怪,反射使用的类找不到了,但是编译的时候没问题啊。然后在代码中使用非反射的方式调用代码也是没有问题的,这时奇怪的现象出现了,加入手动调用代码后反射代码找不到类的问题也不出现了。其实这个是混淆代码所做的工作,一个类没有被使用的情况下会在编译中直接删除掉,显然并没有考虑反射调用的情况。关闭混淆或者修改混淆的配置文件即可解决这个问题。各种框架自动所做的工作大部分是节省了程序员的时间,但是一旦出问题查起来花费的时间也是不少

当处于应用层时,如果只是修改应用内多语言时,上层app可以轻松完成各种语言的切换,网上方法很多,就不在详细叙述,app内部设置多语言可参考下面这篇文章

Android 实现应用内置语言切换(附有源码下载地址7.0可用)。

但是,如何通过app,设置系统语言呢?这正是本文讨论核心。

android6.0

android设置系统语言的核心方法在framework层,地址是\frameworks\base\core\java\com\android\internal\app\LocalePicker.java类里,方法如下:

   /**
     * Requests the system to update the system locale. Note that the system looks halted
     * for a while during the Locale migration, so the caller need to take care of it.
     */
    public static void updateLocale(Locale locale) {
        try {
            IActivityManager am = ActivityManagerNative.getDefault();
            Configuration config = am.getConfiguration();
            config.setLocale(locale);
            config.userSetLocale = true;
            am.updateConfiguration(config);
            // Trigger the dirty bit for the Settings Provider.
            BackupManager.dataChanged("com.android.providers.settings");
        } catch (RemoteException e) {
            // Intentionally left blank
        }
    }

android6.0设置系统语言的关键逻辑就是上面那个方法。如果上层APP想要设置系统语言必须通过反射方法获取,核心方法代码如下(本方法可以持久化系统语言设置,也就是说重启手机后不会恢复默认系统语言):

private void changeSystemLanguage(Locale locale) {if (locale != null) {try {Class classActivityManagerNative = Class.forName("android.app.ActivityManagerNative");
            Method getDefault = classActivityManagerNative.getDeclaredMethod("getDefault");
            Object objIActivityManager = getDefault.invoke(classActivityManagerNative);
            Class classIActivityManager = Class.forName("android.app.IActivityManager");
            Method getConfiguration = classIActivityManager.getDeclaredMethod("getConfiguration");
            Configuration config = (Configuration) getConfiguration.invoke(objIActivityManager);
            config.setLocale(locale);
            //config.userSetLocale = true;
            Class clzConfig = Class.forName("android.content.res.Configuration");
            java.lang.reflect.Field userSetLocale = clzConfig.getField("userSetLocale");
            userSetLocale.set(config, true);
            Class[] clzParams = {Configuration.class};
            Method updateConfiguration = classIActivityManager.getDeclaredMethod("updateConfiguration", clzParams);
            updateConfiguration.invoke(objIActivityManager, config);
            BackupManager.dataChanged("com.android.providers.settings");
        } catch (Exception e) {Log.d(TAG, "changeSystemLanguage: " + e.getLocalizedMessage());
        }}
}
调用时如下:

Local locale = Locale.ENGLISH;
changeSystemLanguage(locale);
系统语言就变成了英文。(不再赘述)

android7.0

7.0与6.0的源码有所不同,LocalePicker.Java定义系统语言的方式,不在是一种Local,而是一个LocaleList,具体方法如下:

  public static void updateLocale(Locale locale) {
        updateLocales(new LocaleList(locale));
    }

updateLocale调用了updateLocales方法,updateLocales方法如下:

 public static void updateLocales(LocaleList locales) {
        try {
            final IActivityManager am = ActivityManagerNative.getDefault();
            final Configuration config = am.getConfiguration();
            config.setLocales(locales);
            config.userSetLocale = true;
            am.updatePersistentConfiguration(config);
            // Trigger the dirty bit for the Settings Provider.
            BackupManager.dataChanged("com.android.providers.settings");
        } catch (RemoteException e) {
            // Intentionally left blank
        }
    }

可见,6.0上的反射直接照搬到7.0是不起作用的,需要重新运用反射方法,反射方法代码如下

protected void changeSystemLanguage(LocaleList locale) {if (locale != null) {try {Class classActivityManagerNative = Class.forName("android.app.ActivityManagerNative");
            Method getDefault = classActivityManagerNative.getDeclaredMethod("getDefault");
            Object objIActivityManager = getDefault.invoke(classActivityManagerNative);
            Class classIActivityManager = Class.forName("android.app.IActivityManager");
            Method getConfiguration = classIActivityManager.getDeclaredMethod("getConfiguration");
            Configuration config = (Configuration) getConfiguration.invoke(objIActivityManager);
            config.setLocales(locale);
            Class[] clzParams = {Configuration.class};
            Method updateConfiguration = classIActivityManager.getDeclaredMethod("updatePersistentConfiguration", clzParams);
            updateConfiguration.invoke(objIActivityManager, config);
        } catch (Exception e) {Log.d(TAG, "changeSystemLanguage: " + e.getLocalizedMessage());
        }}
}

6.0和7.0设置系统语言源码不同之出,有两点:

1.设置参数的方法不同,6.0是updateConfiguration,7.0是updatePersistentConfiguration,这点需要注意

2.6.0传递的local,而7.0是一个列表LocaleList

7.0反射方法调用如下:

Locale newLocale = new Locale("zh", "CN");
final LocaleList localeList = new LocaleList(newLocale);
changeSystemLanguage(localeList);

android7.0app切换系统语言Demo源码下载:http://download.csdn.net/download/zhaokai621/9930068


生成的apk,需要系统签名,可放在源码vendor\customer\你的文件下通过mm编译,需要注意的是,需要有.mk文件,生成的apk在out的目录下(当然层级有很多),把out目录下生成的apkpush到手机system/priv-app/你的文件夹,重启手机即可。

操作如下:

1.把studio生成的apk放入如下目录:


Android.mk文件如下(供参考):

--------------------------开始(下面才是)-------------------------------------------------------------

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# Module name should match apk name to be installed
LOCAL_MODULE := Test
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := $(LOCAL_MODULE).apk
LOCAL_MODULE_CLASS := APPS
LOCAL_OVERRIDES_PACKAGES := Calendar
LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
LOCAL_CERTIFICATE := platform
#LOCAL_PREBUILT_JNI_LIBS:= \
#@lib/armeabi/liblocSDK4d.so
#LOCAL_MODULE_PATH := $(TARGET_OUT)/vendor/operator/app
LOCAL_PRIVILEGED_MODULE := true
include $(BUILD_PREBUILT)

--------------------------------结束(本行不是)-----------------------------------------------------------------------------

2.编译源码,单编模块

命令如下(前提是你已经整编过一套android源码)

source ./build/envsetup.sh(加载命令)

lunch 16(序号和你整编时选的一样,本文以android7.0源码为准)

mmm vendor/customer/Test

3.生成的apk(已经打包了系统签名):在如下目录(可能有出入)


4.push到手机,不要install,重启手机

adb push XXXX system/priv-app/Test

XXX是你out生成的apk,可拖拽到此。


现在就可以看到一个应用了,点击就可以切换系统语言了。多多交流   *-*


android7.0app切换系统语言Demo源码下载:http://download.csdn.net/download/zhaokai621/9930068

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/387469.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[转]JSon数据解析的四种方式

转至http://blog.csdn.net/enuola/article/details/7903632 作为一种轻量级的数据交换格式,json正在逐步取代xml,成为网络数据的通用格式。 有的json代码格式比较混乱,可以使用此“http://www.bejson.com/”网站来进行JSON格式化校验&#xf…

iOS开发UI篇—Quartz2D使用(绘图路径)

1 //1.获取图形上下文 2 CGContextRef ctxUIGraphicsGetCurrentContext(); 3 //2.绘图(画线) 4 //设置起点 5 CGContextMoveToPoint(ctx, 20, 20); 6 //设置终点 7 CGContextAddLineToPoint(ctx, 200, 300); 8 //渲染 9…

13结构型模式之桥接模式

概念 Bridge 模式又叫做桥接模式,是构造型的设计模式之一。Bridge模式基于类的最小设计原则,通过使用封装,聚合以及继承等行为来让不同的类承担不同的责任。它的主要特点是把抽象(abstraction)与行为实现(i…

简易中控紫猫插件版(3)压缩包使用说明

1.环境配置脚本运行环境:没什么说的 正常的最新版手机按键 当然还需要 最新的紫猫插件中控运行环境:首先要保证把压缩包的所有php文件都扔到网站的根目录下 必须保证网站的php版本是5.4 不然紫猫插件的php框架会出问题 然后你要知道网站数据库的账号和密…

Java9新特性

Java 8 发布三年多之后,即将快到2017年7月下一个版本发布的日期了。 你可能已经听说过 Java 9 的模块系统,但是这个新版本还有许多其它的更新。 这里有九个令人兴奋的新功能将与 Java 9 一起发布。 1. Java 平台级模块系统 Java 9 的定义功能是一套全新的…

Java面试常见算法

在程序员的职业生涯中,算法亦算是一门基础课程,尤其是在面试的时候,很多公司都会让程序员编写一些算法实例,例如快速排序、二叉树查找等等。 本文总结了程序员在代码面试中最常遇到的10大算法类型,想要真正了解这些算法…

高仿人人Android梦想版终极源码发送(转)

经过几个月的努力,终于基本完成了人人API拥有的所有功能,界面采用仿照人人梦想版5.13制作,其中资源文件也采用人人的APK文件资源,完成的功能及知识点如下:1.通过三种动画仿照出人人引导页的放大切换图片的效果。2.通过重写ViewGroup仿照出人人菜单和其他界面的手势滑动切换效果…

android 实现SSL握手协商

Android的私钥和信任证书的格式必须是BKS格式的,通过配置本地JDK,让keytool可以生成BKS格式的私钥和信任证书,java本身没有BouncyCastle密库 ssl通道建立前必须进行协商(形成安全的通道--隧道技术)。 服务端: View Co…

同步阻塞的BIO、同步非阻塞的NIO、异步非阻塞的AIO

IO的方式通常分为几种,同步阻塞的BIO、同步非阻塞的NIO、异步非阻塞的AIO。 一、BIO 在JDK1.4出来之前,我们建立网络连接的时候采用BIO模式,需要先在服务端启动一个ServerSocket,然后在客户端启动Socket来对服务端进行通信&#x…

1 概述

Unix C TCP/IP 三位一体 Linux天生是网络操作系统 程序员的学习:不断地敲代码,不断地看别人的代码。 Linux两大领域: (1)服务器 (2)嵌入式设备 www.netcraft.com 查看网站服务器系统 VMware快…

Java Annotation认知(包括框架图、详细介绍、示例说明)

摘要 Java Annotation是JDK5.0引入的一种注释机制。 网上很多关于Java Annotation的文章,看得人眼花缭乱。Java Annotation本来很简单的,结果说的人没说清楚;弄的看的人更加迷糊。 我按照自己的思路,对Annotation进行了整理。理解…

Go语言学习之3 流程控制、函数

主要内容: 1. strings和strconv使用2. Go中的时间和日期类型3. 指针类型4. 流程控制5. 函数详解 1. strings和strconv使用 //strings 1. strings.HasPrefix(s string, prefix string) bool:判断字符串s是否以prefix开头 。 2. strings.HasSuffix(s strin…

RabbitMQ教程总结

【译】RabbitMQ教程一 主要通过Hello Word对RabbitMQ有初步认识 【译】RabbitMQ教程二 工作队列,即一个生产者对多个消费者循环分发、消息确认、消息持久、公平分发 【译】RabbitMQ教程三 如何同一个消息同时发给多个消费者开始引入RabbitMQ消息模型中的重要概念路由…

机器学习实战(笔记)------------KNN算法

1.KNN算法 KNN算法即K-临近算法,采用测量不同特征值之间的距离的方法进行分类。 以二维情况举例: 假设一条样本含有两个特征。将这两种特征进行数值化,我们就可以假设这两种特种分别为二维坐标系中的横轴和纵轴,将一个样本以点的形…

Java注解Annotation 完成验证

Java注解Annotation用起来很方便,也越来越流行,由于其简单、简练且易于使用等特点,很多开发工具都提供了注解功能,不好的地方就是代码入侵比较严重,所以使用的时候要有一定的选择性。 这篇文章将利用注解,来…

隐藏马尔科夫模型HMM

概率图模型 HMM 先从一个具体的例子入手,看看我们要解决的实际问题.例子引自wiki.https://en.wikipedia.org/wiki/Hidden_Markov_model Consider two friends, Alice and Bob, who live far apart from each other and who talk together daily over the telephone about what …

阿里云天池 金融风控训练营Task1 广东工业站

Task1 赛题理解 一、学习知识点概要 本次学习先是介绍了赛题的背景和概况,题目以金融风控中的个人信贷为背景,给所给的47列特征中,根据贷款申请人的数据信息预测其是否有违约的可能,以此判断是否通过贷款。随后介绍了比赛中的评…

如何将.crt的ssl证书文件转换成.pem格式

如何将.crt的ssl证书文件转换成.pem格式摘自:https://www.landui.com/help/show-8127 2018-07-04 14:55:41 2158次 准备:有一台安装了php的linux操作系统执行下面的openssl命令即可:openssl x509 -in www.xx.com.crt -out www.xx.com.pem转载于:https://…

SpringMVC学习记录--Validator验证分析

一.基于Validator接口的验证. 首先创建User实例,并加入几个属性 ?12345678910111213141516171819202122232425262728293031323334<code class"hljs cs">public class User {private String username;private String password;private String nickname;public …

C# 获取句柄程序

这个小程序需要用到系统API&#xff0c;也就是需要用到user32中的三个函数。 第一个&#xff1a;WindowFromPoint 返回一个窗口句柄 第二个&#xff1a;GetWindowText 获取窗口标题 第三个&#xff1a;GetClassName 获取类名 当然&#xff0c;最重要的一点就是要引用命名空间…