2013-03-30 26 views
4

我有一個包含WebView的PopupWindow應用程序,可以打開Facebook的頁面,任何上下文菜單,如:WebView中的文本字段上的自動完成,甚至是應該顯示用戶複製/粘貼/剪切選項的長按,會使應用程序崩潰客場與後續的錯誤:PopupWindow中的WebView中的上下文菜單/窗口崩潰應用程序?

FATAL EXCEPTION: main 
android.view.WindowManager$BadTokenException: Unable to add window -- token [email protected] 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) 

注意:我對這個問題的理解是,上下文菜單/窗口中使用另一個PopWindow(自動web視圖內不通過所產生的應用程序本身的範圍實際顯示核心WebView類)這個類不正確地引用上下文。

我的代碼如下:

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); 
      } 
     }); 
    } 
} 
+0

你在哪條線上合力?我試過了,它的工作。 – kyogs

+0

你在JB上試過這個嗎?它只發生在JB 4.1+上,不會發生在ICS或GB上。 – Shehabix

+0

ya.i也試過在JB 4.2和它的工作很好.. – kyogs

回答

2

是的我認爲你應該使用你的活動名稱來代替「getBaseContext()」。我只是用你的代碼創建了一個演示。它在我的電腦上工作正常。當你得到這個異常?

+0

它長時間按fb登錄中的用戶字段時崩潰,並更改getBaseContext也沒有幫助;試試這個JB 4.1+ – Shehabix

+0

好吧,現在請從下面的鏈接下載我的代碼,並檢查發生了什麼,並告訴我.. http://www.mediafire.com/?ypp5cq22p7n66pq – Ajay

+0

好吧,它崩潰,你沒有改變任何東西代碼已經。 – Shehabix

1

您的代碼沒有錯誤...似乎是Android 4.1+特定問題.. Webview也使用PopupWindow在輸入框中顯示粘貼上下文菜單。通過webview嵌套的popupwindows導致WindowManager崩潰,同時添加新視圖到它。

我與嵌入式網頁視圖試圖自定義對話框(到位Popupwindow的),粘貼上下文菜單來了罰款,Android 4.1以上版本..

如果你不是那麼具體的關於本貼上下文菜單中你可以將其禁用使用下面code..i特定Android版本已經嘗試過了..這將受益於被急停應用..

popupWebView.setOnLongClickListener(new OnLongClickListener() { 

     @Override 
     public boolean onLongClick(View v) { 
      if (Build.VERSION.SDK_INT >= 16) 
        return true; 
       return false; 
     } 
    }); 

您也可以看看Webview HitTestResult類,用於顯示一些定製的上下文菜單,根據您的需要..

+0

這不僅僅是點擊/ longClick,它也發生在自動完成形式,我不想禁用它;相反,我想修復它,即使我必須擴展默認的popupWindow類並重寫一些方法。 – Shehabix

+0

擴展PopupWindow不會解決問題..至於繪圖PopupWindow窗口是需要從父活動。如果嵌套的Popupwindow父窗口爲popupwindow的popupwindow ..我會建議創建自定義對話框與您選擇的x,y coridinates ..那將解決目的。例如[見這裏](http://stackoverflow.com/questions/5469005/show-alertdialog-in-any-position-of-the-screen).. – Akhil

6

正如上面評論我的答案,你可以使用自定義對話框爲您的要求..我創建了一個示例PopupDialog ..請檢查並讓我知道..如果它解決您的目的..自動完成和ContextMenus將按預期工作。

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(); 
} 
} 

編輯:添加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> 

相關問題