Question

I'm trying to implement a timeout behaviour in my app. There should also be a warning (alertdialog) 5 seconds before the timeout actually happens.

I want to use a ScheduledExecutorService to do so.

Here is my relevant Code so far :

private final Context context = this;

private ScheduledExecutorService sExService = Executors.newScheduledThreadPool(2);

private RunnableScheduledFuture<?> sFutureTimeout;
private RunnableScheduledFuture<?> sFutureDisconnect;

private final Runnable timeoutRunnable = new Runnable(){
    @Override
    public void run() {     
        showTimeoutAlertDialog();
    }   
};
private final Runnable disconnectRunnable = new Runnable(){
    @Override
    public void run() {
        disconnect();   
    }   
};

and the methods to handle the timeout behaviour :

private void setTimeout(){
    sFutureTimeout = (RunnableScheduledFuture<?>) sExService.schedule(timeoutRunnable, 5, TimeUnit.SECONDS);
}

setTimeout is called in onCreate(), so the app should disconnect 5s after launch.

private void showTimeoutAlertDialog(){

    new AlertDialog.Builder(context)
            .setTitle("Disconnect in 5s")
            .setCancelable(false)
            .setPositiveButton("Abort",
                    new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int id) {
                            sFutureDisconnect.cancel(false);
                            setTimeout();
                        }
                    }).show();  

    sFutureDisconnect = (RunnableScheduledFuture<?>) sExService.schedule(disconnectRunnable, 5, TimeUnit.SECONDS);
}

Here's the problems I am facing :

  • if the runnable called in "setTimeout" is set to 'disconnectRunnable', it works fine, the app disconnects after 5s.

  • when I set it to 'timeoutRunnable', the alertDialog is not shown + the app never disconnects even though 'disconnectRunnable' should be called after 5s in "showTimeoutAlertDialog"!?

I think something with the ScheduledExecutorService went wrong here, but I can't find a solution.

Thank you for your help :)

Was it helpful?

Solution

You are trying to show AlertDialog not from the UI thread so it will never work The method showTimeoutAlertDialog() is called from the worker thread created in the scheduled thread pool. You can use Handler for your purpose:

public class MyActivity extends Activity {

    private final Context context = this;

    private static Handler mHandler = new Handler();

    private final Runnable timeoutRunnable = new Runnable(){
        @Override
        public void run() {
            showTimeoutAlertDialog();
        }
    };
    private final Runnable disconnectRunnable = new Runnable(){
        @Override
        public void run() {
            disconnect();
        }
    };

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

    private void disconnect() {
        Log.e("MyActivity", "Disconnected");
    }

    private void setTimeout(){
        mHandler.postDelayed(timeoutRunnable, 5000);
    }

    private void showTimeoutAlertDialog(){

        new AlertDialog.Builder(context)
                .setTitle("Disconnect in 5s")
                .setCancelable(false)
                .setPositiveButton("Abort",
                        new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int id) {
                                mHandler.removeCallbacks(disconnectRunnable);
                                setTimeout();
                            }
                        }).show();

        mHandler.postDelayed(disconnectRunnable, 5000);
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top