SurfaceView, Black screen after reopening application - java

I have an activity which calls a class that extends a SurfaceView and implement Runnable
and sets the contentView() of the activity class to the instance of the surfaceview class. After minimizing the activity, i pause and destroy the thread:
public void pause(){
running = false;
while(true){
try{
renderThread.join();
break;
}catch(InterruptedException e){
//retry
}
}
}
when the activity resumes i recreate the thread:
public void resume(){
running = true;
renderThread = new Thread(this);
renderThread.start();
}
note that those are called within the onPause() and onResume() activity methods.
public void run(){
while(running){//thred loop
if(!holder.getSurface().isValid())
continue;
if(puzzleDrawn!=true) {
canvas = holder.lockCanvas();
drawPuzzle(canvas);
holder.unlockCanvasAndPost(canvas);
}
}
}
public void drawPuzzle(canvas){
//draws on canvas
}
when i try to reopen the application i see a black screen.
I need the drawPuzzle(canvas) method to be drawn just once.
any tips?
if u need more info let me know!
Thanks

In your pause method you are calling break in the wrong spot. What you should do is call break at the end of the while loop after the try and catch brackets and set your thread to null again outside the scope of the loop and just before you end your pause method, like this:
public void pause(){
running = false;
while(true){
try{
renderThread.join();
}catch(InterruptedException e){
//retry
}
break;
}
renderThread = null;
}

Related

Swing wait() and notify() on JDialog, the dialog does not show its components

I have a mouse listener that gets invoked when I move the mouse in the application window.
In the MouseEntered method, I invoke a ThreadB as such:
#Override
public synchronized void mouseEntered(MouseEvent e) {
..
ThreadB b = new ThreadB();
b.start();
System.out.println("Before Sync!!!!!!!");
synchronized(b) {
try{
System.out.println("Waiting for b to complete...");
b.wait();
}catch(InterruptedException ex){
ex.printStackTrace();
}
}
System.out.println("After Sync!!!!!!!");
}
class ThreadB extends Thread {
#Override
public void run(){
synchronized(this){
int dialogResult = JOptionPane.showConfirmDialog(null, "Loading process is in progress. Do you want to stop the process?", "Loading Accounts", JOptionPane.YES_NO_OPTION);
if (dialogResult == 0) {
System.out.println("Yes is chosen!!!!");
}else {
System.out.println("No is chosen!!!!");
}
System.out.println("before NOTIFY!!!!!!!");
notify();
}
}
}
The loading process is stopped as expected, but the dialog does not gets painted meaning it does not show its components.
Your help is much appreciated.
Thanks a lot
Regards
You can't do GUI things anywhere in your code, except if that code runs in the Event Dispatch Thread (the EDT). You're running it on a thread of your own creation; not allowed. Use e.g. SwingUtilities.invokeLater, or the SwingWorker system.

Count integer with Thread in Activity and update Canvas in View

I'm developing my first android game without xml files for layouts in eclipse. This is calling MyGameView.class(extends View) from MyGameActivity.class(extends View implements OnTouchListener)
MyGameView myView;
myView = new MyGameView(this);
myView.setOnTouchListener(this);
setContentView(myView);
Everytime, I touch (MotionEvent.ACTION_DOWN), I update the Canvas in MyGameView.class with the following code. This is the code I use to update MyGameView.class from MyGameActivity.class.
myView.invalidate();
Yes it works!But I got a serious problem now.I need to move Canvas in MyGameView.class by every 0.3 second.I use Thread to update but it forced stop!!!! I tried again and again and again! I failed!
public void runtime() {
i = 0;
Thread timer = new Thread(new Runnable() {
#Override
public void run() {
while (i<1500) {
try {
Thread.sleep(300);
}
catch (InterruptedException e) {
e.printStackTrace();
}
finally {
if (right) {
i++;
//This is static int a from MyGameView.
MyGameView.a += 2;
myView.invalidate();
}
else {
i = 1500;
}
}
}
}
});
timer.start();
}
Updating Static int or boolean to MyGameView.class from MyGameActivity.class with myView.invaldate(); is working. But I can't control it with Thread! Is there something wrong with my Thread running code?
It's probably up to Thread because I can move +2 along X-axis to right everytime I press (MotionEvent.ACTION_DOWN).
//I can Move with this code but not with Thread!
case MotionEvent.ACTION_DOWN:
MyGameView.a += 2;
myView.invalidate();
break;
With Thread, it stops! Please give me a solution for this! In other words, I need to count with time without error and update canvas on every count!
Invalidate must be called from the UI thread. Try calling
postInvalidate()
instead.
See this for reference.

