2017-11-20 11 views
0

Ich habe Probleme mit dem Speicherproblem. Manchmal stürzt die App nach einigen Minuten aufgrund einer nicht ausreichenden Speicherausnahme ab. Ich lade die Bilder aus der SQL Server-Datenbank und konvertiert sie aus Bytes in einer separaten Klasse.viele Bilder saugen Speicher und aus dem Speicher Ausnahme?

meine XAML-Ansicht:

<?xml version="1.0" encoding="utf-8" ?> 
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" 
      xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
      x:Class="TestProject.Views.DetailViews.JsonDesertPage" 
      xmlns:local ="clr-namespace:TestProject.Data"> 
    <ContentPage.Resources> 
     <ResourceDictionary> 
      <local:ByteArrayToImageConverter x:Key="severityTypeImageConvertertwo"/> 
     </ResourceDictionary> 
    </ContentPage.Resources> 
    <ListView x:Name="listviewConactstwo" RowHeight="100" HorizontalOptions="FillAndExpand" HasUnevenRows="True" ItemSelected="listviewContacts_ItemSelected"> 
     <ActivityIndicator x:Name="ProgressLoadertwo" IsRunning="True"/> 
     <ListView.ItemTemplate > 
      <DataTemplate> 
       <ViewCell> 
        <StackLayout Orientation="Vertical" Padding="5"> 
         <StackLayout Orientation="Horizontal" BackgroundColor="Ivory" Opacity="0.9"> 
          <Image Source="{Binding Image,Converter={StaticResource severityTypeImageConvertertwo}}" HeightRequest="120" WidthRequest="120"/> 
          <StackLayout Orientation="Vertical"> 
           <Label Text="{Binding Name}" FontSize="Medium" TextColor="Gray" FontAttributes="Bold"/> 
           <BoxView HeightRequest="2" Margin="0,10,10,0" BackgroundColor="Gray" HorizontalOptions="FillAndExpand" /> 
           <Label Text="{Binding Description}" FontSize="Micro" TextColor="Gray" FontAttributes="Bold"/> 
           <StackLayout Orientation="Horizontal" VerticalOptions="Start" HorizontalOptions="Start"> 
            <Label Text="$" FontSize="Micro" VerticalOptions="Start" HorizontalOptions="Start" TextColor="Gray" FontAttributes="Bold"/> 
            <Label Text="{Binding Price}" FontSize="Micro" TextColor="Gray" FontAttributes="Bold"/> 
           </StackLayout> 
          </StackLayout> 
          <Image Source="arrowtwo.png" BackgroundColor="Transparent" WidthRequest="25" Margin="0,10,10,0"/> 
         </StackLayout>       
        </StackLayout>      
       </ViewCell>     
      </DataTemplate>    
     </ListView.ItemTemplate>   
    </ListView> 
</ContentPage> 

meinem Code hinter:

using Newtonsoft.Json; 
using Plugin.Connectivity; 
using System; 
using System.IO; 
using System.Net.Http; 
using TestProject.Data; 
using TestProject.Models; 
using Xamarin.Forms; 

namespace TestProject.Views.DetailViews 
{ 
    public partial class JsonDesertPage : ContentPage 
    { 
     public JsonDesertPage() 
     { 
      InitializeComponent(); 

      this.BackgroundImage = "background.png"; 
      this.Title = "Soup Menu"; 
      GetJSON(); 
      // CrossConnectivity.Current.ConnectivityChanged += Current_ConnectivityChanged; 
     } 


     protected async override void OnAppearing() 
     { 
      base.OnAppearing(); 

      if (!CrossConnectivity.Current.IsConnected) 
      { 
       await DisplayAlert("fail", "No Internet Connection.Offline Menu Activated", "Ok"); 
       await Navigation.PushAsync(new MainTabbed()); 
      } 
      else 
      { 
       // await DisplayAlert("sucess", " Network Is Available.", "Ok"); 
       GetJSON(); 
      } 
     } 

     public async void GetJSON() 
     {     
      var client = new HttpClient(); 
      // var response = await client.GetAsync("http://192.168.43.226/GetContactsDesert.php"); 
      var response = await client.GetAsync(Constants.BaseUrlpos + "GetContactsDesert.php");  

      string contactsJson = response.Content.ReadAsStringAsync().Result; 
      ContectList ObjContactList = new ContectList(); 

      if (response.IsSuccessStatusCode) 
      {      
       ObjContactList = JsonConvert.DeserializeObject<ContectList>(contactsJson); 
       listviewConactstwo.ItemsSource = ObjContactList.contacts; 
      } 

      else 
      { 
       var textReader = new JsonTextReader(new StringReader(contactsJson)); 
       dynamic responseJson = new JsonSerializer().Deserialize(textReader); 
       contactsJson = "Deserialized JSON error message: " + responseJson.Message; 
       await DisplayAlert("fail", "no Network Is Available.", "Ok"); 
      } 

      ProgressLoadertwo.IsVisible = false;    

     } 

     private void listviewContacts_ItemSelected(object sender, SelectedItemChangedEventArgs e) 
     { 
      var itemSelectedData = e.SelectedItem as Contactone; 
      Navigation.PushAsync(new JsonDetailsPage(itemSelectedData.ID, itemSelectedData.Image, itemSelectedData.Name, itemSelectedData.Code, itemSelectedData.Description, itemSelectedData.Price,itemSelectedData.isservicecharge, itemSelectedData.CostPrice)); 

     } 
    } 
} 

