上下文菜单/窗口中的WebView里面PopupWindow崩溃的应用程序? [英] Context Menu/Window in WebView inside PopupWindow crashes the app?

查看:1175
本文介绍了上下文菜单/窗口中的WebView里面PopupWindow崩溃的应用程序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有包含的WebView PopupWindow一个应用程序,打开Facebook的页面,就像任何上下文菜单:在文本字段中的web视图中自动完成,甚至长preSS应显示供用户选择复制/粘贴/剪切崩溃的应用程序与后续的错误的时候了:

 致命异常:主要
android.view.WindowManager $ BadTokenException:无法添加窗口 - 令牌android.view.ViewRootImpl$W@418cdab0无效;在您的活动运行?
在android.view.ViewRootImpl.setView(ViewRootImpl.java:700)
在android.view.WindowManagerImpl.addView(WindowManagerImpl.java:345)
在android.view.WindowManagerImpl.addView(WindowManagerImpl.java:224)
在android.view.WindowManagerImpl $ CompatModeWrapper.addView(WindowManagerImpl.java:149)
在android.view.Window $ LocalWindowManager.addView(Window.java:554)
在android.widget.PopupWindow.invokePopup(PopupWindow.java:1013)
在android.widget.PopupWindow.showAtLocation(PopupWindow.java:856)
在android.widget.PopupWindow.showAtLocation(PopupWindow.java:820)
在android.webkit.WebViewClassic $ PastePopupWindow.show(WebViewClassic.java:971)
在android.webkit.WebViewClassic.showPasteWindow(WebViewClassic.java:7037)
在android.webkit.WebViewClassic.access $ 10300(WebViewClassic.java:235)
在android.webkit.WebViewClassic $ PrivateHandler.handleMessage(WebViewClassic.java:11376)
在android.os.Handler.dispatchMessage(Handler.java:99)
在android.os.Looper.loop(Looper.java:137)
在android.app.ActivityThread.main(ActivityThread.java:4921)
在java.lang.reflect.Method.invokeNative(本机方法)
在java.lang.reflect.Method.invoke(Method.java:511)
在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:1027)
在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:794)
在dalvik.system.NativeStart.main(本机方法)
 

请注意:我对问题的理解是,在上下文菜单/窗口中的应用程序本身的范围,实际显示不使用其他PopWindow(自动由核心的WebView类生成)web视图里面此类引用上下文不正确。

我的code是如下:

的main.xml

 < XML版本=1.0编码=UTF-8&GT?;
< LinearLayout中的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
    机器人:layout_width =FILL_PARENT
    机器人:layout_height =FILL_PARENT
    机器人:方向=垂直>

    <按钮
        机器人:ID =@ + ID / openpopup
        机器人:layout_width =FILL_PARENT
        机器人:layout_height =WRAP_CONTENT
        机器人:文本=打开弹出窗口/>

< / LinearLayout中>
 

Popup.xml

 < LinearLayout中的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
    机器人:layout_width =FILL_PARENT
    机器人:layout_height =FILL_PARENT
    机器人:背景=@机器人:彩色/ background_light
    机器人:方向=垂直>

    <的LinearLayout
        机器人:layout_width =FILL_PARENT
        机器人:layout_height =FILL_PARENT
        机器人:layout_margin =1DP
        机器人:背景=@机器人:彩色/ darker_gray
        机器人:方向=垂直>
     >

        <的LinearLayout
            机器人:layout_width =FILL_PARENT
            机器人:layout_height =FILL_PARENT
            机器人:layout_margin =20dp
            机器人:方向=垂直>

            <的WebView
                的xmlns:PTR =htt​​p://schemas.android.com/apk/res-auto
                机器人:ID =@ + ID / webviewActionView
                机器人:layout_width =FILL_PARENT
                机器人:layout_height =FILL_PARENT
                机器人:=了minHeight200dp
                机器人:=了minWidth200dp
                机器人:滚动条=无>
            < /的WebView>

            <按钮
                机器人:ID =@ + ID /解雇
                机器人:layout_width =FILL_PARENT
                机器人:layout_height =WRAP_CONTENT
                机器人:文本=辞退/>
        < / LinearLayout中>
    < / LinearLayout中>

< / LinearLayout中>
 

MainActivity.java

 进口android.os.Bundle;
