I am trying to make an android game.
I have a game class that extends activity and handles all the user input. Then I have a missionView class that extends view and
For games I would actually use a lower level access to graphics. The LunarLander from Google is an excellent example for that. Basically You need to do two things:
replace view.invalidate() with custom method repaint() that would contain
private void repaint() {
Canvas c = null;
try {
c = surfaceHolder.lockCanvas();
paint(c);
} finally {
if (c != null) {
surfaceHolder.unlockCanvasAndPost(c);
}
}
}
Paint method will contain what You have in View.onDraw at the moment
I've faced with the same problem in my application.
In my case I was trying to call invalidate()
from the [doInBackground()][1]
method of the [AsyncTask][2]
.
The problem was solved by moving invalidate()
to [onProgressUpdate()][3]
method of AsyncTask
. I.e. you cannot update UI from the doInBackground()
method of AsyncTask
. It is mentioned in Android docs, but it is so easy to forget about it... so, don't forget to check it.
I could be late but I'm sure this would work for you.
I did this with Kotlin. You can modify according to Java.
Put your code inside runOnUIThread()
.
Sample code:
activity?.runOnUiThread {
// Your code goes here
}
Hope this helps.
View#invalidate tells the system to redraw (via onDraw) the view as soon as the main thread goes idle. That is, calling invalidate schedules your view to be redrawn after all other immediate work has finished. If the code in your Game class is being called from the main thread and it puts that thread to sleep, you aren't just pausing rendering, you are pausing input processing all together (usually a bad idea). As a rule of thumb, never sleep a thread that you didn't spawn yourself unless you know what you are doing.
If you'd like to have your game logic periodically delay using Thread#sleep then run it in a separate thread and use view.postInvalidate() to signal the main thread to wake up and call onDraw.