android.view.WindowManager$BadTokenException异常。有指针吗?

android.view.WindowManager$BadTokenException异常。有指针吗?,android,Android,我有两个Web视图,为了从这两个Web视图中删除公共功能,我创建了一个超类,其中包含了超类中的所有方法,并在两个Web视图中使用它 当我从第一个webview创建对象并设置变量时,webview会正确显示,当我按下“上一步”按钮并转到第二个webview时,我会收到错误异常 有什么帮助吗 第一个WebView代码 public class firstWebView extends Activity { private static final String LOG_TAG = "Fir

我有两个Web视图,为了从这两个Web视图中删除公共功能,我创建了一个超类,其中包含了超类中的所有方法,并在两个Web视图中使用它

当我从第一个webview创建对象并设置变量时,webview会正确显示,当我按下“上一步”按钮并转到第二个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);
    } 
第二个的代码与第一个类似,但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();
    }
公共类NicuWebView{
专用静态NicuWebView_NicuWebView;
私有静态网络视图WebView;
私有静态HashMap\u URL;
私有静态上下文contextName;
私有静态最终整数视频_播放=0;
私有NicuWebView(WebView myWebView){
_URL=新的HashMap(10);
_webView=myWebView;
_setWebViewClient(新的NicuWebViewClient());
_webView.getSettings().setJavaScriptEnabled(true);
_clearCache(true);
WebSettings WebSettings=_webView.getSettings();
webSettings.setSavePassword(true);
webSettings.setSaveFormData(真);
setJavaScriptEnabled(true);
webSettings.setSupportZoom(真);
_addJavascriptInterface(新的DemoJavaScriptInterface(),“demo”);
_clearCache(true);
_setWebViewClient(新的WebViewClient(){
public void onReceivedError(WebView视图、int错误代码、字符串描述、字符串失败URL){
Toast.makeText(contextName,“超级类Toast消息”,Toast.LENGTH_LONG.show();
}
@凌驾
公共void onPageFinished(WebView视图,字符串url)
{  
_loadUrl(“javascript:(函数(){”+
setVariable(“+mainMenuActivity.numberSelected+”)+
"})()");
}  
});
_setWebView.WebChromeClient(新WebChromeClient(){
public void onProgressChanged(WebView视图,int-progress){
//活动和网络视图以不同的尺度衡量进度。
//当我们达到100%时,进度表将自动消失
((活动)contextName).setProgress(进度*1000);
}
});
_setWebViewClient(新的WebViewClient(){
public void onReceivedError(WebView视图、int错误代码、字符串描述、字符串失败URL){
Toast.makeText(contextName,“噢,不!”+描述,Toast.LENGTH_SHORT.show();
}
@凌驾
public void onPageFinished(WebView视图,字符串url){
_loadUrl(“javascript:(函数(){”+
setVariable(“+mainMenuActivity.numberSelected+”)+
"})()");
}  
});
}
//允许点击链接保留在应用程序中,而不是启动android浏览器
私有类NicuWebViewClient扩展了WebViewClient{
@凌驾
公共布尔值shouldOverrideUrlLoading(WebView视图,字符串url){
view.loadUrl(url);
返回true;
}
}   
公共静态NicuWebView getNicuWebView(WebView myWebView){
如果(_-nicuWebView==null)_-nicuWebView=new-nicuWebView(myWebView);
返回_nicuWebView;
}
//加载请求的URL并维护已访问页面的“历史记录”。
//返回页面加载的次数。
公共长加载url(字符串url){
长计数=递增计数器(url);
_loadUrl(url);
返回计数;
}
//助手
专用静态长增量计数器(字符串url){
如果(url!=null){
if(_url.get(url)==null)_url.put(url,新长(0));
长计数=url.put(url,url.get(url)+1L);
返回计数;
}
否则{
Toast.makeText(contextName,“Null URL”,Toast.LENGTH_SHORT).show();
返回0;
}
}
///返回给定URL的访问次数
公共长getUrlVisitCount(字符串url){
if(_url.get(url)==null)返回0L;
返回_url.get(url);
}
//返回上一个URL,返回该URL
公共字符串goBack(){
如果(_webView.canGoBack())_webView.goBack();
字符串url=_webView.getUrl();
递增计数器(url);
返回url;
}
//返回下一个转发URL,返回该URL
公共字符串goForward(){
如果(_webView.canGoForward())_webView.goForward();
字符串url=_webView.getUrl();
递增计数器(url);
返回url;
}
公共静态布尔集合上下文(上下文上下文){
contextName=上下文;
返回true;
}
公共上下文getContext(){
if(contextName==null)返回null;
返回contextName;
}
最终类DemoJavaScriptInterface{
public void setPlayVideo(字符串选项){
Toast.makeText(contextName,“播放视频=“+选项,Toast.LENGTH_SHORT).show();
意图=新意图(contextName,playVideo.class);
((活动)contextName).startActivityForResult(意图,视频播放);
}
}   
公共布尔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;
    }

创建
WebView
时,您当前正在使用应用程序的上下文。您应该使用
活动的上下文。要解决此问题,请在创建
WebView

时将
getApplicationContext()
替换为此,您的nicuwebview的代码是什么?您的解决方案对我很有效,进一步播放表明,放置
mContext=this内部
onCreate()
就足够了。我猜错误是b