为什么键盘滑动会导致我的应用崩溃?

9
如果我在我的Moto Droid A855上物理滑动键盘,它会导致我的测试应用程序崩溃,并显示下面的堆栈跟踪。我不明白为什么?
另外,如果我在键盘弹出状态下启动我的应用程序,我的应用程序会立即崩溃。
该应用程序包括一个活动,其中包含一个viewflipper作为主要视图布局。viewflipper包含两个linearlayouts...
堆栈跟踪:
06-10 21:10:17.652 E/AndroidRuntime( 3785): Uncaught handler: thread main exiting due to uncaught exception
06-10 21:10:17.668 E/AndroidRuntime( 3785): java.lang.IllegalArgumentException: Receiver not registered: android.widget.ViewFlipper$1@447af0b8
06-10 21:10:17.668 E/AndroidRuntime( 3785):     at android.app.ActivityThread$PackageInfo.forgetReceiverDispatcher(ActivityThread.java:667)
06-10 21:10:17.668 E/AndroidRuntime( 3785):     at android.app.ApplicationContext.unregisterReceiver(ApplicationContext.java:747)
06-10 21:10:17.668 E/AndroidRuntime( 3785):     at android.content.ContextWrapper.unregisterReceiver(ContextWrapper.java:321)
06-10 21:10:17.668 E/AndroidRuntime( 3785):     at android.widget.ViewFlipper.onDetachedFromWindow(ViewFlipper.java:104)
06-10 21:10:17.668 E/AndroidRuntime( 3785):     at android.view.View.dispatchDetachedFromWindow(View.java:5835)
06-10 21:10:17.668 E/AndroidRuntime( 3785):     at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:1076)
06-10 21:10:17.668 E/AndroidRuntime( 3785):     at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:1074)
06-10 21:10:17.668 E/AndroidRuntime( 3785):     at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:1074)
06-10 21:10:17.668 E/AndroidRuntime( 3785):     at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:1074)
06-10 21:10:17.668 E/AndroidRuntime( 3785):     at android.view.ViewRoot.dispatchDetachedFromWindow(ViewRoot.java:1570)
06-10 21:10:17.668 E/AndroidRuntime( 3785):     at android.view.ViewRoot.doDie(ViewRoot.java:2556)
06-10 21:10:17.668 E/AndroidRuntime( 3785):     at android.view.ViewRoot.die(ViewRoot.java:2526)
06-10 21:10:17.668 E/AndroidRuntime( 3785):     at android.view.WindowManagerImpl.removeViewImmediate(WindowManagerImpl.java:218)
06-10 21:10:17.668 E/AndroidRuntime( 3785):     at android.view.Window$LocalWindowManager.removeViewImmediate(Window.java:436)
06-10 21:10:17.668 E/AndroidRuntime( 3785):     at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:3498)
06-10 21:10:17.668 E/AndroidRuntime( 3785):     at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3599)
06-10 21:10:17.668 E/AndroidRuntime( 3785):     at android.app.ActivityThread.access$2300(ActivityThread.java:119)
06-10 21:10:17.668 E/AndroidRuntime( 3785):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1867)
06-10 21:10:17.668 E/AndroidRuntime( 3785):     at android.os.Handler.dispatchMessage(Handler.java:99)
06-10 21:10:17.668 E/AndroidRuntime( 3785):     at android.os.Looper.loop(Looper.java:123)
06-10 21:10:17.668 E/AndroidRuntime( 3785):     at android.app.ActivityThread.main(ActivityThread.java:4363)
06-10 21:10:17.668 E/AndroidRuntime( 3785):     at java.lang.reflect.Method.invokeNative(Native Method)
06-10 21:10:17.668 E/AndroidRuntime( 3785):     at java.lang.reflect.Method.invoke(Method.java:521)
06-10 21:10:17.668 E/AndroidRuntime( 3785):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
06-10 21:10:17.668 E/AndroidRuntime( 3785):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
06-10 21:10:17.668 E/AndroidRuntime( 3785):     at dalvik.system.NativeStart.main(Native Method)
06-10 21:10:17.684 I/Process ( 1017): Sending signal. PID: 3785 SIG: 3

编辑:添加了XML布局和主要活动相关片段。

整个XML布局文件

<?xml version="1.0" encoding="utf-8"?>


