5

Ich versuche, einen langen Klick in einem EditText zu tun, aber wenn ich einen langen Klick mache, erhalte ich den Fehler unten. Ich möchte in der Lage sein, einen langen Klick zu machen, um das Kontext-Popup Kopieren/Einfügen/Alles auswählen zu erhalten, damit der Benutzer Text in das Feld einfügen kann.Lange drücken EditText Absturz: Kann Fenster nicht hinzufügen

Fatal Exception: android.view.WindowManager$BadTokenException: Unable to add window -- token [email protected] is not valid; is your activity running? 

Der EditText befindet sich in einer ScrollView in einem PopupWindow. Wenn der Fehler auftritt, bin ich momentan in einer Aktivität mit geöffnetem PopupWindow aktiv und mache einen Long Click innerhalb des EditText, der im PopupWindow enthalten ist.

Gradle Einstellungen

compileSdkVersion 25 
buildToolsVersion '25.0.0' 
defaultConfig { 
    applicationId 'com.accoservice.cico' 
    minSdkVersion 17 
    targetSdkVersion 25 
    versionCode 37 
    versionName '4.2.6' 
    multiDexEnabled true 
} 

Layout der EditText:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/outer_layout" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:background="#73000000"> 

    <LinearLayout 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
     android:layout_gravity="top" 
     android:layout_marginLeft="20dp" 
     android:layout_marginRight="20dp" 
     android:layout_marginTop="100dp" 
     android:layout_marginBottom="5dp" 
     android:background="#ffffff" 
     android:orientation="vertical"> 

     <TextView 
      android:id="@+id/title" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:layout_marginBottom="5dp" 
      android:layout_marginLeft="5dp" 
      android:layout_marginTop="15dp" 
      android:singleLine="true" 
      android:text="@string/note_msg" 
      android:textColor="#62CCFE" 
      android:textSize="18sp" /> 

     <View 
      android:layout_width="fill_parent" 
      android:layout_height="2dp" 
      android:layout_marginBottom="5dp" 
      android:layout_marginTop="10dp" 
      android:background="#62CCFE" /> 

     <ScrollView 
      android:id="@+id/sv_resolution_note" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:layout_marginLeft="5dp" 
      android:layout_marginRight="5dp" 
      android:layout_marginTop="5dp"> 

      <EditText 
       android:id="@+id/et_note_msz" 
       android:layout_width="match_parent" 
       android:layout_height="match_parent" 
       android:layout_above="@+id/view" 
       android:layout_alignParentTop="true" 
       android:scrollbars="vertical" 
       android:focusable="true" 
       android:gravity="left" 
       android:maxLines="20" 
       android:hint="@string/write_note" 
       android:inputType="textFilter|textMultiLine|textCapSentences" 
       android:singleLine="false" 
       android:textIsSelectable="true" 
       android:enabled="true" 
       android:longClickable="true" /> 
     </ScrollView> 

     <View 
      android:id="@+id/view" 
      android:layout_width="fill_parent" 
      android:layout_height="1dp" 
      android:layout_above="@+id/send_note" 
      android:layout_alignParentLeft="true" 
      android:layout_alignParentStart="true" 
      android:background="@android:color/darker_gray" /> 

     <Button 
      android:id="@+id/send_note" 
      android:layout_width="fill_parent" 
      android:layout_height="wrap_content" 
      android:layout_above="@+id/viewss" 
      android:layout_gravity="center" 
      android:background="@color/white" 
      android:text="@string/add_note" /> 

     <View 
      android:id="@+id/viewss" 
      android:layout_width="fill_parent" 
      android:layout_height="1dp" 
      android:layout_alignParentBottom="true" 
      android:layout_alignParentLeft="true" 
      android:layout_alignParentStart="true" 

      android:background="@android:color/darker_gray" /> 

    </LinearLayout> 

</LinearLayout> 

Pop up das Fenster:

@Override 
public void onClick(View v) { 
    noteDialog(getResources().getString(R.string.laborentryresolutionstart), tv_labor_entry_resolution_start); 
} 

public void noteDialog(String noteTitle, final TextView tv_resolution_note) 
{ 
    LayoutInflater layoutInflater = (LayoutInflater) getBaseContext().getSystemService(LAYOUT_INFLATER_SERVICE); 
      final View popupView; 
      popupView = layoutInflater.inflate(R.layout.resolution_note, null); 

      TextView title = (TextView) popupView.findViewById(R.id.title); 
      title.setText(noteTitle); 

      final EditText editText = (EditText) popupView.findViewById(R.id.et_note_msz); 
      final PopupWindow popupWindow = new PopupWindow(popupView, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT, true); 
      popupWindow.update(); 
      popupWindow.setFocusable(true); 
      popupWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE); 
      editText.setEnabled(false); 
      editText.setEnabled(true); 
      editText.setFocusable(true); 
      editText.setOnLongClickListener(new View.OnLongClickListener() { 
       @Override 
       public boolean onLongClick(View v) { 

        //ADD HERE ABOUT CUT COPY PASTE 
        // TODO Auto-generated method stub 
        return false; 
       } 
      }); 

      if (!tv_resolution_note.getText().toString().isEmpty()) { 
       editText.setText(tv_resolution_note.getText().toString()); 
      } 

      Button btnDone = (Button) popupView.findViewById(R.id.send_note); 
      LinearLayout outer_layout = (LinearLayout) popupView.findViewById(R.id.outer_layout); 
      outer_layout.setOnClickListener(new View.OnClickListener() { 
       @Override 
       public void onClick(View view) { 
        popupWindow.dismiss(); 

        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); 
        imm.toggleSoftInput(InputMethodManager.RESULT_HIDDEN, 0); 
       } 
      }); 

      System.gc(); 
      try { 
       btnDone.setOnClickListener(new Button.OnClickListener() { 
        @Override 
        public void onClick(View v) { 
         EditText noteMsz = (EditText) popupView.findViewById(R.id.et_note_msz); 
         tv_resolution_note.setText(noteMsz.getText().toString()); 

         popupWindow.dismiss(); 

         InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); 
         imm.toggleSoftInput(InputMethodManager.RESULT_HIDDEN, 0); 

         invalidateOptionsMenu(); 
        } 
       }); 
      } catch (Exception e) { 
      } 

      popupWindow.setFocusable(true); 
      popupWindow.setBackgroundDrawable(new BitmapDrawable(null, "")); 
      popupWindow.showAsDropDown(tv_labor_sym_entry, 0, -60); 
      popupWindow.update();  
} 
+0

