java.lang.RuntimeException:无法从宗地读取输入通道文件描述符

2022-08-31 15:58:17

我正在使用 crashlytics 来跟踪我的应用的崩溃。有一个错误很难弄清楚。来自 crashlytics 的堆栈跟踪如下所示:

java.lang.RuntimeException: Could not read input channel file descriptors from parcel.
       at android.view.InputChannel.nativeReadFromParcel(InputChannel.java)
       at android.view.InputChannel.readFromParcel(InputChannel.java:148)
       at android.view.InputChannel$1.createFromParcel(InputChannel.java:39)
       at android.view.InputChannel$1.createFromParcel(InputChannel.java:36)
       at com.android.internal.view.InputBindResult.<init>(InputBindResult.java:62)
       at com.android.internal.view.InputBindResult$1.createFromParcel(InputBindResult.java:102)
       at com.android.internal.view.InputBindResult$1.createFromParcel(InputBindResult.java:99)
       at com.android.internal.view.IInputMethodManager$Stub$Proxy.windowGainedFocus(IInputMethodManager.java:851)
       at android.view.inputmethod.InputMethodManager.startInputInner(InputMethodManager.java:1292)
       at android.view.inputmethod.InputMethodManager.onWindowFocus(InputMethodManager.java:1518)
       at android.view.ViewRootImpl$ViewRootHandler.handleMessage(ViewRootImpl.java:3550)
       at android.os.Handler.dispatchMessage(Handler.java:102)
       at android.os.Looper.loop(Looper.java:157)
       at android.app.ActivityThread.main(ActivityThread.java:5293)
       at java.lang.reflect.Method.invokeNative(Method.java)
       at java.lang.reflect.Method.invoke(Method.java:515)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
       at dalvik.system.NativeStart.main(NativeStart.java)

我知道这里有一个类似的问题。但也有一点不同。正如crashlytics的统计数据一样,崩溃主要发生在三星Android手机中。

我是Android的新手,不知道为什么会发生崩溃以及如何修复这种崩溃。

任何建议将不胜感激。


答案 1

认为这是一个非常广泛的领域,可能有很多情况可以触发此系统级异常。但是,也许这个例子可以在特定项目中修复它,可以帮助某人。

我在三星手机上遇到了类似的异常:
“无法从包裹中读取输入通道文件描述符”

java.lang.RuntimeException: Could not read input channel file descriptors from parcel.
        at android.view.InputChannel.nativeReadFromParcel(Native Method)
        at android.view.InputChannel.readFromParcel(InputChannel.java:148)
        at android.view.IWindowSession$Stub$Proxy.addToDisplay(IWindowSession.java:690)
        at android.view.ViewRootImpl.setView(ViewRootImpl.java:525)
        at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:269)
        at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69)
        at android.widget.Toast$TN.handleShow(Toast.java:402)
        at android.widget.Toast$TN$1.run(Toast.java:310)
        at android.os.Handler.handleCallback(Handler.java:730)
        at android.os.Handler.dispatchMessage(Handler.java:92)
        at android.os.Looper.loop(Looper.java:137)
        at android.app.ActivityThread.main(ActivityThread.java:5103)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:525)
        at       com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
        at dalvik.system.NativeStart.main(Native Method)

它发生在一个大型的旧项目中,我得到了维护,这个浮动的错误仅在几个小时后才发生。我花了相当多的时间在它上面,还阅读了一些关于SO的相关答案,除了它是Android的系统级错误之外,没有任何线索,并且应该有一些额外的数据或对象或内存中大对象的重复等:

https://code.google.com/p/android/issues/detail?id=32470

我能想到的最后一件事是SoundPool。它在项目中没有被大量使用 - 不时播放不超过10种不同的声音。
但这是根本原因!有时,SoundPool 会出现浮动异常“无法加载样本(空值)”。它有助于意识到SoundPool的使用方式是错误的:

