Изначально весь экран будет отображаться, карты и все остальное, но никогда не будет обновляться снова, кроме как до тех пор, пока поток выдает исключение IllegalThreadStateException. (переведя приложение в фоновый режим, нажав кнопку «Домой» или кнопку «Недавние приложения»).
Большая часть моего кода была скопирована из учебных пособий в попытке заставить его работать в состояние, в котором я могу его протестировать.
Я новичок в Android API и до сих пор абсолютно ненавижу его. Пожалуйста, скажите мне, если я вообще сделал что-нибудь глупое.
Целевой API — 34, минимальное значение — 21. Мое устройство — физическое устройство; TCL 10 Pro, 6,47 дюйма, API 30. Однако об API ничего не говорится.
Вот мой собственный источник темы:
Код: Выделить всё
public class MainThread extends Thread {
private final SurfaceHolder surfaceHolder;
private final GameBoard boardView;
private boolean running;
public static Canvas canvas;
public MainThread(SurfaceHolder surfaceHolder, GameBoard boardView) {
super();
this.surfaceHolder = surfaceHolder;
this.boardView = boardView;
}
public void setRunning(boolean isRunning) {
running = isRunning;
}
@Override
public void run() {
while (running) {
canvas = null;
try {
canvas = this.surfaceHolder.lockCanvas();
synchronized(surfaceHolder) {
this.boardView.update();
this.boardView.draw(canvas);
}
} catch (Exception e) {
System.out.println("CATCH");
} finally {
if (canvas != null) {
try {
surfaceHolder.unlockCanvasAndPost(canvas);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
}
Код: Выделить всё
public class GameBoard extends SurfaceView implements SurfaceHolder.Callback {
BaseSingleDeckGameObject gameObject;
private final MainThread thread;
// shorter constructors were here
public GameBoard(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(attrs, defStyle); //shorter constructors set these to (null, 0)
getHolder().addCallback(this);
thread = new MainThread(getHolder(), this);
setFocusable(true);
gameObject = new KlondikeGameObject(0, context);
}
public void update() {
gameObject.updateGame();
}
private void init(AttributeSet attrs, int defStyle) {
this.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
| 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
);
}
public boolean onTouchEvent(MotionEvent motion) {
gameObject.doTouchEvent(motion); //this just prints out the information from MotionEvent to console, and sets 2 variables.
//performClick
return true;
}
// performClick is here
@Override
public void draw(Canvas canvas) {
super.draw(canvas);
if (canvas != null) {
gameObject.drawGame(canvas);
}
}
@Override
public void surfaceCreated(@NonNull SurfaceHolder holder) {
thread.setRunning(true);
thread.start();
}
@Override
public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
boolean retry = true;
while (retry) {
try {
thread.setRunning(false);
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
retry = false;
}
}
}
Код: Выделить всё
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle bundle) {
super.onCreate(bundle);
this.setContentView(R.layout.game_screen);
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder(StrictMode.getVmPolicy())
.detectLeakedClosableObjects()
.build());
}
@Override
protected void onResume() {
super.onResume();
}
}
Вот какая ошибка:
Код: Выделить всё
Exception configuring surface
java.lang.IllegalThreadStateException
at java.lang.Thread.start(Thread.java:872)
at com.severinghams.homebrewsolitaire.GameBoard.surfaceCreated(GameBoard.java:113)
at android.view.SurfaceView.updateSurface(SurfaceView.java:1208)
at android.view.SurfaceView.setWindowStopped(SurfaceView.java:294)
at android.view.SurfaceView.surfaceCreated(SurfaceView.java:1699)
at android.view.ViewRootImpl.notifySurfaceCreated(ViewRootImpl.java:1796)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2798)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:2008)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:8343)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1136)
at android.view.Choreographer.doCallbacks(Choreographer.java:958)
at android.view.Choreographer.doFrame(Choreographer.java:882)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1121)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:236)
at android.app.ActivityThread.main(ActivityThread.java:7904)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:952)
onTouchEvent вызывает метод моего игрового класса, который устанавливает переменные позиции внутри игрового класса. Затем метод draw() вызывает drawGame() внутри моего игрового класса, который должен нарисовать квадрат в указанном месте, но не обновляет экран.
Белый квадрат перемещается только после возникновения исключения потока, но только один раз. Он обновится снова, когда попытается создать снова.
Приношу извинения за мое невероятно неестественное и запутанное объяснение проблемы, а также явное отсутствие краткости. Мои попытки сократить мое объяснение делают его еще более бессвязным.
Буду признателен за любую помощь! Я действительно в тупике!
Подробнее здесь: https://stackoverflow.com/questions/784 ... not-update