【问题标题】:NullPointerException on WebView (WebView.requestFocus())WebView 上的 NullPointerException (WebView.requestFocus())
【发布时间】:2011-05-26 19:14:04
【问题描述】:

我有一个问题:

在我的 Android 应用中有一个包含 WebView 的活动。此WebView 包含播放的 Flash 内容。当我从这个应用程序切换到我的主屏幕时,Flash 内容在后台运行流畅。当我切换到主屏幕然后关闭屏幕时,Flash 内容也在运行。但是当我在应用程序中关闭屏幕时,WebView 会在文本末尾抛出一个NullPointerException,如下所示。我真的不知道如何解决这个问题。我希望有人可以帮助我。

编辑:我为Android 2.2 开发。经过一番测试,我发现了一些特别的东西。当我在运行应用程序时关闭屏幕时,我得到了提到的异常,但是当我及时重新打开屏幕时,我得到“仅”以下异常。我知道这没什么特别的,而且是众所周知的,但也许它会有所帮助。

05-27 07:46:10.067: ERROR/AndroidRuntime(8064): FATAL EXCEPTION: main
05-27 07:46:10.067: ERROR/AndroidRuntime(8064): java.lang.NullPointerException
05-27 07:46:10.067: ERROR/AndroidRuntime(8064):     at android.webkit.WebView.requestFocus(WebView.java:6737)
05-27 07:46:10.067: ERROR/AndroidRuntime(8064):     at android.view.ViewGroup.onRequestFocusInDescendants(ViewGroup.java:1085)
05-27 07:46:10.067: ERROR/AndroidRuntime(8064):     at android.view.ViewGroup.requestFocus(ViewGroup.java:1041)
05-27 07:46:10.067: ERROR/AndroidRuntime(8064):     at android.view.ViewGroup.onRequestFocusInDescendants(ViewGroup.java:1085)
05-27 07:46:10.067: ERROR/AndroidRuntime(8064):     at android.view.ViewGroup.requestFocus(ViewGroup.java:1041)
05-27 07:46:10.067: ERROR/AndroidRuntime(8064):     at android.view.ViewGroup.onRequestFocusInDescendants(ViewGroup.java:1085)
05-27 07:46:10.067: ERROR/AndroidRuntime(8064):     at android.view.ViewGroup.requestFocus(ViewGroup.java:1044)
05-27 07:46:10.067: ERROR/AndroidRuntime(8064):     at android.view.View.requestFocus(View.java:3671)
05-27 07:46:10.067: ERROR/AndroidRuntime(8064):     at android.view.ViewRoot.performTraversals(ViewRoot.java:1224)
05-27 07:46:10.067: ERROR/AndroidRuntime(8064):     at android.view.ViewRoot.handleMessage(ViewRoot.java:1870)
05-27 07:46:10.067: ERROR/AndroidRuntime(8064):     at android.os.Handler.dispatchMessage(Handler.java:99)
05-27 07:46:10.067: ERROR/AndroidRuntime(8064):     at android.os.Looper.loop(Looper.java:130)
05-27 07:46:10.067: ERROR/AndroidRuntime(8064):     at android.app.ActivityThread.main(ActivityThread.java:3694)
05-27 07:46:10.067: ERROR/AndroidRuntime(8064):     at java.lang.reflect.Method.invokeNative(Native Method)
05-27 07:46:10.067: ERROR/AndroidRuntime(8064):     at java.lang.reflect.Method.invoke(Method.java:507)
05-27 07:46:10.067: ERROR/AndroidRuntime(8064):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841)
05-27 07:46:10.067: ERROR/AndroidRuntime(8064):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599)
05-27 07:46:10.067: ERROR/AndroidRuntime(8064):     at dalvik.system.NativeStart.main(Native Method)

这里是创建WebView的方法:

protected void onCreate(Bundle savedInstanceState){
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);

    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
    setContentView(R.layout.externalplayer);

    final Intent j = this.getIntent();

    webview = (WebView)findViewById(R.id.webview);
    webview.getSettings().setJavaScriptEnabled(true);
    webview.getSettings().setAllowFileAccess(true);
    webview.getSettings().setPluginsEnabled(true);
    webview.freeMemory();
    webview.setPictureListener(new picListener());

    webview.setWebViewClient(new WebViewClient(){
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url){
            return true;
        }   
    });

    if(Controller.unbuggedStart == true){
        Controller.unbuggedStart = false;
        webview.destroy();
    } else{
        Controller.unbuggedStart = true;
        d = ProgressDialog.show(externalPlayer.this, "Loading...", "Wait a moment...");
        webview.loadUrl(j.getCharSequenceExtra("link").toString());
    }
}


