【发布时间】:2017-03-27 15:06:37
【问题描述】:
我正在尝试在 android studio 中制作一个简单的游戏,我需要能够延迟某些事件。
我开始使用谷歌搜索,发现Timer 和TimerTask 似乎是一个不错的选择。但是,如果我的活动调用onPause 没有Timer.pause,我必须取消整个活动。
因此,我决定继续创建自己的类来为我处理事件并支持暂停。
我创建了一个简单的类 (EventHandler),它根据用户命令创建“事件”,并每 10 毫秒循环一次事件的 ArrayList 以查看 System.currentTimeMillis >= eventFinishedTime。如果事件完成,则调用一个接口方法,并将事件从 ArrayList 中移除。
但现在我遇到了一个新问题。
EventHandler 在事件结束时调用接口方法 (onFinished),所以我不能使用在 onFinished 中未声明为 final 的变量。我能找到的唯一解决方法是在每次我想延迟事件时创建一个新方法,这似乎是一种不好的做法。
所以我的问题是,最好的方法是什么,或者你会怎么做?
如果您想查看我的代码,请随时询问,只需指定哪一部分即可:) 也请随时询问更多信息...我总结了很多,并且非常愿意尝试通过示例进一步解释。
谢谢!
这里是 EventHandler.class(我没有包含导入...滚动到底部查看调用接口方法的位置):
public class EventHandler extends Thread {
//Constants
final String TAG = "EventHandler";
final long WAIT_TIME = 10;
public ArrayList<Event> events = new ArrayList<>(); //Every WAIT_TIME the run() funtion cycles through this list and checks if any events are complete
public boolean runChecks = true; //If true, the run() function goes (It's only false while the DoDayActivity tells it to pause
public long pauseStartTime; //This value tags the System.currentTimeMillis() @pauseCheck
public long totalPausedTime = 0; //This value contains how long the EventHandler was paused
Activity activity;
public EventHandler(Activity activity) {
this.activity = activity;
}
public void run() {
//checking the listeners
while (true) {
if (runChecks) {//Making sure the timer isn't paused
checkListeners();
}
try {
Thread.sleep(WAIT_TIME); //Yes I am using Thread.sleep(), kill me
} catch (Exception ignore) {
}
}
}
public interface OnEventListener {
void onFinished();
}
public void createEvent(String name, long milliseconds, OnEventListener eventListener) {//This is how an event is created, see the private Event class below
new Event(this, name, milliseconds, eventListener);
}
public void checkListeners() {
for (Event event : events) {
event.amIFinished();//A method that checks if the event has reached its end time
}
}
public void pauseCheck() { //"Pauses" the timer (Probably not the best way, but it is simple and does what I need it to
runChecks = false;
pauseStartTime = System.currentTimeMillis();
}
public void resumeCheck() {//Resumes the timer by adding the amount of time the EventHandler was paused for to the end if each event
try {
if ((pauseStartTime > 99999999)) {//For some reason, when an activity is created, onResume is called, so I added this in there to prevent glicthes
totalPausedTime = System.currentTimeMillis() - pauseStartTime;
Log.d(TAG, "Resuming, adding " + String.valueOf(totalPausedTime) + " milliseconds to each event");
for (Event e : events) {
e.end += totalPausedTime;
}
}
} catch (Exception e) {
Log.w(TAG, "During resume, EventHandler tried to add time to each of the events, but couldn't!");
e.printStackTrace();
}
runChecks = true;
}
private class Event { //Here is the class for the event
public long start;
public long end;
OnEventListener listener;
EventHandler parent;
String name;
public Event(EventHandler parent, String name, long milliseconds, OnEventListener listener) {
start = System.currentTimeMillis();
end = start + milliseconds;
this.listener = listener;
this.parent = parent;
this.name = name;
//Adding itself to the ArrayList
parent.events.add(this);
}
public void amIFinished() {//Method that checks if the event is completed
if (System.currentTimeMillis() >= end) {//Removes itself from the arraylist and calls onFinished
Log.d(TAG, "Completed " + name);
parent.events.remove(this);
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
listener.onFinished(); //This is where the interface method is called!
}
});
}
}
}
}
这是我尝试使用它的地方(这只是一个使用 int x 的示例):
int x = 0;
eventHandler = new EventHandler(this);
eventHandler.start();
eventHandler.createEvent("Change X Value", 800, new EventHandler.OnEventListener() {
@Override
public void onFinished() {
//x is not declared final so it will not work
x = 5;
}
});
【问题讨论】:
-
你不应该在当前程序中使用
ArrayList。查看替代课程CopyOnWriteArrayLis、ConcurrentLinkedQueue、...
标签: java android timer timertask