2017-07-26 2 views
0

Ich möchte einen Scheduler einrichten und nach einer vordefinierten Zeit ein Popup anzeigen.Wie zeige ich AlertDialog von ScheduledExecutor an?

Im folgenden Beispiel wird das Protokoll "geplante Warnung" einmal gedruckt, aber das Warndialogfeld wird nie angezeigt.

public class MainActivity extends AppCompatActivity { 

     @Override 
     protected void onCreate(Bundle savedInstanceState) { 
      //... 
      initAlert(this); 
     } 

     private void initAlert(Activity activity) { 
      final ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1); 
      executor.schedule(new Runnable() { 
       @Override 
       public void run() { 
        Log.i("app", "scheduled alert"); 

        new AlertDialog.Builder(activity) 
        .setTitle("test") 
        .setMessage("lorep") 
        .setPositiveButton("OK", new DialogInterface.OnClickListener() { 
         public void onClick(DialogInterface dialog, int id) { 
          Log.i("app", "ok clicked"); 
         } 
        }) 
        .setIcon(android.R.drawable.ic_dialog_alert) 
        .create() 
        .show(); 
       } 
      }, 10, TimeUnit.SECONDS); 
     } 
} 

Die Initialisierung befindet sich in der Hauptaktivität.

Warum wird der Dialog nicht angezeigt?

Wenn ich eine Schaltfläche zu meiner Ansicht hinzufüge und den Warndialog explizit mit dieser Schaltfläche verknüpfe, funktioniert es. Daher sollte der Dialogcode im Allgemeinen in Ordnung sein.

+0

Kompilieren wirklich? Ist das 'this' in' newAlertDialog.Builder (this) 'die Instanz von Runnable? – lelloman

+0

Versuchen Sie, in Aktivität Alarm anzuzeigen. RunOnUiThread –

+0

@lelloman ja. Dies kompiliert nicht –

Antwort

1

Das Problem Ihres Codes ist, dass Sie versuchen, den Dialog nicht aus dem UI-Thread zu zeigen.

, wenn alles, was Sie brauchen, um die Anzeige des Dialogs um 10 Sekunden verzögert ist, und das wäre es, können Sie eine Handler

private final Handler handler = new Handler(); 
private final Runnable showDialogRunnable = new Runnable() { 
    @Override 
    public void run() { 
     new AlertDialog.Builder(MainActivity.this) 
       .setTitle("test") 
       .setMessage("lorep") 
       .setPositiveButton("OK", new DialogInterface.OnClickListener() { 
        public void onClick(DialogInterface dialog, int id) { 
         Log.i("app", "ok clicked"); 
        } 
       }) 
       .setIcon(android.R.drawable.ic_dialog_alert) 
       .create() 
       .show(); 
    } 
}; 

verwenden und per Post

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    handler.postDelayed(showDialogRunnable, 10000); 
... 

, wenn Sie die geplante Ausführung abbrechen möchten, können Sie anrufen

handler.removeCallbacks(showDialogRunnable); 

die Sache ist, wenn Sie nicht p die Handler mit Verwendung ass Looper im Konstruktor, die Looper mit den Thread verbunden ist, wo der Konstruktor in diesem Fall wird es wäre der UI-Thread

genannt, sein Update

, wenn Sie Ihre Aktivität halten Reiniger, könnten Sie eine andere Klasse, die das Runnable implementiert, zum Beispiel

public class AlertDialogShower implements Runnable { 
    private Context context; 

    public AlertDialogShower(Context context){ 
     this.context = context; 
    } 

    @Override 
    public void run() { 
     new AlertDialog.Builder(context) 
       .setTitle("test") 
       .setMessage("lorep") 
       .setPositiveButton("OK", new DialogInterface.OnClickListener() { 
        public void onClick(DialogInterface dialog, int id) { 
         Log.i("app", "ok clicked"); 
        } 
       }) 
       .setIcon(android.R.drawable.ic_dialog_alert) 
       .create() 
       .show(); 
    } 
} 

und es dann in Ihrer Tätigkeit instanziiert

private final Runnable showDialogRunnable = new AlertDialogShower(this); 
+0

Wie könnte ich die 'AlertDialog' Definition in seiner eigenen Klasse extrahieren? Ich kann dort 'MainActivity.this' nicht nennen ... – membersound

+0

kann man MainActivity.this von dort verwenden, handler und showDialogRunnable sind Felder der MainActivity Klasse – lelloman

+0

Ja, aber was ist, wenn ich meine' MainActivity' Klasse sauber halten und '' verschieben will showDialogRunnable '-Feld außerhalb dieser Klasse, sowie der Alarmdialog Builder? Abgesehen davon funktioniert der Code wie erwartet, danke! – membersound

1
private void initAlert() { 
    final ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1); 
    executor.schedule(new Runnable() { 
     @Override 
     public void run() { 
      Log.i("app", "scheduled alert"); 
      YourActivity.this.runOnUiThread(new Runnable() { 
       @Override 
       public void run() { 
        new AlertDialog.Builder(this) 
          .setTitle("test") 
          .setMessage("lorep") 
          .setPositiveButton("OK", new DialogInterface.OnClickListener() { 
           public void onClick(DialogInterface dialog, int id) { 
            Log.i("app", "ok clicked"); 
           } 
          }) 
          .setIcon(android.R.drawable.ic_dialog_alert) 
          .create() 
          .show(); 
       } 
      }); 

     } 
    }, 10, TimeUnit.SECONDS); 
} 
+0

Hm, ein "Runnable" innerhalb eines 'Runnable' innerhalb eines Schedulers zu wickeln, nur um eine asynchrone Warnung anzuzeigen, fühlt sich irgendwie komisch an. Obwohl es funktioniert. – membersound

+0

Es ist der einfachste Weg, Alarm in diesem Fall zu zeigen –

+0

Dies ist die Lösung, Sie können immer die Runnable als ein Feld der Aktivität zu erklären – lelloman

Verwandte Themen