进口android.annotation.Sup pressLint;
进口android.app.Activity;
进口android.util.Log;
进口android.view.LayoutInflater;
进口android.view.View;
进口android.view.ViewGroup.LayoutParams;
进口android.webkit.WebView;
进口android.webkit.WebViewClient;
进口android.widget.Button;
进口android.widget.PopupWindow;

公共类MainActivity延伸活动{

    @覆盖
    公共无效的onCreate(包savedInstanceState){
        super.onCreate(savedInstanceState);
        的setContentView(R.layout.main);

        最终按钮btnOpenPopup =(按钮)findViewById(R.id.openpopup);
        btnOpenPopup.setOnClickListener(新Button.OnClickListener(){

            @燮pressLint(NewApi)
            @覆盖
            公共无效的onClick(查看为arg0){

                LayoutInflater layoutInflater =(LayoutInflater)getBaseContext()getSystemService(LAYOUT_INFLATER_SERVICE)。
                查看popupView = layoutInflater.inflate(R.layout.popup,NULL);
                最后PopupWindow popupWindow =新PopupWindow(popupView,
                        LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT);

                popupWindow.setTouchable(真正的);
                popupWindow.setFocusable(真正的);

                的WebView popupWebview =(web视图)popupView.findViewById(R.id.webviewActionView);
                popupWebview.loadUrl(https://m.facebook.com);
                按钮btnDismiss =(按钮)popupView
                        .findViewById(R.id.dismiss);
                btnDismiss.setOnClickListener(新Button.OnClickListener(){
                    @覆盖
                    公共无效的onClick(视图v){

                        // TODO自动生成方法存根
                        popupWindow.dismiss();
                    }
                });
                popupWindow.showAsDropDown(btnOpenPopup,50,-30);
            }
        });
    }
}
 

解决方案

由于上述评论我的回答,您可以使用自定义对话框您的要求..我已经创建了一个样本PopUpDialog,这个PopUpDialog ..请让我know..if它解决了你的目的..自动完成和ContextMenus会正常运行。

MyActivity.java

 包com.example.testapp;

进口android.annotation.Sup pressLint;
进口android.app.Activity;
进口android.os.Bundle;
进口android.view.LayoutInflater;
进口android.view.View;
进口android.webkit.WebChromeClient;
进口android.webkit.WebView;
进口android.webkit.WebViewClient;
进口android.widget.Button;

公共类MyActivity延伸活动{

@覆盖
公共无效的onCreate(包savedInstanceState){
    super.onCreate(savedInstanceState);
    的setContentView(R.layout.main);

    最终按钮btnOpenPopup =(按钮)findViewById(R.id.openpopup);
    btnOpenPopup.setOnClickListener(新Button.OnClickListener(){

        @燮pressLint(NewApi)
        @覆盖
        公共无效的onClick(查看为arg0){

            最后PopUpDialog,这个PopUpDialog PopUpDialog,这个PopUpDialog =新PopUpDialog,这个PopUpDialog(MyActivity.this);
            popupDialog.setContentView(R.layout.popup);

            的WebView popupWebview =(web视图)popupDialog.findViewById(R.id.webviewActionView);
            popupWebview.setWebChromeClient(新WebChromeClient());
            popupWebview.setWebViewClient(新WebViewClient());

            popupWebview.loadUrl(http://m.facebook.com);
            按钮btnDismiss =(按钮)PopUpDialog,这个PopUpDialog
                    .findViewById(R.id.dismiss);
            btnDismiss.setOnClickListener(新Button.OnClickListener(){
                @覆盖
                公共无效的onClick(视图v){

                    // TODO自动生成方法存根
                    popupDialog.dismiss();
                }
            });
// popupDialog.showAtLocation(50,50);
            popupDialog.showAsDropDown(findViewById(R.id.openpopup));
        }
    });
}
}
 

PopupDialog.java

 包com.example.testapp;

进口android.app.Dialog;
进口android.content.Context;
进口android.view.Gravity;
进口android.view.View;
进口android.view.Window;
进口android.view.WindowManager;

公共类PopUpDialog,这个PopUpDialog扩展对话框{
私人最终语境mContext;

公共PopUpDialog,这个PopUpDialog(上下文的背景下){
    超(上下文);
    mContext =背景;
    requestWindowFeature(Window.FEATURE_NO_TITLE);
}

公共无效showAtLocation(INT X,int y)对
{
    WindowManager.LayoutParams wmlp = getWindow()的getAttributes()。
    wmlp.gravity = Gravity.TOP | Gravity.LEFT;
    wmlp.x = X;
    wmlp.y = Y;
    显示();
}
公共无效showAsDropDown(查看视图)
{
    浮密度= mContext.getResources()getDisplayMetrics()密度。
    WindowManager.LayoutParams wmlp = getWindow()的getAttributes()。
    INT []的位置=新INT [2];
    view.getLocationInWindow(位置);
    wmlp.gravity = Gravity.TOP | Gravity.LEFT;
    wmlp.x =位置[0] +(int)的(view.getWidth()/密度);
    wmlp.y =位置[1] +(int)的(view.getHeight()/密度);
    显示();
}
}
 

编辑:添加popup.xml

 < LinearLayout中的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
          机器人:layout_width =FILL_PARENT
          机器人:layout_height =FILL_PARENT
          机器人:=了minHeight400dp
          机器人:=了minWidth200dp
          机器人:背景=@机器人:彩色/ background_light
          机器人:方向=垂直>

<的LinearLayout
        机器人:layout_width =FILL_PARENT
        机器人:layout_height =FILL_PARENT
        机器人:layout_margin =1DP
        机器人:背景=@机器人:彩色/ darker_gray
        机器人:方向=垂直>
    >

    <的LinearLayout
            机器人:layout_width =FILL_PARENT
            机器人:layout_height =FILL_PARENT
            机器人:layout_margin =20dp
            机器人:方向=垂直>

        <的WebView
            的xmlns:PTR =htt​​p://schemas.android.com/apk/res-auto
                机器人:ID =@ + ID / webviewActionView
                机器人:layout_width =FILL_PARENT
                机器人:layout_height =WRAP_CONTENT
                机器人:=了minHeight200dp
                机器人:=了minWidth200dp
                机器人:滚动条=无>
        < /的WebView>

        <按钮
                机器人:ID =@ + ID /解雇
                机器人:layout_width =FILL_PARENT
                机器人:layout_height =WRAP_CONTENT
                机器人:文本=辞退/>
    < / LinearLayout中>
< / LinearLayout中>
 

I have an app with PopupWindow containing WebView that opens Facebook's page, any context menu like: the Autocomplete on text fields in the WebView or even the Long Press that should display options for the user to copy/paste/cut crashes the app right away with the follow error:

FATAL EXCEPTION: main
android.view.WindowManager$BadTokenException: Unable to add window -- token android.view.ViewRootImpl$W@418cdab0 is not valid; is your activity running?
at android.view.ViewRootImpl.setView(ViewRootImpl.java:700)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:345)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:224)
at android.view.WindowManagerImpl$CompatModeWrapper.addView(WindowManagerImpl.java:149)
at android.view.Window$LocalWindowManager.addView(Window.java:554)
at android.widget.PopupWindow.invokePopup(PopupWindow.java:1013)
at android.widget.PopupWindow.showAtLocation(PopupWindow.java:856)
at android.widget.PopupWindow.showAtLocation(PopupWindow.java:820)
at android.webkit.WebViewClassic$PastePopupWindow.show(WebViewClassic.java:971)
at android.webkit.WebViewClassic.showPasteWindow(WebViewClassic.java:7037)
at android.webkit.WebViewClassic.access$10300(WebViewClassic.java:235)
at android.webkit.WebViewClassic$PrivateHandler.handleMessage(WebViewClassic.java:11376)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4921)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1027)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:794)
at dalvik.system.NativeStart.main(Native Method)