Dies ist eine der Seiten ich verwende:

using System; 
using System.Collections.Generic; 
using System.Globalization; 
using System.IO; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using Xamarin.Forms; 

namespace TestProject.Data 
{ 
    public class ByteArrayToImageConverter : IValueConverter 
    { 
     public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
     { 
      ImageSource retSource = null; 
      if (value != null) 
      { 
       byte[] imageAsBytes = (byte[])value; 
       // byte[] decodedByteArray = System.Convert.FromBase64String(Encoding.UTF8.GetString(imageAsBytes, 0, imageAsBytes.Length)); 
       // var stream = new MemoryStream(decodedByteArray); 
       retSource = ImageSource.FromStream(() => new MemoryStream(imageAsBytes)); 
      } 
      return retSource; 
     } 

     public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
     { 
      //return null; 
      throw new NotImplementedException(); 
     } 

    } 
} 

, wenn ich das Profil lief ich kann sehen Sie das Tschüß [] wächst auf, während ich mich zwischen den Seiten bewege. Ich habe versucht, die FFimageloading-Option und es scheint nicht zu unterstützen, die Byte-Array-Image-Konverter.

Wie das Problem mit dem Speicher loswerden?

Antwort

0

Spotted ein paar Dinge. Ohne einen vollständigen Lauf kann ich nicht feststellen, welche Ihre Kopfschmerzen sind, aber ...

Verwenden Sie HttpClient als Singleton. Ich habe mit einem Xam-Arch bestätigt, dass die Singleton-Nutzung sowohl für Xam als auch für alles andere optimal ist.

Achten Sie auf IDiposable Objekte.

Der folgende Code gibt eine HttpResponse-Methode zurück. HttpResponseMessage ist IDisposeable. Wickeln Sie es in eine "Verwendung".

StringReader erbt von TextReader, der IDisposable ist. Wrap in "Verwenden".

Der dynamische Typ ist unbestimmt. Am besten, es in eine Verwendung zu verpacken. Weitere Informationen finden Sie unter Do you need to dispose of objects and set them to null?.

PNP Führer zu Httpclient - https://github.com/mspnp/performance-optimization/blob/465514674354c8f833c73882f7405ac22c4fd437/ImproperInstantiation/docs/ImproperInstantiation.md

PNP Gut/Schlecht-Httpclient Probe - https://github.com/mspnp/performance-optimization/tree/465514674354c8f833c73882f7405ac22c4fd437/ImproperInstantiation

Sie verwenden Httpclient falsch und es Ihre Software destabilisiert - http://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/

sehen, ob das hilft.

private HttpClient m_httpClient = new HttpClient(); 
    private HttpClient MyHttpClient 
    { 
     get 
     { 
      if (m_httpClient==null) 
      { 
       m_httpClient = new HttpClient(); 
      } 
      return m_httpClient; 
     } 
    } 
    public async void GetJSON() 
    { 
     // var client = new HttpClient(); 
     var client = MyHttpClient; 

     // var response = await client.GetAsync("http://192.168.43.226/GetContactsDesert.php"); 
     // var response = await client.GetAsync(Constants.BaseUrlpos + "GetContactsDesert.php"); 
     string contactsJson = string.Empty; 
     using (HttpResponseMessage response = await client.GetAsync(Constants.BaseUrlpos + "GetContactsDesert.php")) 
     { 
      contactsJson = response.Content.ReadAsStringAsync().Result; 
     } 
     ContectList ObjContactList = new ContectList(); 

     if (response.IsSuccessStatusCode) 
     { 
      ObjContactList = JsonConvert.DeserializeObject<ContectList>(contactsJson); 
      listviewConactstwo.ItemsSource = ObjContactList.contacts; 
     } 

     else 
     { 
      using (var textReader = new JsonTextReader(new StringReader(contactsJson))) 
      { 
       using (dynamic responseJson = new JsonSerializer().Deserialize(textReader)) 
       { 
        contactsJson = "Deserialized JSON error message: " + responseJson.Message; 
       } 
       await DisplayAlert("fail", "no Network Is Available.", "Ok"); 
      } 
     } 

     ProgressLoadertwo.IsVisible = false; 
    } 
+0

Vielen Dank fro die Antwort, aber es ist ein Fehler, zeigt sich in den „if (response.IsSuccessStatusCode)“, und ich versuchte, es aber nicht möglich zu korrigieren, kann ich Ihnen die Xamarin Profiler Bilder zeigen, wenn Sie mögen die Rate, die der Stapel beim Laden der Bilder in die Listenansicht annimmt. Soweit ich den Grund verstehe, stapeln sich die Stapel in den geladenen Bildern nicht. Wenn es eine Möglichkeit gibt, die Listview-Bilder zu entfernen, wenn ich zur nächsten Seite navigiere, kann das helfen, die vorinstallierten Bilder zu behalten, Problem ist, weiß ich nicht, wie man es macht ???? – pan

+0

Post eine einfache Reproduktion Ich kann zu einem GitHub laufen und ich werde einen Blick darauf werfen. –

+0

Ich bin quit Neu zu Github, also habe ich meine Projektdateien hochgeladen, wenn Sie nicht in der Lage sind, es zu erhalten, lassen Sie mich wissen, um in Github den Link zu ändern https://github.com/wpanduka/panPosSystem – pan