Xamarin NullReferenceException 在活动上调用'Finish()'时



我创建了一个生物识别身份验证服务,它启动一个活动,并为结果注册一个回调到静态EventHandler

处理程序:

public class BiometricHandler : IBiometricHandler
{
private TaskCompletionSource<byte[]> taskCompletionSource;
public Task<byte[]> StartBiometricAuth()
{
Intent intent = new Intent(Android.App.Application.Context, typeof(BiometricActivity));
intent.AddFlags(ActivityFlags.NewTask);
Android.App.Application.Context.StartActivity(intent);
taskCompletionSource = new TaskCompletionSource<byte[]>();
BiometricActivity.BiometricEventHandler += BiometricCompleted;
return taskCompletionSource.Task;
}
private void BiometricCompleted(object sender, BiometricEventArgs e)
{
taskCompletionSource.SetResult(e.Success ? e.Payload : new byte[] { });
BiometricActivity.BiometricEventHandler -= BiometricCompleted;
}
}

和活动(显然不是实际代码):

public class BiometricActivity : Activity
{
public static event EventHandler<BiometricEventArgs> BiometricEventHandler;
private readonly int BIOMETRIC_REQUEST = 1;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Intent intent = new Intent(Application.Context, typeof(BiometricAuth));
StartActivityForResult(intent, BIOMETRIC_REQUEST);
}
protected override void OnActivityResult(int requestCode, [GeneratedEnum] Result resultCode, Intent data)
{
BiometricEventHandler?.Invoke(
this,
new BiometricEventArgs(
true, new byte[] {1, 2, 3}
);
Finish();

}
}

上面的代码抛出一个NullReferenceException:

0xFFFFFFFFFFFFFFFF in System.Diagnostics.Debugger.Mono_UnhandledException_internal
0x1 in System.Diagnostics.Debugger.Mono_UnhandledException at /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/mcs/class/corlib/System.Diagnostics/Debugger.cs:125,4
0x20 in Android.Runtime.DynamicMethodNameCounter.57
0x6 in Xamarin.Forms.Platform.Android.PlatformConfigurationExtensions.OnThisPlatform<Xamarin.Forms.Application> at D:a_work1sXamarin.Forms.Platform.AndroidPlatformConfigurationExtensions.cs:8,4
0xC in Xamarin.Forms.Platform.Android.AppCompat.FragmentContainer.OnResume at D:a_work1sXamarin.Forms.Platform.AndroidAppCompatFragmentContainer.cs:126,4
0x8 in AndroidX.Fragment.App.Fragment.n_OnResume at C:a_work1sgeneratedandroidx.fragment.fragmentobjReleasemonoandroid12.0generatedsrcAndroidX.Fragment.App.Fragment.cs:2570,4
0x11 in Android.Runtime.DynamicMethodNameCounter.57

和控制台:

**System.NullReferenceException:** 'Object reference not set to an instance of an object.'

我把范围缩小到Finish()方法。

不调用时不存在异常。我尝试使用BroadcastReceiver从处理程序调用Finish(),结果相同。

为什么Finish()抛出这个异常?

这个问题似乎是一个异步竞争条件。Finish()完成的时间比服务返回数据的时间稍长。

然后内容页尝试执行UI事件,并且由于Finish()尚未完成,该活动仍然是"可见"的;内容页还不负责UI线程。因此UI事件失败并产生异常。

由于似乎没有一种简单的方法来awaitFinish()调用,我使用Task.Await来延迟UI事件一点,并完成Finish()

不理想,但至少NullReferenceException不见了

最新更新