Rufen Sie diesen Code in einer Aktivität an? Ein Dienst? Sind Sie sicher, dass Sie nicht vom Bildschirm entfernt wurden, wenn eine Aktivität? Diese Meldung tritt normalerweise auf, wenn Sie versuchen, eine Benutzeroberfläche von einem Dienst aus zu starten, oder wenn Sie nach Abschluss der Aktivität versuchen, ein Dialogfeld aufzurufen. –

+0

Ich rufe den Code für das Popup-Fenster während einer Aktivität an. Die Aktivität läuft gerade, das Popup-Fenster ist aktiv und ich drücke lange in EditText und erhalte den Fehler. – Adam

+1

Ich habe Ihren Code mit geringfügigen Änderungen auf einem Emulator ausgeführt, der API 24 ausführt, und es funktioniert für mich OK. Das heißt, es stürzt nicht ab, und der Listener für lange Druckvorgänge wird wie erwartet aufgerufen. Kannst du mehr Informationen darüber geben, wie du Dinge aufstellst? API, auf der Sie testen? [Hier] (https://gist.github.com/Cheticamp/08ebef491a727a12577a7e9790eaa752) ist ein Kern der Aktivität, die ich für den Fall verwendet habe, dass es dir hilft. – Cheticamp

Antwort

0

Wir waren mit einer Neugestaltung ging das Popup und beseitigen den Fehler zu nehmen, der dort war.

0

Möglicherweise rufen Sie Ihr Popup zu früh an. In meinem Beispiel (gist here) führe ich den Popup-Code von einem Knopfdruck aus. Dies ist nach onCreate() und die anderen Schlüssel Lebenszyklus Methoden ausgeführt. Mit dem Beispiel funktioniert alles in Ordnung.

Wenn ich jedoch versuche, das Popup in onCreate() zu instanziieren, erhalte ich einen Logcat-Fehler, der besagt: "android.view.WindowManager $ BadTokenException: Fenster kann nicht hinzugefügt werden", was Sie sehen.

Ich glaube, dass Sie versuchen, Ihr Popup zu früh zu instanziieren. Starten Sie es später im Lebenszyklus der Aktivität und definitiv nach onCreate() ausgeführt wird. Wenn Sie es pronto instanziieren möchten, können Sie den Code über einen Anruf an post(Runnable) an die UI-Nachrichtenwarteschlange anhängen. (Siehe here).

Ich bin ziemlich sicher, dass dies Ihr Problem ist. Wenn dies nicht hilft, aktualisieren Sie Ihre Frage mit weiteren Informationen darüber, wie und wann Sie das Popup-Fenster instanziieren.

+0

Ich habe der Frage mehr Code hinzugefügt, damit Sie mehr sehen können. – Adam

+0

@Adam Ich kann Ihr Problem mit dem, was Sie geliefert haben, nicht reproduzieren. Wenn Sie weiterhin daran festhalten, schlage ich vor, dass Sie [MCVE] (https://stackoverflow.com/help/mcve) erstellen, das das Problem reproduziert. – Cheticamp

4

mir nach, der Grund, dass dieser Fehler auch immer ist, dass die outer_layout ‚s onClickListener zusammen mit dem onLongClickListener Ihrer editText gefeuert wird. Und da popupWindow.dismiss innerhalb des Click-Listeners Ihrer outer_layout aufgerufen wird, wird das Popup-Fenster vor dem editText langen Listener-Listencode beendet, wodurch der Fehler verursacht wird.

Die einfachste Lösung dieses Problems wäre true für Ihre onLongClick Methode zurückzukehren: -

editText.setOnLongClickListener(new View.OnLongClickListener() { 
       @Override 
       public boolean onLongClick(View v) { 

        //ADD HERE ABOUT CUT COPY PASTE 
        // TODO Auto-generated method stub 
        return true; 
       } 
      }); 

Auf diese Weise werden Sie den gegebenen langen Klick konsumieren, und es wird keine andere unerwünschte Zuhörer nicht feuern .

onLongClick() - Gibt eine boolean, um anzuzeigen, ob Sie haben das Ereignis verbraucht und es sollte nicht weiter getragen werden. Das heißt, geben Sie true zurück, um anzuzeigen, dass Sie das Ereignis behandelt haben, und es sollte hier aufhören; Gibt false zurück, wenn Sie es nicht behandelt haben und/oder das Ereignis mit allen anderen On-Click-Listenern fortgesetzt werden soll.

0

in der Hauptaktivität

Inhalt mContext privat;

public void onCreate(){ 
mContext = this; 
} 

ersetzen getBaseContext() mit mContext

LayoutInflater layoutInflater = (LayoutInflater) mContext.getSystemService(LAYOUT_INFLATER_SERVICE); 

oder

LayoutInflater layoutInflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);