Notice: my understanding of the problem is that the context menu/window are shown actually in the scope of the app itself not inside the WebView using another PopWindow (Auto generated by the Core WebView Class) this class references the context incorrectly.

My Code is as follows:

Main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <Button
        android:id="@+id/openpopup"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Open Popup Window" />

</LinearLayout>

Popup.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@android:color/background_light"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_margin="1dp"
        android:background="@android:color/darker_gray"
        android:orientation="vertical" >
     >

        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:layout_margin="20dp"
            android:orientation="vertical" >

            <WebView
                xmlns:ptr="http://schemas.android.com/apk/res-auto"
                android:id="@+id/webviewActionView"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:minHeight="200dp"
                android:minWidth="200dp"
                android:scrollbars="none" >
            </WebView>

            <Button
                android:id="@+id/dismiss"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:text="Dismiss" />
        </LinearLayout>
    </LinearLayout>

</LinearLayout>

MainActivity.java

import android.os.Bundle;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Button;
import android.widget.PopupWindow;

public class MainActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        final Button btnOpenPopup = (Button) findViewById(R.id.openpopup);
        btnOpenPopup.setOnClickListener(new Button.OnClickListener() {

            @SuppressLint("NewApi")
            @Override
            public void onClick(View arg0) {

                LayoutInflater layoutInflater = (LayoutInflater) getBaseContext().getSystemService(LAYOUT_INFLATER_SERVICE);
                View popupView = layoutInflater.inflate(R.layout.popup, null);
                final PopupWindow popupWindow = new PopupWindow(popupView,
                        LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);

                popupWindow.setTouchable(true);
                popupWindow.setFocusable(true);

                WebView popupWebview = (WebView) popupView.findViewById(R.id.webviewActionView);
                popupWebview.loadUrl("https://m.facebook.com");
                Button btnDismiss = (Button) popupView
                        .findViewById(R.id.dismiss);
                btnDismiss.setOnClickListener(new Button.OnClickListener() {
                    @Override
                    public void onClick(View v) {

                        // TODO Auto-generated method stub
                        popupWindow.dismiss();
                    }
                });
                popupWindow.showAsDropDown(btnOpenPopup, 50, -30);
            }
        });
    }
}