Game thread execution is not resuming properly in Android

I am developing a simple game that is running in its own thread. When I launch the app, everything works great. The thread is initialized, and the update() and render() functions are executed from the thread, which is great.
If I exit the app, the thread is paused. When I launch the app again, the thread resumes fine. (The update and render functions are executed). Again, this is great!
THE PROBLEM IS, I hit the power button to sleep the device. When I resume the app from this state, the render() function appears to work fine; it is drawing all of the elements (background, sprites, etc) exactly where they were before I hit the button. BUT: The sprites are no longer animated! After a bit of tracing and troubleshooting, I found out that although the "running" flag is set to TRUE, it seems like the "RUN" function is no longer running! (On an another note, I am confused why the RENDER function works, but the UPDATE function does not, unless the app is rendering the objects from some other method? Irregardless...)
I am working this problem from two possible angles; I am either missing something in the way Android manipulates my thread, OR would this have something to do with the fact that the member variables inside the objects have been reset...
Can someone please review the basic code I have posted below, and advise any suggestions on how to improve thread manipulation? I am an intelligent person, and I have read so many articles from different sources on the subject, and am more confused now more than ever! Am I on the right track here, or is there a more intelligent way of doing this? Do I really need a separate game thread, or can I run it using the device's main thread instead?
Thanks for your feedback!
public class GameThread extends Thread {
private boolean running=false;
private SurfaceHolder surfaceHolder;
private GameView gameView;
public GameThread(SurfaceHolder surfaceHolder, GameView gameView){
super();
this.surfaceHolder = surfaceHolder;
this.gameView = gameView;
}
#Override
public void run(){
Canvas canvas;
// THIS ONLY RUNS ONCE!
// WHEN I TURN THE POWER OFF AND BACK ON, THE RUN() METHOD DOES NOT RUN!
// ODDLY ENOUGH, IF I WERE TO EXIT THE APP, AND GO BACK IN, IT WORKS FINE!
// THE running FLAG SEEMS TO CHANGE PROPERLY WHEN PAUSING OR RESUMING (SEE gameView, BELOW).
while (running){
canvas = null;
try {
canvas = this.surfaceHolder.lockCanvas();
synchronized (surfaceHolder){
gameView.update();
gameView.render(canvas);
}
} finally {
if (canvas!=null)
surfaceHolder.unlockCanvasAndPost(canvas);
}
}
}
public void setRunning(boolean running){
this.running = running;
}
}
public class GameView extends SurfaceView implements SurfaceHolder.Callback {
private GameThread thread;
private GameScreen gameScreen;
public GameView(Context context) {
super(context);
gameScreen = new GameScreen(context);
setFocusable(true);
thread = new GameThread(getHolder(), this);
getHolder().addCallback(this);
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
thread = new GameThread(getHolder(), this);
thread.setRunning(true);
thread.start();
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
boolean retry = true;
while (retry){
try {
thread.join();
retry = false;
} catch (InterruptedException e){
// Do nothing; continue trying
}
}
}
public void render(Canvas canvas){
gameScreen.draw(canvas);
}
public void update(){
gameScreen.update();
}
#Override
public boolean onTouchEvent(MotionEvent event){
gameScreen.touch(event);
}
public void resume(){
// TODO: Resume events go here
thread.setRunning(true);
}
public void pause(){
// TODO: Pause events go here
thread.setRunning(false);
}
}
public class GameScreen {
public GameScreen(Context context){
// Initialize private variables here
}
public void draw(Canvas canvas){
// Draw events go here
}
public void update(){
// Update events go here
}
public void touch(MotionEvent event){
// Touch events go here
}
}
The update() method needs to be executed BEFORE trying to post the canvas. Still unsure why this is, but it works as intended now.
Canvas canvas = null;
while (running){
gameView.update();
try {
canvas = this.surfaceHolder.lockCanvas();
synchronized (surfaceHolder){
gameView.render(canvas);
}
} finally {
if (canvas!=null)
surfaceHolder.unlockCanvasAndPost(canvas);
}
}
}