05-26 20:13:29.825: ERROR/AndroidRuntime(4754): FATAL EXCEPTION: main
05-26 20:13:29.825: ERROR/AndroidRuntime(4754): java.lang.RuntimeException: Unable to start activity ComponentInfo{xxxApp}: java.lang.NullPointerException
05-26 20:13:29.825: ERROR/AndroidRuntime(4754):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1655)
05-26 20:13:29.825: ERROR/AndroidRuntime(4754):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1671)
05-26 20:13:29.825: ERROR/AndroidRuntime(4754):     at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:2840)
05-26 20:13:29.825: ERROR/AndroidRuntime(4754):     at android.app.ActivityThread.access$1600(ActivityThread.java:117)
05-26 20:13:29.825: ERROR/AndroidRuntime(4754):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:935)
05-26 20:13:29.825: ERROR/AndroidRuntime(4754):     at android.os.Handler.dispatchMessage(Handler.java:99)
05-26 20:13:29.825: ERROR/AndroidRuntime(4754):     at android.os.Looper.loop(Looper.java:130)
05-26 20:13:29.825: ERROR/AndroidRuntime(4754):     at android.app.ActivityThread.main(ActivityThread.java:3694)
05-26 20:13:29.825: ERROR/AndroidRuntime(4754):     at java.lang.reflect.Method.invokeNative(Native Method)
05-26 20:13:29.825: ERROR/AndroidRuntime(4754):     at java.lang.reflect.Method.invoke(Method.java:507)
05-26 20:13:29.825: ERROR/AndroidRuntime(4754):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841)
05-26 20:13:29.825: ERROR/AndroidRuntime(4754):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599)
05-26 20:13:29.825: ERROR/AndroidRuntime(4754):     at dalvik.system.NativeStart.main(Native Method)
05-26 20:13:29.825: ERROR/AndroidRuntime(4754): Caused by: java.lang.NullPointerException
05-26 20:13:29.825: ERROR/AndroidRuntime(4754):     at android.webkit.WebView.requestFocus(WebView.java:6737)
05-26 20:13:29.825: ERROR/AndroidRuntime(4754):     at android.view.View.requestFocus(View.java:3671)
05-26 20:13:29.825: ERROR/AndroidRuntime(4754):     at android.view.View.requestFocus(View.java:3649)
05-26 20:13:29.825: ERROR/AndroidRuntime(4754):     at com.android.internal.policy.impl.PhoneWindow.restoreHierarchyState(PhoneWindow.java:1497)
05-26 20:13:29.825: ERROR/AndroidRuntime(4754):     at android.app.Activity.onRestoreInstanceState(Activity.java:844)
05-26 20:13:29.825: ERROR/AndroidRuntime(4754):     at android.app.Activity.performRestoreInstanceState(Activity.java:816)
05-26 20:13:29.825: ERROR/AndroidRuntime(4754):     at android.app.Instrumentation.callActivityOnRestoreInstanceState(Instrumentation.java:1096)
05-26 20:13:29.825: ERROR/AndroidRuntime(4754):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1633)
05-26 20:13:29.825: ERROR/AndroidRuntime(4754):     ... 12 more

【问题讨论】:

  • 你可以在你的webView上获取和加载数据的时候放上这部分代码吗?
  • 谢谢你,我已经更新了第一篇文章。

标签: android exception webview


【解决方案1】:

好的,我解决了这个问题。

解决方案的线索是屏幕方向。就像你在第一篇文章的代码中看到的那样,我在 onCreate() 方法中调用了:setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

此调用的结果是,由于方向更改,该活动被调用了两次。这就是我使用的原因:

if(Controller.unbuggedStart == true){
        Controller.unbuggedStart = false;
        webview.destroy();
    } else{
        Controller.unbuggedStart = true;
        d = ProgressDialog.show(externalPlayer.this, "Loading...", "Wait a moment...");
        webview.loadUrl(j.getCharSequenceExtra("link").toString());
    }

此代码可防止WebView 被启动两次。您可以看到我销毁了两个创建的 WebView 之一。现在,当我关闭屏幕时,操作系统想要调用被破坏的WebView,从而导致NullPointerException

我对我的 onCreate 方法的机制进行了思考并对其进行了更改。现在,方向已在清单中描述:

android:screenOrientation="landscape"

修改后,问题并没有真正解决。当我关闭屏幕时,操作系统再次启动了带有WebView 的活动,因为当我关闭屏幕时方向从横向切换到纵向。我在清单中添加了以下内容:

android:configChanges="keyboardHidden|orientation"

现在一切正常。

【讨论】:

    【解决方案2】:

    在不知道您正在运行的 Android 版本的情况下,我查看了 WebView 的 head revision 中 requestFocus() 的实现,对于 NPE 来说似乎没有那么多机会。一种可能性是,当屏幕关闭时,WebView.destroy() 方法被调用(将 mWebViewCore 设置为 null),即使 Activity 仍然持有它并在状态为时试图将焦点放在它身上已恢复。

    您可以尝试在您的 Activity 中覆盖 onRestoreInstanceState 并查看 WebView 在该点是否仍然具有一致的状态。同样,查看头部修订版,如果您要调用“getSettings()”,由于同样的原因,这将引发 NPE,您可以相对确定这是问题所在。

    【讨论】:

    • 我已经尝试过您的建议,但遗憾的是它并没有改变什么。我用一些新的新鲜信息编辑了第一篇文章。 :)
    • 正如您在我添加的第一篇文章的源代码中看到的那样,我有一些代码可以防止 WebView 多次启动。我不知道为什么,但是当我调用活动 externalPlayer 时,它将被调用两次,我没有找到另一种避免这种情况的方法。当我推荐这段代码(unbuggedStart)然后关闭屏幕时,应用程序不会崩溃并且主要问题已修复,但我必须处理 WebView 的双启动,我不知道如何。嗯
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-04
    • 1970-01-01
    • 2011-06-30
    • 2013-04-21
    • 2014-03-18
    • 2019-10-24
    相关资源
    最近更新 更多