我正在测试我的MonoDroid应用程序。通过测试的每个循环都涉及给应用程序一个简单的输入,然后更新UI。在经过压力测试的97次循环后,我一直看到以下情况。之后,UI不再更新:
[Surface] dequeueBuffer failed (Invalid argument)
[ViewRootImpl] Could not lock surface
[ViewRootImpl] java.lang.IllegalArgumentException
[ViewRootImpl] at android.view.Surface.nativeLockCanvas(Native Method)
[ViewRootImpl] at android.view.Surface.lockCanvas(Surface.java:243)
[ViewRootImpl] at android.view.ViewRootImpl.drawSoftware(ViewRootImpl.java:2435)
[ViewRootImpl] at android.view.ViewRootImpl.draw(ViewRootImpl.java:2409)
[ViewRootImpl] at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2253)
[ViewRootImpl] at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1883)
[ViewRootImpl] at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1000)
[ViewRootImpl] at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5670)
[ViewRootImpl] at android.view.Choreographer$CallbackRecord.run(Choreographer.java:761)
[ViewRootImpl] at android.view.Choreographer.doCallbacks(Choreographer.java:574)
[ViewRootImpl] at android.view.Choreographer.doFrame(Choreographer.java:544)
[ViewRootImpl] at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:747)
[ViewRootImpl] at android.os.Handler.handleCallback(Handler.java:733)
[ViewRootImpl] at android.os.Handler.dispatchMessage(Handler.java:95)
[ViewRootImpl] at android.os.Looper.loop(Looper.java:136)
[ViewRootImpl] at android.app.ActivityThread.main(ActivityThread.java:5017)
[ViewRootImpl] at java.lang.reflect.Method.invokeNative(Native Method)
[ViewRootImpl] at java.lang.reflect.Method.invoke(Method.java:515)
[ViewRootImpl] at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
[ViewRootImpl] at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
[ViewRootImpl] at dalvik.system.NativeStart.main(Native Method)
[InputMethodManager] IME died: com.google.android.inputmethod.latin/com.android.inputmethod.latin.LatinIME
[InputMethodManager] android.os.TransactionTooLargeException
[InputMethodManager] at android.os.BinderProxy.transact(Native Method)
[InputMethodManager] at com.android.internal.view.IInputMethodManager$Stub$Proxy.startInput(IInputMethodManager.java:604)
[InputMethodManager] at android.view.inputmethod.InputMethodManager.startInputInner(InputMethodManager.java:1173)
[InputMethodManager] at android.view.inputmethod.InputMethodManager.checkFocus(InputMethodManager.java:1282)
[InputMethodManager] at android.view.ViewRootImpl$ViewRootHandler.handleMessage(ViewRootImpl.java:3201)
[InputMethodManager] at android.os.Handler.dispatchMessage(Handler.java:102)
[InputMethodManager] at android.os.Looper.loop(Looper.java:136)
[InputMethodManager] at android.app.ActivityThread.main(ActivityThread.java:5017)
[InputMethodManager] at java.lang.reflect.Method.invokeNative(Native Method)
[InputMethodManager] at java.lang.reflect.Method.invoke(Method.java:515)
[InputMethodManager] at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
[InputMethodManager] at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
[InputMethodManager] at dalvik.system.NativeStart.main(Native Method)
有趣的是,我没有使用任何明确的surfaceView,但我确实有scrollViews和很多RelativeLayouts。
我很好奇,如果有人之前见过这个,如果是的话,你是如何处理它的。我确实发现了类似的崩溃here和here,建议将图层类型设置为软件。但是,在我的情况下,将图层类型设置为软件只会略微推迟崩溃(98个循环而不是97个)。
编辑:几乎整个应用程序的UI都是用代码创建的,而不是XML。布局主要由此方法控制。 Element的东西都是自定义的,与Xamarin.Forms无关。基本上,应用程序的核心已计算出布局,前端正在通过以下方法应用它。public static void UpdateLayoutParamsFromModel(this View This) {
INativeElement nativeThis = This as INativeElement;
if (nativeThis != null) {
IViewParent parent = This.Parent;
if (parent == null || parent is RelativeLayout) {
IElement element = nativeThis.GetModel ();
if (element.HasLayout) {
RectangleF arranged = element.Arranged;
var layoutParams = new RelativeLayout.LayoutParams ((int)arranged.Width, (int)arranged.Height);
layoutParams.LeftMargin = (int)arranged.X;
layoutParams.TopMargin = (int)arranged.Y;
This.LayoutParameters = layoutParams;
}
}
}
进一步编辑:ScrollViews基本上是我使用ListViews而没有ListViews所需的所有重载的方式。他们像这样创造他们的孩子。 ListViewSectionModel是一个核心对象,无论名称如何,它都为整个ListView建模。
public void CreateChildren() {
Android.Content.Context context = this.Context;
ListViewSectionModel model = this.Model;
int count = model.Count;
LinearLayout layout = new LinearLayout (context);
layout.SetBackgroundColor (Android.Graphics.Color.Transparent);
layout.Orientation = Orientation.Vertical;
FrameLayout.LayoutParams layoutLayoutParams = new FrameLayout.LayoutParams (FrameLayout.LayoutParams.MatchParent, FrameLayout.LayoutParams.WrapContent);
this.AddView (layout, layoutLayoutParams);
float width = model.Width;
if (width <= 0) {
CommonDebug.BreakPoint ("Need model width to create children");
}
for (int i = 0; i < count; i++) {
IElement element = model.GetElement (i);
this.HackAddOnItemClick (element, i);
float height = float.MaxValue;
SizeF childSize = new SizeF (width, height);
ElementContainerLayout child = new ElementContainerLayout (this.Context);
View childContent = child.CreateContentView (element, childSize);
float elementHeight = element.Arranged.Height;
float bigNumber = 100000;
if (elementHeight > bigNumber) {
CommonDebug.BreakPoint ("Element needs to pick a minimal height when arranging itself.");
}
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams (LinearLayout.LayoutParams.MatchParent, LinearLayout.LayoutParams.WrapContent);
layout.AddView (child, layoutParams);
INativeElement nativeElementChildContent = childContent as INativeElement;
if (nativeElementChildContent == null) {
CommonDebug.BreakPoint ("should be making an INativeElement.");
}
this.NativeElementChildren.Add (nativeElementChildContent);
{ // divider
View view = new View (this.Context);
view.SetBackgroundColor (Android.Graphics.Color.Gray);
LinearLayout.LayoutParams dividerParams = new LinearLayout.LayoutParams (LinearLayout.LayoutParams.MatchParent, 2);
layout.AddView (view, dividerParams);
}
}
}