Reputation: 2179
This is the comple java class (GFXSurface). Inside this class, a second class is defined,
public class GFXSurface extends Activity implements OnTouchListener {
AnotherSurface ourSurfaceView;
float x, y;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
ourSurfaceView = new AnotherSurface(this);
ourSurfaceView.setOnTouchListener(this);
x = 0;
y = 0;
setContentView(ourSurfaceView);
}
@Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
ourSurfaceView.ourPause();
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
ourSurfaceView.ourResume();
}
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
x = event.getX();
y = event.getY();
return true;
}
/*------------------------Class within a class-------------------------------*/
public class AnotherSurface extends SurfaceView implements Runnable {
SurfaceHolder ourHolder;
Thread ourThread = null;
boolean isRunning;
public AnotherSurface(Context context) {
// TODO Auto-generated constructor stub
super(context); //not auto-generated; set it up manually
isRunning = false;
ourHolder = getHolder();
}
public void ourPause(){
isRunning = false;
while(true){
try {
ourThread.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
}
ourThread = null;
}
public void ourResume(){
isRunning = true;
ourThread = new Thread(this);
ourThread.start();
}
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
if(!ourHolder.getSurface().isValid())
continue;
Canvas canvas = ourHolder.lockCanvas();
canvas.drawRGB(255, 0, 0);
if(x!=0 && y!=0){
Bitmap ourBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.green_ball);
canvas.drawBitmap(ourBitmap, x-(ourBitmap.getWidth()/2), y-(ourBitmap.getHeight()/2), null);
}
ourHolder.unlockCanvasAndPost(canvas);
}
}
}
}
Now, when I start the activity, it works as is required, it creates a bitmap at the place where the screen is clicked (centered at the point of click). The problem it gives is that, when I press the back key on my phone, the app stops responding and the phone gives an option to force shut the app. I think the it has got to do something with the "ourThread" thread not being joined properly.
Any idea where the problem lies? Thanks.
while(true){
if(!ourHolder.getSurface().isValid())
continue;
Canvas canvas = ourHolder.lockCanvas();
canvas.drawRGB(255, 0, 0);
if(x!=0 && y!=0){
Bitmap ourBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.green_ball);
canvas.drawBitmap(ourBitmap, x-(ourBitmap.getWidth()/2), y-(ourBitmap.getHeight()/2), null);
}
I just changed "true" to "isRunning". And now the thread does end, and thus, the activity closes on pressing the back button. Thanks all for your valuable suggestions.
Upvotes: 2
Views: 8527
Reputation: 116908
The problem is that, "ourThread" never stops when it is joined.
You have to realize that calling ourThread.join()
only waits for the thread to finish -- it won't stop the thread. Your ourThread
may be hung for some reason. A thread dump will show where it is running. Maybe it is stuck in a loop? Maybe it is waiting on a network connection?
If the join()
returns successfully, by definition, the thread was was joined is no longer running. So the thread calling ourThread.join()
will wait until the ourThread
thread has completed.
If the thread is no longer running then maybe there are other threads running keeping your application open? A thread dump will show you what other non-daemon threads are still around. They will need to terminate before your application will stop.
In looking at your thread code, I don't see any way for you to exit the infinite loop unless a RuntimeException
is thrown. When does the thread stop working? Did you mean to do a break;
instead of a continue;
?
while(true){
if(!ourHolder.getSurface().isValid())
continue; // should this be a break?
Canvas canvas = ourHolder.lockCanvas();
canvas.drawRGB(255, 0, 0);
ourHolder.unlockCanvasAndPost(canvas);
}
Now that you've added more code, you need to make isRunning
be volatile
so that multiple threads can update it and see the updates and you should change the while
loop in your run()
method to be:
private volatile boolean isRunning;
...
while(!isRunning){
Upvotes: 2