如何在 Android Studio 中的 for 循环内实现延迟

How to implement a delay inside a for loop in Android Studio

我需要在 Android Studio 中的 for 循环 中实现延迟,在循环中我有一个发送帧序列的代码,这些帧必须每个延迟 200 毫秒发送,我在没有使用 200 毫秒延迟的情况下完成了测试并且代码运行正常,但是没有延迟,我的错误可能是什么?。 这是我的代码:

Integer i,  nroTrama;
nroTrama = 10;

final Handler delay2 = new Handler();
for (i = 0; i < nroTrama; i++) {
delay2.postDelayed(new Runnable() {
    @Override
    public void run() {
        bufferSendTrama = myBuffer.substring((20 * i), (i * 20 + 20));
        send(bufferSendTrama.toString());
        Log.e("DEBUG-->", bufferSendTrama);
    }
  }, 200);
}

你真的应该在这里使用 ThreadHandler。这是一个例子:

public int nroTrama = 10; //Global variable
public Handler delay2; //Global variable


// Inside a method
delay2 = new Handler(Looper.getMainLooper()) {
    @Override
    public void handleMessage(Message msg)
    {
        switch(msg.what) {
            case 1: // Do something like updating the UI, etc.
                Log.i("DEBUG-->", "String: " + (String) msg.obj);
            break;
            default: //Do something...
            break;
        }
        //Return the Message instance to the global pool.
        msg.recycle();
    }
};

Thread myThread = new Thread(new Runnable() {
    @Override
    public void run()
    {
        for(int i = 0; i < nroTrama; i++) {
            try {
                Thread.sleep(200L); //Delay
                bufferSendTrama = myBuffer.substring((20 * i), (i * 20 + 20));
                //send(bufferSendTrama.toString());
                final Message msg = Message.obtain();
                //If it does not work, try creating a new Message instance instead.
                //e.g. final Message msg = new Message();
                msg.what = 1;
                msg.obj = bufferSendTrama.toString();
                delay2.sendMessage(msg);
                Log.e("DEBUG-->", bufferSendTrama);
            } catch(InterruptedException e) {}
        }
    }
});

//Start the thread.
myThread.start();

[编辑]

这是另一种更好的方法。这避免了为相同的重复任务创建新的 Handler/Thread,也避免了内存泄漏。

//#####################
//#    INNER CLASS    #
//#####################

private static final class Timer implements Runnable
{
    private final WeakReference<Handler> handler;
    private final Thread thread;
    private boolean isAlive;
    private boolean state;

    public final Timer(final Handler handler)
    {
        this.handler = new WeakReference<Handler>(handler);
        thread = new Thread(this);
        isAlive = true;
        thread.setPriority(Thread.NORM_PRIORITY);
        thread.start();
    }

    @Override
    public final void run()
    {
        while(isAlive) {
            try {
                synchronized(this) {
                    while(!state) this.wait();
                }
                Thread.sleep(200L); //Delay
                final Handler hanRef = handler.get();
                if(hanRef == null) {
                    isAlive = false;
                    handler.clear();
                    break;
                }
                final Message msg = Message.obtain();
                msg.what = 0;
                hanRef.sendMessageAtTime(msg, SystemClock.uptimeMillis());
            } catch(final InterruptedException e) {}
        }
    }

    public final synchronized void resume()
    {
        if(isAlive) {
            state = true;
            this.notify();
        }
    }

    public final void suspend()
    {
        state = false;
        thread.interrupt();
    }

    public final void stop()
    {
        isAlive = false; // In case interrupt() does nothing (Thread was not in sleep nor wait mode).
        thread.interrupt();
        handler.clear();
    }
}

//#####################
//#    INNER CLASS    #
//#####################

private static final class UIHandler extends Handler
{
    private final WeakReference<MainActivity> myActivity;

    public final UIHandler(final MainActivity myActivity)
    {
        super(Looper.getMainLooper());
        this.myActivity = new WeakReference<MainActivity>(myActivity);
    }

    @Override
    public final void handleMessage(final Message msg)
    {
        final MainActivity referent = myActivity.get();
        if(referent != null) {
            switch(msg.what) {
                // onUpdate() and onImageLoaded() need to be implemented in parent class.
                // onUpdate --> refresh UI for a example.
                case 0: referent.onUpdate(); break;
                // onImageLoaded --> Load image from assets folder for a example.
                case 1: referent.onImageLoaded(msg.arg1, (Bitmap)msg.obj); break;
            }
        }
    }
}

稍后在 class 的某处初始化这些变量。这应该只做一次。

handler = new UIHandler(this);
timer = new Timer(handler);

启动、暂停或停止线程。

//To start the thread for the first time or after calling timer.suspend().
timer.resume();
//To pause/suspend the thread for later use.
timer.suspend();
//To stop/kill the thread and never want to call it again.
//Make sure to call this method somehow, somewhere to kill the thread
//Or else the thread will never actually killed.
timer.stop();