Исключение NullPointerException в WebView (WebView.requestFocus())

#android #exception #webview

#Android #исключение #webview

Вопрос:

У меня вопрос:

В моем приложении для 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
  

Комментарии:

1. можете ли вы поместить часть кода, когда вы получаете и загружаете данные в свой 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 повторный запуск. Вы можете видеть, что я уничтожаю один из двух созданных веб-просмотров. Теперь, когда я выключил экран, ОС хочет вызвать destroyed, WebView что приводит к NullPointerException .

Я переосмыслил механизмы моего метода onCreate и изменил его. Теперь ориентация описана в манифесте:

 android:screenOrientation="landscape"
  

После этого изменения проблема на самом деле не была решена. Когда я выключил экран, ОС снова запустила действие с WebView в нем, потому что ориентация переключилась с альбомной на книжную, когда я выключил экран. Я добавил в манифест следующее:

 android:configChanges="keyboardHidden|orientation"
  

и теперь все работает идеально.

Ответ №2:

Не зная версию Android, на которой вы работаете, я взглянул на реализацию requestFocus() в головной редакции WebView, и, похоже, там не так много возможностей для NPE. Одна из возможностей заключается в том, что при выключении экрана вызывается метод WebView.destroy() (установка mWebViewCore в значение null), даже если действие все еще сохраняется за ним и пытается сфокусироваться на нем, когда состояние восстанавливается.

Вы могли бы попробовать переопределить onRestoreInstanceState в вашем Activity и посмотреть, по-прежнему ли WebView имеет согласованное состояние на данный момент. Опять же, глядя на редакцию head, если бы вы вызвали «getSettings()», это вызвало бы NPE по той же причине, и вы могли бы быть относительно уверены, что это проблема.

Комментарии:

1. Я попробовал ваш совет, но, к сожалению, это ничего не меняет. Я отредактировал первое сообщение, добавив в него некоторую новую информацию. 🙂

2. Как вы можете видеть в исходном коде, который я добавил в первом сообщении, у меня есть некоторый код, предотвращающий многократный запуск WebView. Я не знаю почему, но когда я вызываю activity externalPlayer, оно будет вызвано дважды, и я не нашел другого способа избежать этого. Когда я отправляю этот код (unbuggedStart) и затем выключаю экран, приложение не выходит из строя, и основная проблема устранена, но я должен выполнить двойной запуск WebView, и я не знаю как. хммм