
我宁愿不打破AndroID的资源系统;例如,我想在strings.xml中提供主要语言本地化字符串,就像在任何AndroID应用程序中一样.
为了实现这一点,我创建了一个扩展androID.content.res.Resources的类,重写了三个getText方法.覆盖实现将尽可能从外部本地化源返回资源,否则将请求转发给super.getText()实现.
资源包装器:
public class IntegratedResources extends Resources { private ResourceIntegrator ri; public IntegratedResources(AssetManager assets,displayMetrics metrics,Configuration config,ResourceIntegrator ri) { super(assets,metrics,config); this.ri = ri; } @OverrIDe public CharSequence getText(int ID) throws NotFoundException { return ri == null ? super.getText(ID) : ri.getText(ID); } @OverrIDe public CharSequence getText(int ID,CharSequence def) throws NotFoundException { return ri == null ? super.getText(ID,def) : ri.getText(ID,def); } @OverrIDe public CharSequence[] getTextArray(int ID) throws NotFoundException { return ri == null ? super.getTextArray(ID) : ri.getTextArray(ID); }} 然后我创建了一个Contextwrapper实现来包装Activity的上下文.上下文包装器的getResources()方法将返回上面的IntegratedResources对象.
Contextwrapper:
public class IntegratedResourceContext extends Contextwrapper { private IntegratedResources integratedResources; public IntegratedResourceContext(Activity activity,String packagename) throws nameNotFoundException { super(activity); ResourceIntegrator ri = packagename == null ? null : new ResourceIntegrator(activity,packagename); displayMetrics displayMetrics = new displayMetrics(); activity.getwindow().getwindowManager().getDefaultdisplay().getMetrics(displayMetrics); integratedResources = new IntegratedResources(activity.getAssets(),displayMetrics,activity.getResources().getConfiguration(),ri); } @OverrIDe public Resources getResources() { return integratedResources; }} 最后我们有了“ResourceIntegrator”类,它从指定的已安装的第三方本地化APK中选择资源.如果需要,可以创建不同的实现以从XML或属性文件中提取它们.
ResourceIntegrator:
public class ResourceIntegrator { private Resources rBase; private Resources rExternal; private String externalPackagename; private Map<Integer,Integer> baseIDToExternalID = new HashMap<Integer,Integer>(); public ResourceIntegrator(Context context,String externalPackagename) throws nameNotFoundException { super(); rBase = context.getResources(); this.externalPackagename = externalPackagename; if (externalPackagename != null) { PackageManager pm = context.getPackageManager(); rExternal = pm.getResourcesForApplication(externalPackagename); } } public CharSequence getText(int ID,CharSequence def) { if (rExternal == null) { return rBase.getText(ID,def); } Integer externalID = baseIDToExternalID.get(ID); if (externalID == null) { // Not loaded yet. externalID = loadExternal(ID); } if (externalID == 0) { // Resource does not exist in external resources,return from base. return rBase.getText(ID,def); } else { // Resource has a value in external resources,return it. return rExternal.getText(externalID); } } public CharSequence getText(int ID) throws NotFoundException { if (rExternal == null) { return rBase.getText(ID); } Integer externalID = baseIDToExternalID.get(ID); if (externalID == null) { // Not loaded yet. externalID = loadExternal(ID); } if (externalID == 0) { // Resource does not exist in external resources,return from base. return rBase.getText(ID); } else { // Resource has a value in external resources,return it. return rExternal.getText(externalID); } } public CharSequence[] getTextArray(int ID) throws NotFoundException { if (rExternal == null) { return rBase.getTextArray(ID); } Integer externalID = baseIDToExternalID.get(ID); if (externalID == null) { // Not loaded yet. externalID = loadExternal(ID); } if (externalID == 0) { // Resource does not exist in external resources,return from base. return rBase.getTextArray(ID); } else { // Resource has a value in external resources,return it. return rExternal.getTextArray(externalID); } } private int loadExternal(int baseID) { int externalID; try { String entryname = rBase.getResourceEntryname(baseID); String typename = rBase.getResourceTypename(baseID); externalID = rExternal.getIDentifIEr(entryname,typename,externalPackagename); } catch (NotFoundException ex) { externalID = 0; } baseIDToExternalID.put(baseID,externalID); return externalID; }} 我对stackoverflow的问题是上面的实现是否是一个好主意,它是否正确使用API,以及它的设计是否能够面向未来的AndroID未知版本.我之前没有见过有人这样做过,而且似乎无法在文档或网络上找到解决此问题的任何内容.
允许独立第三方翻译的基本要求非常关键.目前在内部维护此应用程序的数十种翻译是不可行的,而且我没有能力审查用户提供的翻译质量.如果这个设计是一个非常糟糕的想法并且没有类似的替代方案可用,那么本地化可能必须在没有AndroID的资源管理系统的情况下完成.
如果这是一个好主意,请随意使用和改进上述代码.
解决方法My question to stackoverflow is whether the above is a good IDea
如果它是一个完整的解决方案,我会感到震惊,因为你不能强迫AndroID使用你的自定义Contextwrapper.它应该适用于您手动调用getString(),getText()等的任何地方,但我不知道它如何在AndroID访问超出您的某个活动之外的那些资源的任何地方工作.有很多地方你不能自己调用getText()等,例如:
>主屏幕发射器
>“设置”中的应用信息
>最近的任务清单
此外,除非您打算永远不要添加新字符串,否则您将遇到永久版本问题.您无法强制第三方翻译支持新字符串,因此您最终会得到一个混合了翻译和非翻译字符串的应用程序.
whether it’s using the API properly
那似乎没问题.
whether its design is future-proof against the unkNown versions of AndroID of tomorrow
AndroID将访问资源本身的位置数量可能会增加而不是减少.
It is not currently feasible to internally maintain doZens of translations for this application,and I have no capability to vet user-provIDed translations for quality.
然后只支持您愿意自己管理的语言.首先,正如我已经指出的那样,我不会在几个方面看到这将是一个完整的解决方案.其次,你似乎认为你的方法会让你不会因为糟糕的翻译而受到指责,虽然它可能会减少你得到的责任,但它不会消除这种责任.在这方面我同意Squonk的观点.
我很钦佩你提供更多翻译的热情,但是,就个人而言,我不会走这条特定的道路.
总结以上是内存溢出为你收集整理的使独立的第三方能够本地化Android应用程序;应用APK之外的本地化数据全部内容,希望文章能够帮你解决使独立的第三方能够本地化Android应用程序;应用APK之外的本地化数据所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)