我有两个网页浏览,并从网页浏览中删除了我使用超类中的所有方法创建超类的常用功能,并在两个网页视图中使用它.
一旦我创建对象并从第一个webview设置变量,WebView就会正常显示,当我按下"BACK"按钮并转到第二个WebView时,我会得到异常的异常.
有帮助吗?
第一个WebView代码
public class firstWebView extends Activity { private static final String LOG_TAG = "FirstWebView"; public static final int VIDEO_PLAY = 0; private WebView mWebView; private NicuWebView _nicuWebView; private static final String URL = mainMenuActivity.urlSelected+"todo.html"; @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); setContentView(R.layout.webview); getWindow().setFeatureInt(Window.FEATURE_PROGRESS, Window.PROGRESS_VISIBILITY_ON); mWebView = (WebView) findViewById(R.id.webview); _nicuWebView = NicuWebView.getNicuWebView(mWebView); // mWebView.setWebChromeClient(new MyWebChromeClient()); final Activity activity = this; NicuWebView.setContext(activity); setProgressBarVisibility(true); int count = (int) _nicuWebView.loadUrl(URL); Toast.makeText(this, "Count = "+count, Toast.LENGTH_SHORT).show(); } public boolean onKeyDown(int keyCode, KeyEvent event) { if ((keyCode == KeyEvent.KEYCODE_BACK) && mWebView.canGoBack()) { // startActivity(new Intent(getApplication(), mainMenuActivity.class)); mWebView.goBack(); return true; } return super.onKeyDown(keyCode, event); }
Code for Second与第一个类似,但URL指向不同的html页面.
E/AndroidRuntime( 7913): android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy@447d2a98 is not valid; is your activity running? E/AndroidRuntime( 7913): at android.view.ViewRoot.setView(ViewRoot.java:468) E/AndroidRuntime( 7913): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:177) E/AndroidRuntime( 7913): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91) E/AndroidRuntime( 7913): at android.view.Window$LocalWindowManager.addView(Window.java:424) E/AndroidRuntime( 7913): at android.app.Dialog.show(Dialog.java:239) E/AndroidRuntime( 7913): at android.app.AlertDialog$Builder.show(AlertDialog.java:802) E/AndroidRuntime( 7913): at android.webkit.CallbackProxy.handleMessage(CallbackProxy.java:483) E/AndroidRuntime( 7913): at android.os.Handler.dispatchMessage(Handler.java:99) E/AndroidRuntime( 7913): at android.os.Looper.loop(Looper.java:123) E/AndroidRuntime( 7913): at android.app.ActivityThread.main(ActivityThread.java:4363) E/AndroidRuntime( 7913): at java.lang.reflect.Method.invokeNative(NativeMethod) E/AndroidRuntime( 7913): at java.lang.reflect.Method.invoke(Method.java:521) E/AndroidRuntime( 7913): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860) E/AndroidRuntime( 7913): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618) E/AndroidRuntime( 7913): at dalvik.system.NativeStart.main(Native Method)
NicuWebView的代码是
public class NicuWebView { private static NicuWebView _nicuWebView; private static WebView _webView; private static HashMap_urls; private static Context contextName; private static final int VIDEO_PLAY = 0; private NicuWebView(WebView myWebView) { _urls = new HashMap (10); _webView = myWebView; _webView.setWebViewClient(new NicuWebViewClient()); _webView.getSettings().setJavaScriptEnabled(true); _webView.clearCache(true); WebSettings webSettings = _webView.getSettings(); webSettings.setSavePassword(true); webSettings.setSaveFormData(true); webSettings.setJavaScriptEnabled(true); webSettings.setSupportZoom(true); _webView.addJavascriptInterface(new DemoJavaScriptInterface(), "demo"); _webView.clearCache(true); _webView.setWebViewClient(new WebViewClient() { public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { Toast.makeText(contextName, "Super Class TOAST message", Toast.LENGTH_LONG).show(); } @Override public void onPageFinished(WebView view, String url) { _webView.loadUrl("javascript:(function () { " + "setVariable("+mainMenuActivity.numberSelected+");" + "})()"); } }); _webView.setWebChromeClient(new WebChromeClient() { public void onProgressChanged(WebView view, int progress) { // Activities and WebViews measure progress with different scales. // The progress meter will automatically disappear when we reach 100% ((Activity) contextName).setProgress(progress * 1000); } }); _webView.setWebViewClient(new WebViewClient() { public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { Toast.makeText(contextName, "Oh no! " + description, Toast.LENGTH_SHORT).show(); } @Override public void onPageFinished(WebView view, String url) { _webView.loadUrl("javascript:(function () { " + "setVariable("+mainMenuActivity.numberSelected+");" + "})()"); } }); } // allow clicking on link to remain in app instead of launching android browser private class NicuWebViewClient extends WebViewClient { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { view.loadUrl(url); return true; } } public static NicuWebView getNicuWebView(WebView myWebView){ if (_nicuWebView == null) _nicuWebView = new NicuWebView(myWebView); return _nicuWebView; } // loads the requested URL and maintains a 'history' of pages visited. // returns number of times page was loaded. public long loadUrl(String url) { long count = incrementCounter(url); _webView.loadUrl(url); return count; } //helper to private static long incrementCounter(String url){ if (url != null) { if (_urls.get(url)==null) _urls.put(url,new Long(0)); long count = _urls.put(url,_urls.get(url) +1L); return count; } else { Toast.makeText(contextName, "Null URL", Toast.LENGTH_SHORT).show(); return 0; } } /// return the number of times the given URL has been visited public long getUrlVisitCount(String url) { if (_urls.get(url)==null) return 0L; return _urls.get(url); } //returns to the previous URL, returns that URL public String goBack(){ if (_webView.canGoBack()) _webView.goBack(); String url = _webView.getUrl(); incrementCounter(url); return url; } //returns to next forward URL, returns that URL public String goForward(){ if (_webView.canGoForward()) _webView.goForward(); String url = _webView.getUrl(); incrementCounter(url); return url; } public static boolean setContext(Context context) { contextName = context; return true; } public Context getContext(){ if (contextName == null) return null; return contextName; } final class DemoJavaScriptInterface { public void setPlayVideo(String option) { Toast.makeText(contextName, "Playing Video = "+option, Toast.LENGTH_SHORT).show(); Intent intent = new Intent ( contextName, playVideo.class ); ((Activity) contextName).startActivityForResult(intent, VIDEO_PLAY); } } public boolean canGoBack() { return _webView.canGoBack(); }
}
问题是对话框需要具有您活动的"基础"上下文,而不一定是您从中启动它的那个.
这是一个经常有效的解决方案
Activity a = this; while(a.getParent() != null) { a = a.getParent(); } _nicuWebView.setContext(a);
查看正在发生的事情的一种方法是修改该示例,如下所示
Activity a = this; while(a.getParent() != null) { Log.i("ActivityTree",a.getClass().getSimpleName()); a = a.getParent(); } _nicuWebView.setContext(a);
adb
然后会告诉你你所在的活动的层次结构.
用这个 :
private Handler myHandler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case DISPLAY_DLG: if (!isFinishing()) { showDialog(MY_DIALOG); } break; } } };
你只需要添加:
public void onResume() { super.onResume(); mContext = this; }