首页 文章

Xamarin.Forms DependencyService无法在文件处理中共享接口跨平台

提问于
浏览
0

我使用 .net-standard-2.0 PCL项目关注official Xamarin guide进行跨平台文件处理 . 该应用程序旨在为Android和Windows构建 .

它在这里提出了一个问题 . 接口代码如下 .

public interface ISaveAndLoad {
    void SaveText (string filename, string text);
    string LoadText (string filename);
}

但是,为UWP提供的代码写为

[assembly: Dependency(typeof(SaveAndLoad_WinApp))]
namespace WindowsApp
{
    // https://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh758325.aspx
    public class SaveAndLoad_WinApp : ISaveAndLoad
    {
        public async Task SaveTextAsync(string filename, string text)
        {
            StorageFolder localFolder = ApplicationData.Current.LocalFolder;
            StorageFile sampleFile = await localFolder.CreateFileAsync(filename, CreationCollisionOption.ReplaceExisting);
            await FileIO.WriteTextAsync(sampleFile, text);
        }
        public async Task<string> LoadTextAsync(string filename)
        {
            StorageFolder storageFolder = ApplicationData.Current.LocalFolder;
            StorageFile sampleFile = await storageFolder.GetFileAsync(filename);
            string text = await Windows.Storage.FileIO.ReadTextAsync(sampleFile);
            return text;
        }
    }
}

代码将无法编译,因为 SaveAndLoad_WinApp 未实现接口 ISaveAndLoad .

我知道我可以将接口更改为 TaskTask<string> ,因此它将进行编译 .

然而问题可以追溯到Android . UWP正在使用Android上不存在的 Windows.Storage.FileIO 事物 . 虽然Android正在使用 System.IO ,但它没有可以等待的异步方法 . 这意味着我无法共享界面,因为UWP需要 async Task<string> 但Android只返回 string 而不是 Task .

如果我在UWP方法中没有使用 async ,则 FileIO 将无效,反之亦然 . async void for SaveText 工作正常,因为接口状态 void . 但是,它不允许我为 LoadText 制作 async string ,因为异步方法必须返回 Task<T>Taskvoid .

似乎要走的路也将在Android上实现异步,同时让代码运行同步 . 但是,我觉得我做错了,因为Xamarin样本显示它应该工作 .

我在这里误解了什么或者错过了实施吗?或者它在Xamarin文档中实际上是错误的?


UPDATE #1 我为 SaveText 放了一个 async void ,并意识到有一个问题就是没有等待线程 . 它快速转发到下一个功能 . 所以我实际上必须等待PCL中的UWP功能 . 然而,Android上的实现是一个无法等待的 void . 所以它实际上导致了错误......有没有关于如何实现这种情况的建议?

这是我在PCL中输入的代码

public static void Save(){
    DependencyService.Get<ISaveAndLoad>().SaveText("temp.txt", input.Text);
}

1 回答

  • 0

    代码将无法编译,因为SaveAndLoad_WinApp未实现接口ISaveAndLoad .

    你可以下载文件样本WorkingWithFiles,你可以找到here . 在此示例中,ISaveAndLoad接口有一点区别:

    public interface ISaveAndLoad
    {
        Task SaveTextAsync (string filename, string text);
        Task<string> LoadTextAsync (string filename);
        bool FileExists (string filename);
    }
    

    UWP正在使用Android上不存在的Windows.Storage.FileIO . 虽然Android正在使用System.IO,但它没有可以等待的异步方法 .

    您可以在示例项目中引用SaveAndLoad_Android.cs类,使用StreamWriter.WriteAsync()方法:

    public class SaveAndLoad_Android : ISaveAndLoad
    {
        #region ISaveAndLoad implementation
    
        public async Task SaveTextAsync (string filename, string text)
        {
            var path = CreatePathToFile (filename);
            using (StreamWriter sw = File.CreateText (path))
                await sw.WriteAsync(text);
        }
    
        public async Task<string> LoadTextAsync (string filename)
        {
            var path = CreatePathToFile (filename);
            using (StreamReader sr = File.OpenText(path))
                return await sr.ReadToEndAsync();
        }
    
        public bool FileExists(string filename)
        {
            return File.Exists(CreatePathToFile(filename));
        }
    
        #endregion
    
        string CreatePathToFile(string filename)
        {
            var docsPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
            return Path.Combine(docsPath, filename);
        }
    }
    

    然后在 PCL 中,使用SaveTextAsync方法,如下所示:

    var fileService = DependencyService.Get<ISaveAndLoad> ();
    ...
    saveButton.Clicked += async (sender, e) => 
    {
        loadButton.IsEnabled = saveButton.IsEnabled = false;
        // uses the Interface defined in this project, and the implementations that must
        // be written in the iOS, Android and WinPhone app projects to do the actual file manipulation
    
        await fileService.SaveTextAsync (fileName, input.Text);
        loadButton.IsEnabled = saveButton.IsEnabled = true;
    };
    

相关问题