How to update values while method is running - Java

So I have this really weird problem that I simply cannot understand why it doesn't work. I am building a strobe light as part of my app and have created a separate Strobelight class. When I call the turnOn method or update method, the intervals never are changed. I guess it would make it easier to explain using some code:
public class Strobelight{
private int delayOn, delayOff;
public void turnStrobeOn(){...}
public void update(int a_delayOn, int a_delayOff){
delayOn = a_delayOn;
delayOff = a_delayOff;
}
public void turnOn(int a_delayOn, int a_delayOff){
delayOn = a_delayOn;
delayOff = a_delayOff;
this.turnStrobeOn();
}
Depending on whether the strobe light is already on or not, one of these methods are called to change turn on the strobe light with the specified intervals or simply to change the intervals.
Instead of changing the intervals to something custom, the application just uses the smallest possible intervals when calling Thread.sleep() for the flashlight being on or off
EDIT: this is the thread code, and code that turns the flashlight on
public void turnStrobeOn(){
for ( int i = 0; i < 3; i++){
isInCycle = true;
cam = Camera.open();
Parameters p = cam.getParameters();
p.setFlashMode(Parameters.FLASH_MODE_TORCH);
cam.setParameters(p);
cam.startPreview(); // the flashlight is now on
lightIsOn = true;
new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(delayOn);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
cam.stopPreview();
cam.release();
lightIsOn = false;
new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(delayOff);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
} //end of for loop
isInCycle = false;
} // end of turnStrobeOn
You might want to get someone else's advice on this buy my best guess is that you can't be so specific on sleep(). Also don't forget to use miliseconds for that. I'd suggest using the android handler and doing postDelayed for this instead of sleeping.
How to pause / sleep thread or process in Android?

Thread in android not working as expected

I am following a guide that shows how to create a Pong game. There is a part, where I am supposed to create a Thread, and call a function that moves the ball.
This is the code I created:
package com.ozadari.pingpong;
public class PingPongGame extends Thread {
private Ball gameBall;
private PingPongView gameView;
public PingPongGame(Ball theBall,PingPongView mainView)
{
this.gameBall = theBall;
this.gameView = mainView;
}
#Override
public void run()
{
while(true)
{
this.gameBall.moveBall();
this.gameView.postInvalidate();
try
{
PingPongGame.sleep(5);
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
}}
The thread is called and working, but it doesn't print anything. I tried to cancel the infinte loop and make the loop run 100 times. After I wait a while, it prints to the screen as it should be after 100 runs, but it doesn't print anything in the middle.
What is the problem? How can I fix it?
Unsure from the code you've posted but anyway, you can use a handler and have it run once every second like so (change the time to what you want):
Handler handler = new Handler();
final Runnable r = new Runnable()
{
public void run()
{
//do your stuff here
handler.postDelayed(this, 1000);
}
};
handler.postDelayed(r, 1000);
http://developer.android.com/reference/android/os/Handler.html
You can also use a normal thread, and call start at the end.
Thread thread = new Thread()
{
#Override
public void run() {
try {
while(true) {
sleep(1000);
handler.post(r);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
thread.start();

Categories