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

时间:2014-08-05 06:33:35

标签: java android

我正在使用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)

我知道有一个类似的问题here。但有一点不同。而作为来自crashlytics的统计数据,崩溃主要发生在SAMSUNG安卓手机上。

我是Android的新手,不知道崩溃发生的原因以及如何解决这种崩溃问题。

任何建议都会非常感激。

6 个答案:

答案 0 :(得分:34)

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

我遇到了类似的例外:
三星手机上的 "Could not read input channel file descriptors from parcel"

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)

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

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

我能想到的最后一件事是SoundPool。它在项目中并没有被大量使用 - 不时播放的声音不超过10种。
但这是根本原因!有时,SoundPool "unable to load sample (null)" 会出现浮动异常。它有助于意识到SoundPool以错误的方式使用:

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

每次应用程序调用播放声音方法时都会生成新的id并重新加载声音资源!在一段时间后,一些非相关的异常开始发生,直到应用程序因 "Could not read input channel file descriptors from parcel" 异常而崩溃。
有趣的是,其中一个不相关的例外是: "ExceptionHandled in unable to open database file (code 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)

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

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

“加载逻辑遍历调用适当SoundPool.load() function的声音列表。这通常应该在过程的早期完成,以便有时间将音频解压缩为原始PCM格式,然后再播放。<登记/> 加载声音并开始播放后,应用程序可以通过调用SoundPool.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 也应该在不再需要时调用。也许它也会对这些异常产生影响,请参见此处的详细信息

Could not read input channel file descriptors from parcel

最有可能的不是原始问题的确切情况,但希望它能提供一些进一步挖掘的信息。即寻找一些额外的例外,吞下异常或错误的文件/数据处理。

答案 1 :(得分:8)

我正在寻找答案很长一段时间,例如其他人面临这个例外。

正如我所看到的,此崩溃也可以由与TextView一起使用的例外EditTextInputMethodManager触发:

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)
    ...

TextView附加文字时,它会将文字发送到Editable,然后启动InputMethodManager。但此时InputMethod进程出现问题,导致无法创建InputBindResult从包裹中读取错误。

在这种情况下,解决方法非常简单:不要直接在textview上调用append,使用StringBuilderSpannableStringBuilder来构建文本并改为调用TextView.setText(text)

答案 2 :(得分:2)

以前的用户评论说,这可能是一个难以追踪的错误。我通过在TextView循环while语句中构建自定义警报对话框(包含多个if对象)来实现此目的。应用程序在显示对话框之前崩溃。

答案 3 :(得分:0)

我最近遇到了这个问题。

java.lang.RuntimeException: Could not read input channel file descr
iptors from parcel.

我在日志中搜索以下信息:

  

01-01 09:07:52.164 5162 6777 W zygote64:ashmem_create_region失败   for&#39; indirect ref table&#39;:打开的文件太多

问题是我反复创建了HandlerThread,但是没有执行它的quit()方法,最后导致fd泄露。

答案 4 :(得分:0)

ViewRootImpl$ViewRootHandler 表示您有 view.postview.postDelay。 在 post 方法中可能是 requestFocusKeyboard

答案 5 :(得分:-1)

我收到此错误是因为在Activity启动时运行了太多查询(对于列表视图中的每一行)。因为我在执行查询时尝试重新打开相同的活动。

修复:我只为列表视图运行了一个查询。