如何在 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);
}
你真的应该在这里使用 Thread
和 Handler
。这是一个例子:
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();
我需要在 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);
}
你真的应该在这里使用 Thread
和 Handler
。这是一个例子:
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();