0

我正在尝试在我的应用程序中实现超时行为。在超时实际发生前 5 秒还应该有一个警告 (alertdialog)。

我想使用 ScheduledExecutorService 来做到这一点。

到目前为止,这是我的相关代码:

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

以及处理超时行为的方法:

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

在 onCreate() 中调用 setTimeout,因此应用程序应该在启动后 5 秒断开连接。

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

这是我面临的问题:

  • 如果“setTimeout”中调用的runnable设置为“disconnectRunnable”,它工作正常,应用程序在5s后断开连接。

  • 当我将其设置为“timeoutRunnable”时,不会显示 alertDialog + 应用程序永远不会断开连接,即使应该在“showTimeoutAlertDialog”中 5 秒后调用“disconnectRunnable”!?

我认为 ScheduledExecutorService 在这里出了问题,但我找不到解决方案。

感谢您的帮助 :)

4

1 回答 1

0

您试图不从 UI 线程显示 AlertDialog,因此它永远不会工作 该方法showTimeoutAlertDialog()是从在计划线程池中创建的工作线程调用的。您可以将Handler其用于您的目的:

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);
    }
}
于 2013-05-14T10:50:21.857 回答