我正在使用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的新手,不知道崩溃发生的原因以及如何解决这种崩溃问题。
任何建议都会非常感激。
答案 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
一起使用的例外EditText
或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)
...
当TextView
附加文字时,它会将文字发送到Editable
,然后启动InputMethodManager
。但此时InputMethod
进程出现问题,导致无法创建InputBindResult
从包裹中读取错误。
在这种情况下,解决方法非常简单:不要直接在textview上调用append,使用StringBuilder
或SpannableStringBuilder
来构建文本并改为调用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.post
或 view.postDelay
。
在 post 方法中可能是 requestFocus
或 Keyboard
答案 5 :(得分:-1)
我收到此错误是因为在Activity启动时运行了太多查询(对于列表视图中的每一行)。因为我在执行查询时尝试重新打开相同的活动。
修复:我只为列表视图运行了一个查询。