Я делаю игру для Android с использованием Java.Когда пользователь нажимает кнопку, которая запускает поток, который выполняет кучу бросков и прыжков, которые продолжаются некоторое время с помощью sleep (20) и this.invalidate (), чтобы показать, что это происходит в режиме реального времени.Я также пытаюсь представить поток демона, который будет отвечать за анимацию.Я заметил, что с введением второго потока что-то в потоке пользовательского интерфейса разрывается во время выполнения программы.Как скоро он сломается, зависит от ряда факторов.Но как только он ломается, можно наблюдать следующие вещи:
- код внутри activity.runOnUiThread (new Runnable () {прекращает выполнение.
при переключении на другоеприложение и обратно, панель действий и панель уведомлений больше не исчезают, поэтому выполнение этого кода также прекращается:
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
закрытие приложения и его повторный запуск приводит к его зависанию с пробеломсерый экран.
Однако все равно работает следующее: * анимации по-прежнему отображаются правильно * выстрелы и отскоки по-прежнему работают и отображаются правильно без задержек. * Уничтожение приложения и его повторный запуск временно исправляет его.
Кажется, что следующие сценарии вызывают разрыв во время выполнения:
введение дополнительного потока анимации.
public void animThread () {
animThread = new Thread ( new Runnable( ) {
public void run( )
{
while(true)
{
animation();
}
}
} );
animThread.setDaemon(true);
animThread.setPriority(3);
animThread.start();
}
private void animation () {if (powerups.isEmpty () == false) {synchronized (powerups) {for (PowerUp pw: powerups) {if (pw.isActivated ()== false) pw.rotate ();}}
}
this.invalidate();
try {
if(Units.animPause==true)
{
synchronized (Units.animSync) {
while (Units.animPause) {
try {
Units.animSync.wait();
} catch (InterruptedException e) {
System.out.println("interrupt");
}
}
}
}
else {
Thread.sleep(20); //delay before next cycle
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Приоритет, демон, оператор if, который проверяет, должен ли поток ждать, не имеет значения.Проблема произойдет без единого вызова activity.runOnUiThread.
Если я вызываю activity.runOnUiThread слишком часто из темы съемки.Та же проблема произойдет даже без анимации.Я даже заменил весь код стрельбы этим, чтобы проверить:
public void testshoot () {// int count = 0;while (counter <100) {</p>
counter++;
System.out.println("counter: " + counter);
if(counter % 2 == 0)
{
gw.activity.runOnUiThread(new Runnable() {
@Override
public void run() {
System.out.println("game over run");
System.out.println("counter: 1: " + counter);
gw.activity.findViewById(R.id.GameOver).setVisibility(View.VISIBLE);
((TextView)gw.activity.findViewById(R.id.Score)).setText("Your Score: " + counter);
System.out.println("game over run1");
}
});
}
try {
if(Units.isPaused==true)
{
synchronized (Units.pauseSync) {
while (Units.isPaused) {
try {
Units.pauseSync.wait();
} catch (InterruptedException e) {
System.out.println("interrupt");
}
}
}
}
else {
Thread.sleep(20); //delay before next cycle
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
counter=0;
}
Что произойдет, если на экране отобразится меню, и счетчик начнет корректно увеличиваться, пока не произойдетпросто перестает обновляться, потому что код внутри runOnUiThread перестал выполняться, потому что что-то сломалось.Похоже, что повторение звонка откладывает или даже устраняет проблему.Например, если (счетчик% 10 == 0)
Если я объединю поток анимации из пункта 1 с вызовом runOnUiThread из пункта 2, проблема появится раньше.
Мой onPause и onResume:
public void onPause()
{
if(Units.isPaused == false)
{
Units.adHocPause=true;
synchronized (Units.pauseSync) {
Units.isPaused = true;
}
}
synchronized (Units.animSync) {
Units.animPause = true;
}
super.onPause();
}
@Override
public void onResume(){
//System.out.println("is paused: " + Units.isPaused);
if(Units.adHocPause==true)
{
Units.adHocPause=false;
synchronized (Units.pauseSync) {
Units.isPaused = false;
Units.pauseSync.notifyAll();
}
}
else
{
View menu = findViewById(R.id.Menu);
menu.setVisibility(View.VISIBLE);
synchronized (Units.pauseSync) {
Units.isPaused = true;
}
}
synchronized (Units.animSync) {
Units.animPause = false;
Units.animSync.notifyAll();
}
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
super.onResume();
}
Я хочу понять, что именно происходит, когда что-то ломается в моем приложении во время выполнения, что ломается, что вызывает это и какмогу ли я избежать этого.Я заинтересован в том, чтобы сценарий 1 работал.Я включил сценарии 2 и 3, потому что, надеюсь, они дают понять, что ломается.