Я пытаюсь сделать простую игру в студии Android, и мне нужно уметь откладывать определенные события.Каков наилучший способ обработки отложенных событий в Java
Я начал с выполнения поиска в Интернете и обнаружил, что Timer
с TimerTask
представляется довольно хорошим вариантом. Однако, если моя деятельность вызывает , нет Timer.pause
, я должен отменить все это.
Итак, я решил продолжить свой собственный класс, который обрабатывал бы события для меня и поддерживал бы паузу.
Я сделал простой класс (EventHandler
), который создает «событие (ы)» по команде пользователей, а также циклы через ArrayList событий каждые 10 миллисекунд, чтобы увидеть, если System.currentTimeMillis
> = eventFinishedTime
. Если событие завершено, он вызывает метод inteface, и событие удаляется из ArrayList.
Но теперь я столкнулся с новой проблемой.
EventHandler
вызывает метод интерфейса (onFinished
), когда событие завершено, поэтому я не могу использовать переменную, которая не объявлена окончательной в onFinished
. Единственный способ обойти это, что я могу найти, - это сделать новый метод для каждого случая, когда я хочу задержать событие, которое кажется плохим.
Так что мой вопрос: Каков наилучший способ сделать это или как вы это сделаете?
Не стесняйтесь спрашивать, хотите ли вы увидеть мой код, просто укажите, какая часть :) Также не стесняйтесь спрашивать о дополнительной информации ... Я подвел итог довольно много, и я более чем готов попробовать объясните далее, с примерами.
Спасибо!
Вот 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 х):
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;
}
});
Обновлено сообщение – Pythogen
Вы не должны использовать 'ArrayList' в программе cuncurrent. См. Альтернативные классы 'CopyOnWriteArrayLis',' ConcurrentLinkedQueue', ... –