我正在尝试在Android应用中制作循环,这是由按钮点击触发的。 在阅读有关在SO(for example here)上进行循环/延迟的提示后,我决定使用消息处理程序方法而不是Runnable。
在下面的代码中,执行toastLoop()并打印“以x开始”秒。 但是,该消息似乎没有发布该延迟。 或者,邮件已发布但处理程序未收到该邮件。 我是新手,我可能在某处犯了一个愚蠢的错误。 我在下面的代码中缺少什么?或者这段代码完全是愚蠢的?
package com.example.testapp;
import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.NavUtils;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;
public class ExecActivity extends FragmentActivity {
static Context context = null;
String LOG_TAG = "FTR";
static boolean test_status = false;
ToastLoop toast_loop;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_exec);
// Show the Up button in the action bar.
setupActionBar();
}
/**
* Set up the {@link android.app.ActionBar}, if the API is available.
*/
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
private void setupActionBar() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
getActionBar().setDisplayHomeAsUpEnabled(true);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.exec, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// This ID represents the Home or Up button. In the case of this
// activity, the Up button is shown. Use NavUtils to allow users
// to navigate up one level in the application structure. For
// more details, see the Navigation pattern on Android Design:
//
// http://developer.android.com/design/patterns/navigation.html#up-vs-back
//
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
class ToastLoop {
private final int loop_max_duration = 60; // in seconds
final int TOAST = 1;
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
Log.i(LOG_TAG, "Handler(): msg: " + msg.what);
switch (msg.what) {
case TOAST:
Toast.makeText( ExecActivity.this, "Doing my thing", Toast.LENGTH_SHORT).show();
if ( test_status) { // test is still running
toastLoop();
}
break;
default:
Toast.makeText(ExecActivity.this, "Unhandled", Toast.LENGTH_SHORT).show();
break;
}
}
};
public boolean toastLoop() {
if ( test_status) { // test is still running
long curr_time_milli = System.currentTimeMillis();
long window_position_sec = (long)( ((long)(curr_time_milli/1000))/loop_max_duration); // fraction discarded
long loop_start_time_sec = (window_position_sec + 1 ) * loop_max_duration;
long actual_start_time_milli = loop_start_time_sec * 1000;
Log.i(LOG_TAG, "toastLoop(): starting in " + ((actual_start_time_milli - curr_time_milli)/1000) );
Message msg = handler.obtainMessage( TOAST);
handler.sendMessageAtTime( msg, actual_start_time_milli );
return true;
}
return false;
}
}
public boolean beginTest( View view) {
Log.i(LOG_TAG, "in beginTest()");
test_status = true;
toast_loop = new ToastLoop();
toast_loop.toastLoop();
return true;
}
public boolean endTest( View view) {
Log.i(LOG_TAG, "in endTest()");
test_status = false;
return true;
}
}