2016-12-11 1 views
0

Ich versuche, von URL, die auf ein Bild verweist, zu zeichnen. Aber das Problem ist, dass Sie in Android nicht Netzwerkaufgaben auf dem Hauptthread ausführen sollten. Aus diesem Grund verwende ich async/await block, aber der Fehler tritt immer noch auf. Hier ist der Code:Android.OS.NetworkOnMainThreadException: in async/erwarten Block

page.Appearing += async(sender, ev3) => 
        { 
         if (GetToolbar == null) return; 

         GetToolbar.Subtitle = viewModel?.SubTitle; 

         if (viewModel == null) return; 

         if (viewModel.AvatarUrl.Contains("?") && !viewModel.AvatarUrl.Contains("gravatar")) 
          viewModel.AvatarUrl = viewModel.AvatarUrl 
           .Substring(0, viewModel.AvatarUrl.IndexOf("?", StringComparison.Ordinal)); 

         //var stream = Context.ContentResolver.OpenInputStream(Android.Net.Uri.Parse(viewModel.AvatarUrl)); 

         await SetLogo(viewModel); 
} 

private async Task SetLogo(PublicRepositoryPageViewModel viewModel) 
     { 
      var url = new URL(viewModel.AvatarUrl); 
      var connection = url.OpenConnection(); 
      var stream = connection.InputStream; 
      var logo = await Drawable.CreateFromStreamAsync(stream, viewModel.Title + "_avatar"); 
      GetToolbar.Logo = logo; 
     } 

genau kommt es auf dieser Linie:

var stream = connection.InputStream; 

Wenn ich OpenInputStream anstatt sie verwenden, dann wirft es java.io.FileNotFoundException: Keine Content-Provider: https://avatars.githubusercontent.com/u/6516107

Ich habe Internet-Erlaubnis überprüft.

Es ist Xamarin.Forms Android Projekt

ANTWORT:

await Task.Run(async() => { 
          var url = new URL(viewModel.AvatarUrl); 
          var connection = url.OpenConnection(); 
          var stream = connection.InputStream; 
          var logo = await Drawable.CreateFromStreamAsync(stream, viewModel.Title + "_avatar"); 
          Device.BeginInvokeOnMainThread(()=>GetToolbar.Logo = logo); 
         }); 

Antwort

1

A Task.Run werden Sie aus dem Haupt-Thread erhalten und auf ein Gewinde in dem Standardthread:

await Task.Run(async() => { 
    var url = new URL(viewModel.AvatarUrl); 
    var connection = url.OpenConnection(); 
    var stream = connection.InputStream; 
    var logo = await Drawable.CreateFromStreamAsync(stream, viewModel.Title + "_avatar"); 
    GetToolbar.Logo = logo; 
}); 
+0

Sie haben ein asynchrones Keyword vor lambda verpasst. Danke. Es hat einen Trick gemacht. Vielleicht hast du eine Quelle, das erklärt es? –

+0

@YuraBabiy Danke, ich repariere das fehlende Async. – SushiHangover

+1

Wenn Sie nur eine Methode mit "async" markieren, führt dies nicht dazu, dass der Methodenkörper einen anderen Thread ausführt. Nun, sobald es eine erwartete Aufgabe trifft, wird es (standardmäßig) in einen Thread-Pool verschoben, so dass es den aufrufenden Thread nicht blockiert (Sie haben also eine asynchrone Funktion) und jetzt "aus" den Thread, der es gestartet hat, in diesem Fall , der Haupt-Messaging/Looper-Thread der Benutzeroberfläche. Nachdem die erwartete Aufgabe abgeschlossen ist, wird der Rest der Methode weiter ausgeführt (diese werden "Fortsetzungen" genannt) und in einem Thread-Pool ausgeführt (der Standard "SynchronizationContext" basiert auf dem Thread-Pool, kann aber geändert werden ...) – SushiHangover

Verwandte Themen