android.view.WindowManager$BadTokenException异常。有指针吗?
我有两个Web视图,为了从这两个Web视图中删除公共功能,我创建了一个超类,其中包含了超类中的所有方法,并在两个Web视图中使用它 当我从第一个webview创建对象并设置变量时,webview会正确显示,当我按下“上一步”按钮并转到第二个webview时,我会收到错误异常 有什么帮助吗 第一个WebView代码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
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