<ViewFlipper
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/vFlipper"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">

                <!--  Linear Layout 1: messages and overview.  -->
                <LinearLayout
                    android:orientation="vertical"
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent"
                    >

                <TableRow android:id="@+id/TableRow01" android:layout_width="fill_parent" android:layout_height="wrap_content">
                <TextView
                        android:text="Connection info"
                        android:id="@+id/tvCon1"
                        android:layout_width="fill_parent"
                        android:layout_height="wrap_content"
                        android:background="#F0F0F0"
                        android:textColor="#FF0000"
                        />
                </TableRow>


                <ScrollView
                        android:id="@+id/ScrollView01"
                        android:layout_width="fill_parent"
                        android:layout_height="fill_parent">

                                <TextView  
                                        android:id="@+id/tvMessages"
                                    android:layout_width="fill_parent"
                                    android:layout_height="fill_parent"
                                    android:text=""
                                    />

                </ScrollView>

        </LinearLayout>


        <!--  Linear Layout 2: settings -->
        <LinearLayout
                    android:orientation="vertical"
                    android:layout_width="fill_parent"
                    android:layout_height="fill_parent"
                    >


                <TableRow
                        android:id="@+id/TableRow03"
                        android:layout_width="fill_parent"
                        android:layout_height="wrap_content">

                                <TextView
                                android:text="hello world"
                                android:id="@+id/asdfasdf2"
                                android:layout_width="fill_parent"
                                android:layout_height="wrap_content"
                                />
                </TableRow>                

        </LinearLayout>

</ViewFlipper>

主活动中的代码片段:

/**
 * Attempt (not currently working) to work around this bug: http://code.google.com/p/android/issues/detail?id=6191
 * TODO: make it work.
 */
@Override
public void onDetachedFromWindow() {
        Log.d("Dash","OnDetachedFromWindow()");

        try {
        super.onDetachedFromWindow();
    }
    catch (Exception e) {
        ViewFlipper v = (ViewFlipper)findViewById(R.id.vFlipper);
        if (v != null) {
                Log.d("Dash","De-Bug hit. e=" + e.getMessage());
                v.stopFlipping();
        }
    }
}
4个回答

21
为了解决这个问题,您必须:
  • 定义一个名为MyViewFlipper的新类,它覆盖了ViewFlipper(见下文)
  • 在以前引用ViewFlipper的任何地方引用该新类
  • 按照下面所示定义您的类和布局:

名为MyViewFlipper的新类。包含以下内容:

package com.gtosoft.dash; // change this to match your own app. 

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.ViewFlipper;

public class MyViewFlipper extends ViewFlipper {

    public MyViewFlipper(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onDetachedFromWindow() {
        try{
            super.onDetachedFromWindow();
        }catch(Exception e) {
            Log.d("MyViewFlipper","Stopped a viewflipper crash");
            stopFlipping();
        }
    }
}

现在要使用这个“修复”版的 ViewFlipper,您需要在 XML 布局中引用它。由于它基本上是一个“自定义视图”,因此您必须完全限定 MyViewFlipper 的包路径,如下所示:

<com.gtosoft.dash.MyViewFlipper
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/vFlipper"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">

    (insert all the other old layout code here)

</com.gtosoft.dash.MyViewFlipper>

现在应用程序不再在键盘滑动事件时崩溃,或者如果应用程序已经启动并且幻灯片已经弹出也不会崩溃。在日志中查找此内容:

06-11 20:08:15.811 D/MyViewFlipper( 6106): Stopped a viewflipper crash

来源: http://code.google.com/p/android/issues/detail?id=6191


我认为我犯了一个小错 - <ViewFlipper 需要是 <com.gtosoft.dash.MyViewFlipper。 - Brad Hein
你缺少了一行重要的代码:在catch块中调用stopFlipping(),这样它就会调用updateRunning()。 - Catalin Morosan

5

如果您没有提供代码的某些部分,那么帮助您会变得非常困难...无论如何,这个错误并不新鲜,有一些解决方法(我猜是一些bug)...尝试这样做:

@Override
protected void onDetachedFromWindow() {
    try {
        super.onDetachedFromWindow();
    }
    catch (IllegalArgumentException e) {
        stopFlipping();
    }
}

这是为了覆盖onDetachedFromWindow方法,希望对您有用。


我昨晚尝试实施这个修复,但没有任何影响。首先,Eclipse不喜欢“protected”,所以我不得不将其改为public。此外,stopFlipping需要使用findviewById进行限定等。我在新的代码块中放置了调试消息,并发现它根本没有触发。 - Brad Hein
@Brad,你能分享你的代码吗?这样我们就能看看你是否出错了。 - Cristian
找到了问题:根据http://code.google.com/p/android/issues/detail?id=6191的建议,我们需要创建一个自己的viewflipper包装器,通过定义继承ViewFlipper的新类来实现。将新类命名为MyViewFlipper。在任何需要使用viewflipper的地方,如布局XML中,使用包含链接中指定的修复代码的MyViewFlipper类即可。 - Brad Hein

2

我知道这个问题已经在两年前被问过了,但是自那时以来,一个非常简单的解决方案已经被实施。只需在清单文件中的每个Activity调用中添加android:configChanges =“orientation | keyboard | keyboardHidden”即可。


0

是的,我之前没有看到过这个 bug.. 不过我在我的清单文件中有这个

 <activity
        android:name=".MainActivity"
        android:configChanges="keyboardHidden|navigation"
        android:label="@string/app_name"
        android:launchMode="singleTop" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>

</activity>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接