解决方案

As commented above in my answer you can use Custom dialog for your requirement.. i have created a sample PopupDialog.. please check and let me know..if it solve your purpose.. Autocomplete and ContextMenus will work as expected..

MyActivity.java

package com.example.testapp;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Button;

public class MyActivity extends Activity {

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    final Button btnOpenPopup = (Button) findViewById(R.id.openpopup);
    btnOpenPopup.setOnClickListener(new Button.OnClickListener() {

        @SuppressLint("NewApi")
        @Override
        public void onClick(View arg0) {

            final PopupDialog popupDialog = new PopupDialog(MyActivity.this);
            popupDialog.setContentView(R.layout.popup);

            WebView popupWebview = (WebView) popupDialog.findViewById(R.id.webviewActionView);
            popupWebview.setWebChromeClient(new WebChromeClient());
            popupWebview.setWebViewClient(new WebViewClient());

            popupWebview.loadUrl("http://m.facebook.com");
            Button btnDismiss = (Button) popupDialog
                    .findViewById(R.id.dismiss);
            btnDismiss.setOnClickListener(new Button.OnClickListener() {
                @Override
                public void onClick(View v) {

                    // TODO Auto-generated method stub
                    popupDialog.dismiss();
                }
            });
//                popupDialog.showAtLocation(50,50);
            popupDialog.showAsDropDown(findViewById(R.id.openpopup));
        }
    });
}
}

PopupDialog.java

package com.example.testapp;

import android.app.Dialog;
import android.content.Context;
import android.view.Gravity;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;

public class PopupDialog extends Dialog{
private final Context mContext;

public PopupDialog(Context context) {
    super(context);
    mContext=context;
    requestWindowFeature(Window.FEATURE_NO_TITLE);
}

public void showAtLocation(int x,int y)
{
    WindowManager.LayoutParams wmlp = getWindow().getAttributes();
    wmlp.gravity = Gravity.TOP | Gravity.LEFT;
    wmlp.x = x;
    wmlp.y = y;
    show();
}
public void showAsDropDown(View view)
{
    float density = mContext.getResources().getDisplayMetrics().density;
    WindowManager.LayoutParams wmlp = getWindow().getAttributes();
    int[] location = new int[2];
    view.getLocationInWindow(location);
    wmlp.gravity = Gravity.TOP | Gravity.LEFT;
    wmlp.x = location[0]+(int)(view.getWidth()/density);
    wmlp.y = location[1]+(int)(view.getHeight()/density);
    show();
}
}

edit: added popup.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:layout_width="fill_parent"
          android:layout_height="fill_parent"
          android:minHeight="400dp"
          android:minWidth="200dp"
          android:background="@android:color/background_light"
          android:orientation="vertical" >

<LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_margin="1dp"
        android:background="@android:color/darker_gray"
        android:orientation="vertical" >
    >

    <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:layout_margin="20dp"
            android:orientation="vertical" >

        <WebView
            xmlns:ptr="http://schemas.android.com/apk/res-auto"
                android:id="@+id/webviewActionView"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:minHeight="200dp"
                android:minWidth="200dp"
                android:scrollbars="none" >
        </WebView>

        <Button
                android:id="@+id/dismiss"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:text="Dismiss" />
    </LinearLayout>
</LinearLayout>

这篇关于上下文菜单/窗口中的WebView里面PopupWindow崩溃的应用程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