Xamarin.Essentials FilePicker 导致应用重启
Xamarin.Essentials FilePicker causes restart of app
我们有一个具有选项卡视图的 Xamarin Forms 应用程序。从其中一个选项卡,我们打开一个新的内容页面,它需要有一个选项 select 文件并上传附件。 使用 Xamarin.Essentials FilePicker,我们可以选择文件并读取文件内容,但在读取文件后,应用程序会自动导航到主屏幕 - 与应用程序重启相同。
我们观察到,当打开文件选择器时,会调用 App.xaml.cs 中的 OnSleep,当读取文件并关闭选择器时,会调用 App.xaml.cs 中的 onresume。这似乎会导致 XForms 应用程序完全重新启动。
所有权限都已到位 - 我们的目标是 Android 9.0,使用 XForms 4.8 版,X.Essentials v1.6。
你能帮忙吗?
相关代码:
try
{
var file = await FilePicker.PickAsync();
if (file != null)
{
var stream = await file.OpenReadAsync();
byte[] FileData = new byte[stream.Length];
await stream.ReadAsync(FileData, 0, (int)(stream.Length - 1));
fileData = Convert.ToBase64String(FileData);
fileStream = new MemoryStream(FileData);
FileNameVisibility = true;
FileName = file.FileName;
}
}
catch (Exception ex)
{
Crashes.TrackError(ex);
}
已测试 code snippet in doc。
这段代码对我有用:
FilePickerPage.xaml:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="XFSOAnswers.FilePickerPage">
<ContentPage.Content>
<StackLayout>
<Button Text="Pick File" Clicked="PickFileButton_Clicked" />
<Label x:Name="FileName" />
<Image x:Name="FileImage" />
</StackLayout>
</ContentPage.Content>
</ContentPage>
FilePickerPage.xaml.cs:
using System;
using System.Threading.Tasks;
using Xamarin.Essentials;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace XFSOAnswers
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class FilePickerPage : ContentPage
{
public FilePickerPage()
{
InitializeComponent();
}
private void PickFileButton_Clicked(object sender, EventArgs e)
{
Device.BeginInvokeOnMainThread(async () =>
{
await PickAndShow(PickOptions.Images);
});
}
async Task<FileResult> PickAndShow(PickOptions options)
{
try
{
var result = await FilePicker.PickAsync(options);
if (result != null)
{
FileName.Text = $"File Name: {result.FileName}";
if (result.FileName.EndsWith("jpg", StringComparison.OrdinalIgnoreCase) ||
result.FileName.EndsWith("png", StringComparison.OrdinalIgnoreCase))
{
var stream = await result.OpenReadAsync();
FileImage.Source = ImageSource.FromStream(() => stream);
}
}
return result;
}
catch (Exception ex)
{
// The user canceled or something went wrong
_ = ex;
}
return null;
}
}
}
App.xaml.cs:
...
MainPage = new StartPage();
起始页:
... had a button to go to FilePickerPage.
因此 StartPage 在堆栈上,然后是 FilePickerPage。
完成 FilePicker 后,FilePickerPage 仍在显示 - 文件名和图像:
MainActivity.cs:
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
...
}
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
{
Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
注意:上面的 MainActivity 代码应该自动出现在任何新的 Xamarin Forms 项目中;只有在项目模板自动添加 Essentials 之前,如果这是一个旧项目,它才会丢失。
那么,如何调试您的代码。
- 先把里面的代码全部注释掉
if (file != null) { ... }
注释掉时,崩溃与否?
- 包装您显示的整个代码片段:
Device.BeginInvokeOnMainThread( async () => {
... YOUR CODE ...
});
- 是的,确实会调用 OnSleep / OnResume。不,这不一定是“重新启动应用程序”。
也许您的导航堆栈是空的?当 FilePicker 关闭时,可能无处可回。