我在Xamarin.Forms / Android中使用MasterDetailPage,汉堡包页面中的每个项目代表一个页面。我通过调用:
来更改详细信息页面Detail = new NavigationPage(new Pages.HomePage());
IsPresented = false;
我注意到这个页面的分配有点大(它的请求类似于22mb)。不仅如此,如果我反复按侧边栏的主页按钮,我会在大约5次点击后得到一个OutOfMemoryException。所以有些东西没有点击垃圾收集。
主页有一个自定义渲染器,它基本上使用三个png文件合成图像。这可以在我的手机上实现最小的减速,但是当它在屏幕上时,模拟器会显着滞后,这让我相信它会导致性能问题。
public class GoalJarViewRenderer : ImageRenderer
{
Bitmap fillBmp = null;
Bitmap jarHud = null;
Paint font;
Paint fontBold;
string goalString = "";
string progString = "";
protected override void OnElementChanged(ElementChangedEventArgs<Image> e)
{
this.SetWillNotDraw(false);
base.OnElementChanged(e);
Element.PropertyChanged += SignalUpdate;
//Cache
if (fillBmp == null) fillBmp = BitmapFactory.DecodeResource(this.Context.Resources, Resource.Drawable.jar_fill);
if (jarHud == null) jarHud = BitmapFactory.DecodeResource(this.Context.Resources, Resource.Drawable.jar_hud);
if (font == null)
{
font = new Paint();
font.AntiAlias = true;
font.Color = Android.Graphics.Color.White;
font.TextSize = 50;
font.TextAlign = Paint.Align.Center;
}
if (fontBold == null)
{
fontBold = new Paint(font);
fontBold.FakeBoldText = true;
fontBold.TextSize = 80;
}
}
private void SignalUpdate(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
GoalJarView handle = (GoalJarView)this.Element;
goalString = String.Format("${0:#0.0#} / ${1:##.##}", handle.CurrentValue, handle.GoalValue);
progString = String.Format("{0:##0.00}%", (handle.CurrentValue / handle.GoalValue) * 100);
this.Invalidate();
}
public override void Draw(Canvas canvas)
{
base.Draw(canvas);
//Draw the fill
double LID_FIX = 0.91;
GoalJarView handle = (GoalJarView)this.Element;
double fillRatio = Math.Min(1,((handle.CurrentValue * LID_FIX) / handle.GoalValue));
int srcStartY = (int)(fillBmp.Height - Math.Floor(fillBmp.Height * fillRatio));
int destStartY = (int)(canvas.Height - Math.Floor(canvas.Height * fillRatio));
Rect fillSrc = new Rect(0, srcStartY, fillBmp.Width, fillBmp.Height);
RectF fillDest = new RectF(0, destStartY, canvas.Width, canvas.Height);
canvas.DrawBitmap(fillBmp, fillSrc, fillDest, null);
//Draw the text container
canvas.DrawBitmap(jarHud, null, new Rect(0,0,canvas.Width,canvas.Height), null);
//Draw the Text
canvas.DrawText(progString, canvas.Width / 2, (canvas.Height / 2) - 20, fontBold);
canvas.DrawText(goalString, canvas.Width / 2, (canvas.Height / 2) + 30, font);
}
}
我被告知BitmapFactory.DecodeResource令人难以置信的负担,所以我把它移到了OnElementChanged而不是draw函数。我没有看到任何其他东西立即在Draw()内部征税,但我是Xamarin / Android的新手,并认为这个问题对于经验丰富的开发人员来说是显而易见的。
我已经尝试在MasterDetailPage上创建存储页面的局部变量,因此每次按下一个项目时都不需要创建局部变量,但这会在页面重新打开时导致崩溃,因为存储数据的实际控件类绑定为空。
导致此内存泄漏的原因是什么?如何更正?