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

cha*_*yWu 55 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)
Run Code Online (Sandbox Code Playgroud)

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

我是Android的新手,不知道为什么崩溃发生以及如何解决这种崩溃.

任何建议将不胜感激.

And*_*ine 36

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

我遇到了类似的例外:
"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)
Run Code Online (Sandbox Code Playgroud)

It happened in a big old project which I got for maintenance and this floating bug occurred only after several hours. I spent quite some time on it and also read some related answers on SO regarding it and had no clue except it's a system level bug of Android, and there should be some extra data or duplicates of objects or big objects in memory etc:

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

The last thing I could think about was SoundPool. It's not used a lot in the project - there are not more than 10 different sounds played from time to time.
But it was the root cause! Sometimes there were floating exceptions from SoundPool "unable to load sample (null)". And it helped to realize that SoundPool was used in a wrong way:

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

So new id was generated and sound resource was reloaded each time application called play sound method! And after certain amount of time some non related exceptions started to occur until application crashed with the "Could not read input channel file descriptors from parcel" exception.
It's interesting that one of those non related exceptions was:
"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)
Run Code Online (Sandbox Code Playgroud)

And of course it has nothing to do neither with database nor with toasts/parcels. The fix for that particular situation was very easy: just preload all sounds as it's suggested in Android documentation:

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

"The loading logic iterates through the list of sounds calling the appropriate SoundPool.load() function. This should typically be done early in the process to allow time for decompressing the audio to raw PCM format before they are needed for playback.
Once the sounds are loaded and play has started, the application can trigger sounds by calling SoundPool.play()."

So I moved soundPool.load() out from play() method and the exception :
"Could not read input channel file descriptors from parcel" has gone as well as the exception "unable to open database file (code 14)".

public void play(int soundId) {
    ...
    soundPool.play(soundId, volume, volume, 5, 0, 1f);
Run Code Online (Sandbox Code Playgroud)

And soundPool.release(); soundPool = null should be called as well when it's not needed anymore. And maybe it also can have an effect on such exceptions, see details here

Could not read input channel file descriptors from parcel

Most probably it's not the exact situation for the original question but hope it can give some information to dig further. I.e. looking for some additional exceptions, swallowed exceptions, or wrong files/data handling.


小智 8

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

正如我所看到的,此崩溃也可以由例外触发TextViewEditText与以下内容一起使用InputMethodManager:

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)
    ...
Run Code Online (Sandbox Code Playgroud)

TextView追加文本,它会使文本Editable,并开始InputMethodManager.但此时,InputMethod过程中出现问题,导致无法InputBindResult从包裹中创建哪个读数错误.

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

  • 我不使用append,我直接在onFocusChanged里面为同一个TextView追加setText,crashlytics中报了crash,虽然很罕见但是还是会发生 (2认同)