I am experiencing stress testing of my MonoDroid app. Each test cycle involves providing a simple input application, and then updating the user interface. I constantly see the following after 97 cycles of the stress test. Subsequently, the user interface is no longer updated:
[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)
Interestingly, I DO NOT use an explicit surface view, but I have scrollViews and many RelativeLayouts.
I wonder if someone has seen this before, and if so, how did you deal with it. I found similar crashes here and here , with a suggestion to set the layer type for the software. However, in my case, setting the layer type to software just slightly delayed the crash (98 cycles instead of 97).
EDIT: Almost the entire user interface of the application is created in code, not in XML. These layouts are mainly controlled by this method. Element is a regular element and is not related to Xamarin.Forms. Basically, the application kernel computed the layout, and the front end applies it using the method below.
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; } } }
FURTHER EDIT: ScrollViews are basically my way of having ListViews without all the reloads that ListView entails. They create their children in this way. ListViewSectionModel is the main object that, despite the name, models the entire 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); {