Ja, ich habe eine Lösung gefunden. Code zu folgen. Aber vorher, lassen Sie mich ein bisschen erklären, was ich getan habe.
Also, es ist definitiv eine Notwendigkeit, in unseren eigenen Händen zu nehmen, um das Bild und die zugrunde liegenden Ressourcen (Bitmap oder zeichnest, wie Sie es nennen möchten) zu entsorgen. Im Grunde kommt es darauf an, das native 'ImageRenderer'-Objekt zu entfernen.
Jetzt gibt es keine Möglichkeit, von überall einen Verweis auf diesen ImageRenderer zu erhalten, weil dazu Platform.GetRenderer (...) aufgerufen werden muss. Der Zugriff auf die Klasse "Plattform" ist nicht möglich, da der Geltungsbereich als "intern" deklariert ist.
So blieb mir keine andere Wahl übrig, als die Image-Klasse und ihren (Android-) Renderer zu unterteilen und diesen Renderer selbst von innen zu zerstören (als Argument 'true' übergeben. Nicht mit 'false' versuchen '). Innerhalb des Renderers hake ich auf Seite verschwinden (im Falle einer TabbedPage). In den meisten Situationen wird das Ereignis Seite verschwinden nicht dem Zweck gut gerecht, z. B. wenn sich die Seite noch im Bildschirmstapel befindet, aber verschwindet, weil eine andere Seite unter Top davon gezeichnet wird. Wenn Sie die Bilder entsorgt haben und die Seite wieder freigelegt (angezeigt) wird, werden die Bilder nicht angezeigt. In diesem Fall müssen wir uns auf das "Popped" -Ereignis der Hauptnavigationsseite begeben.
Ich habe versucht, es so gut wie möglich zu erklären. Der Rest - ich hoffe - Sie werden in der Lage sein, von dem Code zu bekommen:
Dies ist die Bildunterklasse im PCL-Projekt.
using System;
using Xamarin.Forms;
namespace ApplicationClient.CustomControls
{
public class LSImage : Image
{
}
}
Der folgende Code ist im Droid-Projekt.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Views.InputMethods;
using Android.Widget;
using Android.Util;
using Application.Droid.CustomControls;
using ApplicationClient.CustomControls;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(ApplicationClient.CustomControls.LSImage), typeof(LSImageRenderer))]
namespace Application.Droid.CustomControls
{
public class LSImageRenderer : ImageRenderer
{
Page page;
NavigationPage navigPage;
protected override void OnElementChanged(ElementChangedEventArgs<Image> e)
{
base.OnElementChanged(e);
if (e.OldElement == null)
{
if (GetContainingViewCell(e.NewElement) != null)
{
page = GetContainingPage(e.NewElement);
if (page.Parent is TabbedPage)
{
page.Disappearing += PageContainedInTabbedPageDisapearing;
return;
}
navigPage = GetContainingNavigationPage(page);
if (navigPage != null)
navigPage.Popped += OnPagePopped;
}
else if ((page = GetContainingTabbedPage(e.NewElement)) != null)
{
page.Disappearing += PageContainedInTabbedPageDisapearing;
}
}
}
void PageContainedInTabbedPageDisapearing (object sender, EventArgs e)
{
this.Dispose(true);
page.Disappearing -= PageContainedInTabbedPageDisapearing;
}
protected override void Dispose(bool disposing)
{
Log.Info("**** LSImageRenderer *****", "Image got disposed");
base.Dispose(disposing);
}
private void OnPagePopped(object s, NavigationEventArgs e)
{
if (e.Page == page)
{
this.Dispose(true);
navigPage.Popped -= OnPagePopped;
}
}
private Page GetContainingPage(Xamarin.Forms.Element element)
{
Element parentElement = element.ParentView;
if (typeof(Page).IsAssignableFrom(parentElement.GetType()))
return (Page)parentElement;
else
return GetContainingPage(parentElement);
}
private ViewCell GetContainingViewCell(Xamarin.Forms.Element element)
{
Element parentElement = element.Parent;
if (parentElement == null)
return null;
if (typeof(ViewCell).IsAssignableFrom(parentElement.GetType()))
return (ViewCell)parentElement;
else
return GetContainingViewCell(parentElement);
}
private TabbedPage GetContainingTabbedPage(Element element)
{
Element parentElement = element.Parent;
if (parentElement == null)
return null;
if (typeof(TabbedPage).IsAssignableFrom(parentElement.GetType()))
return (TabbedPage)parentElement;
else
return GetContainingTabbedPage(parentElement);
}
private NavigationPage GetContainingNavigationPage(Element element)
{
Element parentElement = element.Parent;
if (parentElement == null)
return null;
if (typeof(NavigationPage).IsAssignableFrom(parentElement.GetType()))
return (NavigationPage)parentElement;
else
return GetContainingNavigationPage(parentElement);
}
}
}
Schließlich habe ich den Namen der Anwendung im Namensraum zu ‚ApplicationClient‘ im PCL-Projekt geändert und auf ‚Application.Droid‘ in Droid Projekt. Sie sollten es zu Ihrem App-Namen ändern.
Auch die wenigen rekursiven Methoden am Ende der Renderer-Klasse, weiß ich, dass ich es in eine generische Methode kombinieren könnte. Die Sache ist, dass ich eine nach der anderen gebaut habe, als die Notwendigkeit entstand. So, so habe ich es verlassen.
Glücklich Codierung,
Avrohom
Was die Bitmap-Größe des 4K PNG ist ? PNGs werden im Speicher ohne Komprimierung gespeichert. Es ist möglich, ein 4K-PNG zu erstellen, das bei der Konvertierung in eine Bitmap weit über 1 GB Daten beträgt. Auch, ja, Sie müssen wirklich überprüfen, ob die Bitmaps entsorgt werden. Und wahrscheinlich ist die Antwort, nein, sind sie nicht. – Frank
das PNG, das ich derzeit verwende, ist als 512 x 512 definiert. – Avrohom
So dass 4kB PNG erfordert 512 x 512 x 32 Bit = 1 MB RAM zu speichern/anzuzeigen. Es ist also sehr wahrscheinlich, dass Sie sie tatsächlich nicht entsorgen. – Frank