我有两个网页浏览,并从网页浏览中删除了常用功能,我使用超类中的所有方法创建了一个超类,并在两个网页视图中使用它。
当我创建对象并从第一个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<String,Long> _urls;
private static Context contextName;
private static final int VIDEO_PLAY = 0;
private NicuWebView(WebView myWebView) {
_urls = new HashMap<String,Long>(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();
}
}
答案 0 :(得分:14)
问题是对话框需要具有您活动的“基础”上下文,而不一定是您要从中启动它的那个。
这是一个经常有效的解决方案
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
将显示您所在的活动层次结构。
答案 1 :(得分:5)
使用它:
private Handler myHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case DISPLAY_DLG:
if (!isFinishing()) {
showDialog(MY_DIALOG);
}
break;
}
}
};
答案 2 :(得分:5)
您只需添加:
public void onResume() {
super.onResume();
mContext = this;
}
答案 3 :(得分:0)
创建WebView
时,您当前正在使用应用程序的上下文。您应该使用Activity
的上下文。要解决此问题,请在创建getApplicationContext()
时将WebView
替换为<{1}}。