Xamarin.android 本地化不';使用“t”工作;将程序集捆绑到本机代码中”;在释放模式下
我遵循程序,使用resx文件显示正确的语言,在Android上使用DI,我可以在我的应用程序中更改语言。 基本上在Android中,我添加了文章中描述的特定于平台的代码Xamarin.android 本地化不';使用“t”工作;将程序集捆绑到本机代码中”;在释放模式下,xamarin.android,xamarin.forms,Xamarin.android,Xamarin.forms,我遵循程序,使用resx文件显示正确的语言,在Android上使用DI,我可以在我的应用程序中更改语言。 基本上在Android中,我添加了文章中描述的特定于平台的代码 `[assembly:Dependency(typeof(UsingResxLocalization.Android.Localize))] namespace UsingResxLocalization.Android { public class Localize : UsingResxLocalization.I
`[assembly:Dependency(typeof(UsingResxLocalization.Android.Localize))]
namespace UsingResxLocalization.Android
{
public class Localize : UsingResxLocalization.ILocalize
{
public void SetLocale(CultureInfo ci)
{
Thread.CurrentThread.CurrentCulture = ci;
Thread.CurrentThread.CurrentUICulture = ci;
}
public CultureInfo GetCurrentCultureInfo()
{
var netLanguage = "en";
var androidLocale = Java.Util.Locale.Default;
netLanguage = AndroidToDotnetLanguage(androidLocale.ToString().Replace("_", "-"));
// this gets called a lot - try/catch can be expensive so consider caching or something
System.Globalization.CultureInfo ci = null;
try
{
ci = new System.Globalization.CultureInfo(netLanguage);
}
catch (CultureNotFoundException e1)
{
// iOS locale not valid .NET culture (eg. "en-ES" : English in Spain)
// fallback to first characters, in this case "en"
try
{
var fallback = ToDotnetFallbackLanguage(new PlatformCulture(netLanguage));
ci = new System.Globalization.CultureInfo(fallback);
}
catch (CultureNotFoundException e2)
{
// iOS language not valid .NET culture, falling back to English
ci = new System.Globalization.CultureInfo("en");
}
}
return ci;
}
string AndroidToDotnetLanguage(string androidLanguage)
{
var netLanguage = androidLanguage;
//certain languages need to be converted to CultureInfo equivalent
switch (androidLanguage)
{
case "ms-BN": // "Malaysian (Brunei)" not supported .NET culture
case "ms-MY": // "Malaysian (Malaysia)" not supported .NET culture
case "ms-SG": // "Malaysian (Singapore)" not supported .NET culture
netLanguage = "ms"; // closest supported
break;
case "in-ID": // "Indonesian (Indonesia)" has different code in .NET
netLanguage = "id-ID"; // correct code for .NET
break;
case "gsw-CH": // "Schwiizertüütsch (Swiss German)" not supported .NET culture
netLanguage = "de-CH"; // closest supported
break;
// add more application-specific cases here (if required)
// ONLY use cultures that have been tested and known to work
}
return netLanguage;
}
string ToDotnetFallbackLanguage(PlatformCulture platCulture)
{
var netLanguage = platCulture.LanguageCode; // use the first part of the identifier (two chars, usually);
switch (platCulture.LanguageCode)
{
case "gsw":
netLanguage = "de-CH"; // equivalent to German (Switzerland) for this app
break;
// add more application-specific cases here (if required)
// ONLY use cultures that have been tested and known to work
}
return netLanguage;
}
}
}`
在PCL代码中,我有
namespace myApp.Resx
{
/// <summary>
/// Implementations of this interface MUST convert iOS and Android
/// platform-specific locales to a value supported in .NET because
/// ONLY valid .NET cultures can have their RESX resources loaded and used.
/// </summary>
/// <remarks>
/// Lists of valid .NET cultures can be found here:
/// http://www.localeplanet.com/dotnet/
/// http://www.csharp-examples.net/culture-names/
/// You should always test all the locales implemented in your application.
/// </remarks>
public interface ILocalize
{
/// <summary>
/// This method must evaluate platform-specific locale settings
/// and convert them (when necessary) to a valid .NET locale.
/// </summary>
CultureInfo GetCurrentCultureInfo();
/// <summary>
/// CurrentCulture and CurrentUICulture must be set in the platform project,
/// because the Thread object can't be accessed in a PCL.
/// </summary>
void SetLocale(CultureInfo ci);
}
/// <summary>
/// Helper class for splitting locales like
/// iOS: ms_MY, gsw_CH
/// Android: in-ID
/// into parts so we can create a .NET culture (or fallback culture)
/// </summary>
public class PlatformCulture
{
public PlatformCulture(string platformCultureString)
{
if (String.IsNullOrEmpty(platformCultureString))
throw new ArgumentException("Expected culture identifier", "platformCultureString"); // in C# 6 use nameof(platformCultureString)
PlatformString = platformCultureString.Replace("_", "-"); // .NET expects dash, not underscore
var dashIndex = PlatformString.IndexOf("-", StringComparison.Ordinal);
if (dashIndex > 0)
{
var parts = PlatformString.Split('-');
LanguageCode = parts[0];
LocaleCode = parts[1];
}
else
{
LanguageCode = PlatformString;
LocaleCode = "";
}
}
public string PlatformString { get; private set; }
public string LanguageCode { get; private set; }
public string LocaleCode { get; private set; }
public override string ToString()
{
return PlatformString;
}
}
}
名称空间myApp.Resx
{
///
///此接口的实现必须转换为iOS和Android
///特定于平台的区域设置为.NET中支持的值,因为
///只有有效的.NET区域性才能加载和使用其RESX资源。
///
///
///有效的.NET区域性列表可在此处找到:
/// http://www.localeplanet.com/dotnet/
/// http://www.csharp-examples.net/culture-names/
///您应该始终测试应用程序中实现的所有区域设置。
///
公共接口ILocalize
{
///
///此方法必须评估特定于平台的区域设置
///并将它们(必要时)转换为有效的.NET区域设置。
///
CultureInfo GetCurrentCultureInfo();
///
///必须在平台项目中设置CurrentCulture和CurrentUICulture,
///因为线程对象无法在PCL中访问。
///
void SetLocale(CultureInfo ci);
}
///
///用于拆分区域设置的帮助器类,如
///iOS:ms_MY,gsw_CH
///Android:in-ID
///分为多个部分,以便创建.NET区域性(或回退区域性)
///
公共类平台文化
{
公共平台文化(字符串platformCultureString)
{
if(String.IsNullOrEmpty(platformCultureString))
抛出新ArgumentException(“预期的区域性标识符”、“platformCultureString”);//在C#6中使用nameof(platformCultureString)
PlatformString=platformCultureString.Replace(““,“-”);//.NET需要破折号,而不是下划线
var dashIndex=PlatformString.IndexOf(“-”,StringComparison.Ordinal);
如果(dashIndex>0)
{
var parts=PlatformString.Split('-');
语言代码=部件[0];
LocaleCode=parts[1];
}
其他的
{
LanguageCode=平台字符串;
LocaleCode=“”;
}
}
公共字符串平台字符串{get;private set;}
公共字符串语言代码{get;private set;}
公共字符串LocaleCode{get;private set;}
公共重写字符串ToString()
{
返回平台字符串;
}
}
}
然后在我的PCL代码中,我可以用下面的代码覆盖区域性
string name = Helpers.Settings.PreferredLanguage == "en" ? "en-US" : Helpers.Settings.PreferredLanguage + "-" + Helpers.Settings.PreferredLanguage.ToUpper();
currentCultureInfo = new System.Globalization.CultureInfo(name);
Xamarin.Forms.DependencyService.Get<Resx.ILocalize>().SetLocale(currentCultureInfo);
Resx.AppRes.Culture = currentCultureInfo;
string name=Helpers.Settings.PreferredLanguage==“en”?“en-US”:Helpers.Settings.PreferredLanguage+“-”+Helpers.Settings.PreferredLanguage.ToUpper();
currentCultureInfo=新系统.Globalization.CultureInfo(名称);
Xamarin.Forms.DependencyService.Get().SetLocale(currentCultureInfo);
Resx.AppRes.Culture=currentCultureInfo;
在调试和发布模式下运行时,此代码实现工作正常。
但它在使用“将程序集捆绑到本机代码”的发布模式下无法工作。
如果我删除此选项的复选框,它可以正常工作。
可能的问题是什么?我不知道如何找到这个。我试着用安卓设备显示器,但它没有显示太多
配置如下所示
编辑:当我在发布模式下启用“EnableDeveloper instrumentation”时,它也可以工作。很明显,对于这个问题,服务器上已经存在一个bug。在xamarin修复该错误之前,解决方法与链接上的建议相同。在MainActivity的OnCreate函数中为每种语言添加一行
System.Reflection.Assembly.LoadFile("de-DE\\AppName.resources.dll");