调用Device.RuntimePlatform引发运行时异常。

8

我将我的Xamarin.Forms包更新到最新版本(2.3.4.224),并在所有项目(平台+共享)中使用。现在似乎我不应该再使用Device.OSTargetPlatform枚举,因为它们已被弃用。

编译器抱怨这些行:

if (Device.OS == TargetPlatform.iOS) 
    _API_BASE_URI = "http://XXX.XXX.XXX.XXX"; 
else
    _API_BASE_URI = "http://YYY.YYY.YYY.YYY"; 

这段话的意思是:

"Device.OS已经过时了。请使用RuntimePlatform代替"

到目前为止一切都很好,现在我想修复它,我一直在尝试使用:

Debug.WriteLine(Device.RuntimePlatform);

但是它抛出了一个运行时异常。以下是堆栈跟踪信息。
04-08 14:57:34.812 I/MonoDroid( 3782): UNHANDLED EXCEPTION: 04-08 14:57:34.824 I/MonoDroid( 3782): System.TypeInitializationException: 'Mob.ApiCommunication'的类型初始化程序引发了异常。 ---> System.MissingMethodException: 找不到方法“Xamarin.Forms.Device.get_RuntimePlatform”。 04-08 14:57:34.824 I/MonoDroid( 3782): --- 内部异常堆栈跟踪结束 --- 04-08 14:57:34.824 I/MonoDroid( 3782): 在 (wrapper managed-to-native) System.Object:__icall_wrapper_mono_generic_class_init (intptr) 04-08 14:57:34.824 I/MonoDroid( 3782): 在 Mob.Views.Public.LoginViewModel.RestoreState(System.Collections.Generic.IDictionary`2[TKey,TValue] dictionary)[0x00001]中的C:\Users...\Source...\LoginViewModel.cs:52 04-08 14:57:34.824 I/MonoDroid( 3782): 在 Mob.App.OnStart ()[0x00001]中的C:\Users...\App.xaml.cs:39 04-08 14:57:34.824 I/MonoDroid( 3782): 在 Xamarin.Forms.Application.SendStart ()[0x00000]中的C:\BuildAgent2\work\ca3766cfc22354a1\Xamarin.Forms.Core\Application.cs:228 04-08 14:57:34.824 I/MonoDroid( 3782): 在 Xamarin.Forms.Platform.Android.FormsAppCompatActivity+d__43.MoveNext ()[0x0003b]中的C:\BuildAgent2\work\ca3766cfc22354a1\Xamarin.Forms.Platform.Android\AppCompat\FormsAppCompatActivity.cs:426 04-08 14:57:34.824 I/MonoDroid( 3782): --- 前一个位置引发异常的堆栈跟踪结束 --- 04-08 14:57:34.824 I/MonoDroid( 3782): 在 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw ()[0x0000c]中的/Users/builder/data/lanes/4468/f913a78a/source/mono/mcs/class/referencesource/mscorlib/system/runtime/exceptionservices/exceptionservicescommon.cs:143 04-08 14:57:34.824 I/MonoDroid( 3782): 在 System.Runtime.CompilerServices.AsyncMethodBuilderCore.m__0(System.Object state)[0x00000]中的/Users/builder/data/lanes/4468/f913a78a/source/mono/mcs/class/referencesource/mscorlib/system/runtime/compilerservices/AsyncMethodBuilder.cs:1018 04-08 14:57:34.824 I/MonoDroid( 3782): 在 Android.App.SyncContext+c__AnonStorey0.<>m__0 ()[0x00000]中的/Users/builder/data/lanes/4468/b16fb820/source/xamarin-android/src/Mono.Android/Android.App/SyncContext.cs:35 04-08 14:57:34.824 I/MonoDroid( 3782): 在 Java.Lang.Thread+RunnableImplementor.Run ()[0x0000b]中的/Users/builder/data/lanes/4468/b16fb820/source/xamarin-android/src/Mono.Android/Java.Lang/Thread.cs:36 04-08 14:57:34.824 I/MonoDroid( 3782): 在 Java.Lang.IRunnableInvoker.n_Run (System.IntPtr jnienv, System.IntPtr native__this)[0x00009]中的/Users/builder/data/lanes/4468/b16fb820/source/monodroid/src/Mono.Android/platforms/android-25/src/generated/Java.Lang.IRunnable.cs:81 04-08 14:57:34.824 I/MonoDroid( 3782): 在 (wrapper dynamic-method) System.Object:88db5e57-5ac7-4ba4-a574-4ec5eaf704fd (intptr,intptr)

我在使用RuntimePlatform时是否漏掉了什么?我查看了相关文档和样例,但目前所有关于Device类的资料都在使用已废弃的成员。


只是注意,我目前也遇到了相同的问题,所以不是你的配置引起的。发行说明中也没有任何提示表明这种变化。在撰写本文时,我将继续使用Device.Os,因为它仍然有效。 - App Pack
以下代码在我使用的Xamarin Forms版本2.3.4.224上运行良好:bool isAndroid = Device.RuntimePlatform == Device.Android; 此外,这里有非官方文档:https://github.com/xamarin/Xamarin.Forms/pull/658 - hvaughan3
很遗憾,情况还是一样的。 - TaiT's
1
你确定你的Android项目使用的是与你的共享/PCL项目相同的Xamarin Forms版本吗?当你运行iOS项目时,是否会出现相同的错误? - hvaughan3
是的,我确定!而且在iOS和Android上都出现了同样的错误! - TaiT's
@AppPack:检查一下我的答案。你可能想试一试! - TaiT's
4个回答

5
我提出了一个解决方案。奇怪的是,在发布到SO之前,我已经在我的Xamarin项目中尝试过这个方法,但没有任何效果。但是这一次,在阅读Xamarin论坛上的这个帖子后:https://forums.xamarin.com/discussion/92455/xamarin-forms-2-3-4-224,我做了以下操作:

我关闭VisualStudio,清除所有项目中的“bin”和“obj”文件夹,然后重新启动VS,再清理和重建解决方案。

现在,Debug.WriteLine(Device.RuntimePlatform); 就会按照预期返回“Android”字符串!


它总是这个干净的项目。为什么他们不能自动化,令人难以置信。 - Emil
很好,很高兴你找到了它。我自己写了一个PowerShell脚本来删除给定目录中的所有obj和bin子文件夹。我经常要使用它。 - hvaughan3
我不知道为什么它已经过时了。太奇怪了。枚举比魔术字符串更好!!! - Mahdi

5

Xamarin.Forms-2.3.4.224已经改变了条件检查方式:

if (Device.OS == TargetPlatform.iOS) 
{

}

致:

if (Device.RuntimePlatform.Equals("Android"))
{
    Debug.WriteLine($"Onplatform: {Device.RuntimePlatform}");
}
else if (Device.RuntimePlatform.Equals("iOS"))
{
    Debug.WriteLine($"Onplatform: {Device.RuntimePlatform}");
}

1
如果(Device.RuntimePlatform == Device.iOS) { //iOS 的东西 } 否则如果(Device.RuntimePlatform == Device.Android) {} - Suchith

0

我使用以下内容没有任何问题

if(Device.RuntimePlatform.Equals("Android")){
  //YOUR CODE
}else if(Device.RuntimePlatform.Equals("iOS")){
  //YOUR CODE
}

看起来 Visual Studio 标准的“关闭并重新打开”答案是解决方案...


0

hvaughan3对OP的评论让我明白了。确保不仅你的PCL,而且你的Android/iOS等项目也更新了它们的包。然后按照OP的采纳答案进行完全清理和构建。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接