public void play(int rscId) {
...
    final int soundId = soundPool.load(mContext, rscId, 1);
    ...
    soundPool.play(soundId, volume, volume, 5, 0, 1f);

因此,每次调用播放声音方法的应用程序时,都会生成新的ID并重新加载声音资源!经过一段时间后,一些不相关的异常开始发生,直到应用程序崩溃并出现“无法从包裹中读取输入通道文件描述符”异常。
有趣的是,其中一个不相关的异常是:
“异常处理在无法打开数据库文件(代码14)”

ExceptionHandled in unable to open database file (code 14)
android.database.sqlite.SQLiteCantOpenDatabaseException: 
unable to open database file (code 14)
at android.database.sqlite.SQLiteConnection.nativeExecuteForCursorWindow
(Native Method)
at android.database.sqlite.SQLiteConnection.executeForCursorWindow
(SQLiteConnection.java:845)

当然,它与数据库和吐司/包裹无关。针对该特定情况的修复非常简单:只需按照Android文档中的建议预加载所有声音即可:

http://developer.android.com/reference/android/media/SoundPool.html

“加载逻辑循环访问调用相应的声音列表。这通常应该在流程的早期完成,以便在需要播放之前有时间将音频解压缩为原始PCM格式。
加载声音并开始播放后,应用程序可以通过调用来触发声音。SoundPool.load() functionSoundPool.play()

所以我搬家了,例外:
已经走了,就像例外一样。soundPool.load() out from play() method"Could not read input channel file descriptors from parcel""unable to open database file (code 14)"

public void play(int soundId) {
    ...
    soundPool.play(soundId, volume, volume, 5, 0, 1f);

SoundPool.release(); soundPool = null 在不再需要时也应该调用。也许它也会对此类异常产生影响,请参阅此处的详细信息

无法从包裹中读取输入通道文件描述符

很可能这不是原始问题的确切情况,但希望它能提供一些信息来进一步挖掘。即,查找一些其他异常、吞咽异常或错误的文件/数据处理。


答案 2

我一直在寻找答案,例如在这个例外中面临的其他人。

正如我所看到的,这种崩溃也可以由不例外的触发,或者与:TextViewEditTextInputMethodManager

java.lang.RuntimeException: Could not read input channel file descriptors from parcel.
    at android.view.InputChannel.nativeReadFromParcel(Native Method)
    at android.view.InputChannel.readFromParcel(InputChannel.java:148)
    at android.view.InputChannel$1.createFromParcel(InputChannel.java:39)
    at android.view.InputChannel$1.createFromParcel(InputChannel.java:36)
    at com.android.internal.view.InputBindResult.<init>(InputBindResult.java:68)
    at com.android.internal.view.InputBindResult$1.createFromParcel(InputBindResult.java:112)
    at com.android.internal.view.InputBindResult$1.createFromParcel(InputBindResult.java:109)
    at com.android.internal.view.IInputMethodManager$Stub$Proxy.startInput(IInputMethodManager.java:697)
    at android.view.inputmethod.InputMethodManager.startInputInner(InputMethodManager.java:1407)
    at android.view.inputmethod.InputMethodManager.checkFocus(InputMethodManager.java:1518)
    at android.view.inputmethod.InputMethodManager.restartInput(InputMethodManager.java:1286)
    at android.widget.TextView.setText(TextView.java:4718)
    at android.widget.TextView.setText(TextView.java:4656)
    at android.widget.TextView.append(TextView.java:4330)
    at android.widget.TextView.append(TextView.java:4320)
    ...

追加文本时,它会将文本设置为 ,然后启动 。但是此时,在此过程中出现问题,导致无法从包裹中创建哪个读取错误。TextViewEditableInputMethodManagerInputMethodInputBindResult

在这种情况下,解决方法非常简单:不要直接在textview上调用add,而是使用或构建文本并调用!StringBuilderSpannableStringBuilderTextView.setText(text)


推荐