Reputation: 86747
I want to set up a scheduler and show a popup after a predefined time.
In the following example, the Log "scheduled alert" is printed once, but the alert dialog is never shown.
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);
}
}
The initialization is inside the main activity.
Why is the dialog not shown?
If I add a button to my view, and link the alert dialog explicit to that button click, it works. So the dialog code in general should be fine.
Upvotes: 0
Views: 300
Reputation: 14173
the problem of your code is that you're trying to show the Dialog not from the UI thread.
if all you need is to delay the display of the dialog by 10 seconds, and that would be it, you can use a 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();
}
};
and post it
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
handler.postDelayed(showDialogRunnable, 10000);
...
if you want to cancel the scheduled execution you can call
handler.removeCallbacks(showDialogRunnable);
the thing is, if you don't pass Looper
in the constuctor, the Handler
with use the Looper
associated with the Thread
where the constructor is being called, in this case it would be the UI thread
update
if you want to keep your activity cleaner, you could create another class that implements that Runnable, for example
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();
}
}
and then instantiate it in your activity
private final Runnable showDialogRunnable = new AlertDialogShower(this);
Upvotes: 1
Reputation: 1000
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);
}
Upvotes: 1