做网站怎么弄模板,济南特大最新消息,雄安专业网站建设哪家好,友情网站Java中使用反射的地方较多#xff0c;尤其是各种框架中。最近在Android7.0的项目中遇到个问题很奇怪#xff0c;反射使用的类找不到了#xff0c;但是编译的时候没问题啊。然后在代码中使用非反射的方式调用代码也是没有问题的#xff0c;这时奇怪的现象出现了#xff0c;…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是updateConfiguration7.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