android 语言设置
[Android]应用语言切换的三种方法
Android对国际化与多语言切换已经做得不错了,一个应用只要命名相应语系的values-[language]文件夹,通过“设置”→“语言&键盘”→“选择语言”即可实现应用多种语言的切换。
但如何在应用里自己实现?搜索过发现网上有如下的做法:
view plaincopy to clipboardprint?
Resources res = getResources();
Configuration config = res.getConfiguration();
config.locale = locale;
DisplayMetrics dm = res.getDisplayMetrics();
res.updateConfiguration(config, dm);
前两种方法的原理即在应用里实现“选择语言”。通过查看源码,其核心代码为:
view plaincopy to clipboardprint?IActivityManager iActMag = ActivityManagerNative.getDefault();
try {
Configuration config = iActMag.getConfiguration();
config.locale = locale;
// 此处需要声明权限:android.permission.CHANGE_CONFIGURATION
// 会重新调用onCreate();
iActMag.updateConfiguration(config);
} catch (RemoteException e) {
e.printStackTrace();
}
PS:感谢 曾阳 的帮助。
IActivityManager iActMag = ActivityManagerNative.getDefault();
try {
Configuration config = iActMag.getConfiguration();
config.locale = locale;
// 此处需要声明权限:android.permission.CHANGE_CONFIGURATION
// 会重新调用onCreate();
iActMag.updateConfiguration(config);
} catch (RemoteException e) {
e.printStackTrace();
}
PS:感谢 曾阳 的帮助。 可以发现IActivityManager与ActivityManagerNative都是非公开类。如何调用?第一种是API欺骗,第二种是使用Java反射机制。
1. API欺骗
烧制到手机中的android.jar包含了Android所需的各种类与方法;而供开发者使用的android.jar只是其中的一部分。API欺骗是指在应用中去模拟未公开的类和方法让应用编译通过并生成APK,然而在应用实际运行中调用的却仍是烧制到手机中真实的android.jar。
通过核心代码可以看到我们要模拟的是ActivityManagerNative中的一个方法getDefault()和IActivityManager中的两个方法getConfiguration()与updateConfiguration(config)。参照源码,应用的工程结构图及代码模拟如下:
代码:
view plaincopy to clipboardprint?ActivityManagerNative.java
package android.app;
/**
* @author Sodino E-mail:sodinoopen@hotmail.com
* @version Time:2011-7-10上午11:37:01
*/
public abstract class ActivityManagerNative {
public static IActivityManager getDefault() {
return null;
}
}
IActivityManager.java
package android.app;
import android.content.res.Configuration;
import android.os.RemoteException;
/**
* @author Sodino E-mail:sodinoopen@hotmail.com
* @version Time:2011-7-10上午11:37:46
*/
public abstract inte易做图ce IActivityManager {
public abstract Configuration getConfiguration() throws RemoteException;
public abstract void updateConfiguration(Configuration paramConfiguration)
throws RemoteException;
}
ActivityManagerNative.java
package android.app;
/**
* @author Sodino E-mail:sodinoopen@hotmail.com
* @version Time:2011-7-10上午11:37:01
*/
public abstract class ActivityManagerNative {
public static IActivityManager getDefault() {
return null;
}
}
IActivityManager.java
package android.app;
import android.content.res.Configuration;
import android.os.RemoteException;
/**
* @author Sodino E-mail:sodinoopen@hotmail.com
* @version Time:2011-7-10上午11:37:46
*/
public abstract inte易做图ce IActivityManager {
public abstract Configuration getConfiguration() throws RemoteException;
public abstract void updateConfiguration(Configuration paramConfiguration)
throws RemoteException;
} 实现模拟了这两个类后,即可正常使用上面提到的转换语系的核心代码了。
直接上代码:
view plaincopy to clipboardprint?
private void updateLanguage(Locale locale) {
Log.d("ANDROID_LAB", locale.toString());
try {
Object objIActMag, objActMagNative;
Class clzIActMag = Class.forName("android.app.IActivityManager");
Class clzActMagNative = Class.forName("android.app.ActivityManagerNative");
Method mtdActMagNative$getDefault = clzActMagNative.getDeclaredMethod("getDefault");
// IActivityManager iActMag = ActivityManagerNative.getDefault();
objIActMag = mtdActMagNative$getDefault.invoke(clzActMagNative);
// Configuration config = iActMag.getConfiguration();
Method mtdIActMag$getConfiguration = clzIActMag.getDeclaredMethod("getConfiguration");
Configur
补充:移动开发 , Android ,