ListView上的内存泄漏(由于ByteArrayToImageConverter)

时间:2017-12-06 10:58:25

标签: c# xamarin xamarin.forms xamarin.android

我使用ByteArrayToImageConverter来转换来自SQL Server数据库的字节数组,转换器如下所示

 public class ByteArrayToImageConverter : IValueConverter
    {
        public ImageSource retSource;
        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();
        }

我的观点模型如下

 public class ResturentItems    {
        public long ID { get; set; }
        public string Category { get; set; }
        public string Name { get; set; }
        public string Code { get; set; }
        public string Description { get; set; }
        public decimal Price { get; set; }
        public bool isservicecharge { get; set; }
        public decimal CostPrice { get; set; }
        public string Date { get; set; }      
        public byte[] Image { get; set; }    }

    public class ResturentList
    {
        public List<ResturentItems> Resturent { get; set; }
    }

背后的网络页面代码

namespace TestProject.Views.DetailViews
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class FoodTabPage : ContentPage
    {
        private List<ResturentItems> _foodList;
        public FoodTabPage(string categoryName, List<ResturentItems>foodList)
        {
            InitializeComponent();
            this.BackgroundImage = "background.png";

            // createEventsList();           
            Title = categoryName;            
            mealsListView.ItemsSource = foodList;
            _foodList = foodList;

        }

        private void Search(object sender, EventArgs e)
        {
            stackLayoutShowHide.IsVisible = !stackLayoutShowHide.IsVisible;
        }

        private void searchChanged(object sender, TextChangedEventArgs e)
        {

            if (string.IsNullOrWhiteSpace(e.NewTextValue))
                mealsListView.ItemsSource = _foodList;
            else
                mealsListView.ItemsSource = _foodList.Where(i => i.Name.ToLower().Contains(e.NewTextValue.ToLower()));
        }


        private void listviewContacts_ItemSelected(object sender, SelectedItemChangedEventArgs e)
        {
            var itemSelectedData = e.SelectedItem as ResturentItems;
            Navigation.PushAsync(new JsonDetailsPage(itemSelectedData.ID, itemSelectedData.Image, itemSelectedData.Name, itemSelectedData.Code, itemSelectedData.Description, itemSelectedData.Price, itemSelectedData.isservicecharge, itemSelectedData.CostPrice));
            //this.Content = null;
            //this.BindingContext = null;
            //GC.Collect(1);
        }


        protected override void OnDisappearing()
        {
            // ImagesStackLayout.Children.Clear();

            GC.Collect();
           // mealsListView.BindingContext = null;
           // this.Content = null;
            //mealsListView.ItemsSource = null;
            //this.BindingContext = null;
            //GC.Collect(1);
        }

    }


} 

标准页面的XAML

<?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.FoodTabPage"
             xmlns:local ="clr-namespace:TestProject.Data">   
    <ContentPage.Resources>
        <ResourceDictionary>
            <local:ByteArrayToImageConverter x:Key="severityTypeImageConvertertwo"/>
        </ResourceDictionary>
    </ContentPage.Resources>
    <ContentPage.ToolbarItems>
        <ToolbarItem Text="Search" Clicked="Search"/>
    </ContentPage.ToolbarItems>
    <ContentPage.Content>       
            <StackLayout>
                <StackLayout x:Name="stackLayoutShowHide" IsVisible="False">
                    <Entry Placeholder="Your text to search" TextChanged="searchChanged" TextColor="Gray" BackgroundColor="White"/>
                </StackLayout>
                <ListView x:Name="mealsListView" HasUnevenRows="True" ItemSelected="listviewContacts_ItemSelected" CachingStrategy="RecycleElement" >
                <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>
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

我通过带API调用的标签页获取内容页面数据,如下所示

public partial class FoodTabbedPage : TabbedPage
    {
        // List<ResturentItems> ResturentList = new List<ResturentItems>();
        List<ResturentItems> ResturentList;
        //SearchBar searchBar;
        //Label resultsLabel;

        public FoodTabbedPage()
        {

          //  List<ResturentItems> ResturentList = new List<ResturentItems>();
            InitializeComponent();
            this.BackgroundImage = "Resources/drawable/background.png";
            this.BackgroundColor = Color.Maroon;
            Children.Add(new TabLoader());


            //View.BackgroundColor = UIColor.FromPatternImage(UIImage.FromFile("Images/bg.png"));
            //this.ParentView = "background.png";
            // this.View.BackgroundColor = UIColor.FromPatternImage(UIImage.FromFile("your-background.png"));
            //ActivityIndicator ciclenow = new ActivityIndicator();
            //ciclenow.Color = Color.Green;
            //ciclenow.IsRunning = true;
            ActivityIndicator ai = new ActivityIndicator
            {
                Color = Color.Black,
                IsRunning = true,
            };


            this.IsBusy = true;
            GetJSON();
            //Children.Remove(new JsonDesertNew());
            //var stack = new StackLayout
            //{
            //    Spacing = 20,
            //    Children = {
            //             new Label {Text = "Hello World!"},
            //             new Button {Text = "Click Me!"}
            //                }
            //};

            //ToolbarItem cartItem = new ToolbarItem();            
            //cartItem.Order = ToolbarItemOrder.Primary;
            //cartItem.Text = "serch";
            //cartItem.Command = new Command(() => Navigation.PushAsync(new SearchItemsPage()));
            //ToolbarItems.Add(cartItem);

            ToolbarItem serch = new ToolbarItem();
            serch.Order = ToolbarItemOrder.Secondary;
            serch.Text = "SERCH MORE";
            serch.Command = new Command(() => Navigation.PushAsync(new SearchItemsPage()));
            ToolbarItems.Add(serch);

        }




        public async void GetJSON()
        {

            var client = new System.Net.Http.HttpClient();               
                var response = await client.GetAsync("http://192.168.43.51/TabPageAll.php");
                string contactsJson = response.Content.ReadAsStringAsync().Result;
                if (response.IsSuccessStatusCode)
                {
                    var list = JsonConvert.DeserializeObject<ResturentList>(contactsJson);
                    ResturentList = new List<ResturentItems>(list.Resturent);
                    List<string> allCategories = ResturentList.Select(x => x.Category).ToList();
                    allCategories = allCategories.Distinct().ToList();
                    foreach (var category in allCategories)
                    {
                    //Children.Remove(Children.First());
                    Children.Add(new FoodTabPage(category, ResturentList.Where(x => x.Category == category).ToList()));
                    // Children.Remove(Children.First());

                    }
                Children.Remove(Children.First());
                }
                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");
                }


        }

我的问题当我在xaml列表视图中显示所有图像(与我的模型绑定)我有记忆泄漏时,每次打开列表视图时内存逐渐增长,Whast是减少memeor泄漏问题的解决方案使用转换器和列表视图(顺便说一下我使用CachingStrategy="RecycleElement",但它可以减少内存泄漏。如果有任何人遇到此类问题请告诉我。 ProfilerImage ProfilerImage2

感谢您的支持。 泛

0 个答案:

没有答案