【问题标题】:how to fix Could not read input channel file descriptors from parcel in EditText.SetText on UiThread如何修复无法从 UiThread 上的 EditText.SetText 中的包裹中读取输入通道文件描述符
【发布时间】:2019-09-06 11:02:59
【问题描述】:

我在使用 Xamarin 为 Zebra TC72 条形码阅读器 (Android 8.1 API 27) 编写的应用程序时遇到问题 每次读取条码时,我都会在 EditText 中写入条码并更新 ListView。我看到在扫描 150-400 个条形码后通常发生在 SetText 行中,这给了我以下异常:

错误:Eccezione non gestita System.Exception:CurrentDomainOnUnhandledException ---> Java.Lang.RuntimeException:无法从包裹中读取输入通道文件描述符。 在 Java.Interop.JniEnvironment+InstanceMethods.CallVoidMethod(Java.Interop.JniObjectReference 实例,Java.Interop.JniMethodInfo 方法,Java.Interop.JniArgumentValue* args)[0x00069] 在:0 在 Java.Interop.JniPeerMembers+JniInstanceMethods.InvokeVirtualVoidMethod (System.String encodedMember, Java.Interop.IJavaPeerable self, Java.Interop.JniArgumentValue* 参数) [0x0002a] in :0 在 Android.Widget.TextView.SetText (Java.Lang.ICharSequence 文本,Android.Widget.TextView+BufferType 类型) [0x0004b] in :0 在 Android.Widget.TextView.SetText (System.String text, Android.Widget.TextView+BufferType 类型) [0x0000d] in :0 在 Droid.ScannerActivity_V1+c__DisplayClass23_0.b__0 () [0x00016] 在 :0 在 :0 中的 Java.Lang.Thread+RunnableImplementor.Run () [0x00008] 在 :0 中的 Java.Lang.IRunnableInvoker.n_Run (System.IntPtr jnienv, System.IntPtr native__this) [0x00009] 在(包装动态方法)System.Object.6(intptr,intptr) --- 内部异常堆栈跟踪结束 ---

我从分析器中看到的是大量线程。 (我不明白是否应该使用 runOnUiThread 一遍又一遍地调用同一个线程,或者是否每次都调用一个新线程)。 Ater 大量成功调用下一个 RunOnUiThread 无法在 editText 中设置文本,我的应用程序进入 Show(exc),它也使用 RunOnUiThread 显示异常消息的 Toast。 RunOnUiThread 的第二次调用也会导致应用程序完全崩溃

    public void Write_returned_BC(EditText v)
            {
                try
                {
                    if (Scanned_Data != null) //Scanned_Data is my Barcode
                    {
                        RunOnUiThread(() => v.SetText(Scanned_Data,TextView.BufferType.Normal));
                    }
                }
                catch (Exception exc)
                {
                    Show(exc);
                }
            }

【问题讨论】:

    标签: c# xamarin.android


    【解决方案1】:

    好吧,我建议你这样做:

    如果您有一个 RunOnMainThread 方法,请在您的 BaseActivity 中添加,或者将其添加到您的 MainActivity:

     public bool IsMainThread => Build.VERSION.SdkInt >= BuildVersionCodes.M
    ? Looper.MainLooper.IsCurrentThread
    : Looper.MyLooper() == Looper.MainLooper;
    
    public void RunOnMainThread(Action action)
    {
      if (IsMainThread) action();
      else RunOnUiThread(action);
    } 
    

    上述方法的作用是仅在您不在 MainThread 上时才调用 RunOnUiThread 方法,这样可以确保您不会创建额外的线程。

    其次,我建议您使用 C# 提供的属性,而不是使用 SetText 方法,即 Text 属性。

     RunOnMainThread(() => v.Text=Scanned_Data);
    

    此外,在处理字符串时,对空值检查最好的做法是使用 string.IsNullOrWhitespace() 方法,该方法将直接返回一个布尔值,因此 if 会变成类似的东西。

    if(string.IsNullOrWhitespace(Scanned_Data))
    

    【讨论】:

    • 您好,首先感谢您的回复!是的,我确实有一个 BaseActivity,所以我会尝试你的解决方案。我尝试使用 SetText 方法,因为在这里的另一个问题上,我发现使用此方法而不是 .Text 属性解决了可能与此异常相关的问题。在将字符串保存到 Scanned_Data 之前,我已经对字符串进行了空值检查,但也感谢第二个提示
    • 也许你应该看看上面的解决方案我从来没有遇到过任何问题。
    • 我按照上面的说明进行操作(除了 .Text 部分,我会尽力尝试但我没有任何改进。有趣的是,作为测试,我手动编写了对所有方法的调用扫描仪(包括通常崩溃的代码)并在 700 个不同的条形码上复制此代码 700 次,运行代码并没有收到任何问题。这东西变得越来越复杂
    • 我尝试了 .Text 解决方案,但没有任何结果。我还尝试在关闭表单bu的异常捕获中午餐onBackPressed,在关闭表单后返回我的应用程序的主菜单,当我尝试重新打开表单时,同样的异常会再次弹出崩溃我的应用程序。
    【解决方案2】:

    我设法解决了我的问题。 该问题看起来与扫描仪实现有关。 我使用 Zebra 提供的示例作为我工作的基础,从头开始重做扫描仪管理

    感谢大家的帮助

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-08-13
      • 2011-08-16
      • 1970-01-01
      • 1970-01-01
      • 2017-05-16
      • 2010-11-06
      • 1970-01-01
      相关资源
      最近更新 更多