NullPointerException on WebView (WebView.requestFocus())
I've got a question:
In my Android app there is an activity containing a WebView
. This WebView
contains Flash content which is played back. When I switch out of this App to my Homescreen, the Flash contents is running smooth in the background. When I switch to the Homescreen an then turn the screen off, the Flash content is also running. But when I turn the screen off, while I'm in the App itself, the WebView
throws a NullPointerException
like the following at the end of the text. I have seriously no clue how to fix this issue. I hope that somebody might help me out.
Edit: I develop for Android 2.2
. After some testing I found something special. When I turn off the screen while I'am running the app I get the mentioned exception, but when I turn the screen back on in time, I get "only" the following exception. I know it's nothing special and already known, but maybe it helps.
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.and开发者_JAVA技巧roid.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)
And here is the the method where the WebView
is created:
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
Ok guys, I solved this problem.
The clue to the solution was the screen orientation. Like you can see in the code of the first post, I called in the onCreate() method: setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
The result of this call was, that the activity was called twice because of the orientation change. Thats the reason why I used:
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());
}
This code prevents the WebView
for being started twice. You can see that I destroy one of the two created WebViews. Now, when I turned off the screen, the OS wants to call the destroyed WebView
which leads to the NullPointerException
.
I overthougt the mechanisms of my onCreate method and changed it. Now, the orientation is discribed in the manifest:
android:screenOrientation="landscape"
After this modification, the problem wasn't truley solved. When I turned off the screen, the OS launched the Activity with the WebView
in it again, because the orientation switched from Landscape to Portrait when I switched off the screen. I added in the Manifest the following:
android:configChanges="keyboardHidden|orientation"
and now everything works perfectly.
Without knowing the version of Android that you're running, I took a look at the implementation of requestFocus() in the head revision of WebView and there don't appear to be that many opportunities for an NPE. One possibility is that when the screen is turned off, that the WebView.destroy() method is getting called (setting mWebViewCore to null), even though the Activity is still holding onto it and trying to give focus to it when the state is being restored.
You might try overriding onRestoreInstanceState in your Activity and seeing whether the WebView still has a consistent state at that point. Again, looking at the head revision, if you were to call "getSettings()", this will throw an NPE for the same reason and you could be relatively certain that this is the issue.
精彩评论