I was trying to make the image move. The image does not move and sometimes it flickers.
I wanted to make it Runnable. It uses a Surface Holder and s is the bitmap. The canvas sometimes remain still at i=0 or it flickers. How to make it runnable
package com.smiley;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Path;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class SmileyView extends SurfaceView implements SurfaceHolder.Callback {
public SmileyView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
holder = getHolder();
s= BitmapFactory.decodeResource(context.getResources(),R.drawable.smiley);
holder.addCallback(this);
}
#Override
public boolean onKeyUp(int keyCode, KeyEvent msg) {
super.onKeyUp(keyCode, msg);
rv.update();
return true;
}
private int i=0;
private Bitmap s;private SurfaceHolder holder;private RenderView rv ;
boolean grun=true;long t=0;
public void resume()
{
rv=new RenderView();
}
#Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
// TODO Auto-generated method stub
}
#Override
public void surfaceCreated(SurfaceHolder arg0) {
// TODO Auto-generated method stub
grun=true;
if(rv!=null)
rv.start();
}
#Override
public void surfaceDestroyed(SurfaceHolder arg0) {
// TODO Auto-generated method stub
try {
grun =false;
rv.join();
rv=null;
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
class RenderView extends Thread {
RenderView(){
super();
}
#Override
public void run()
{
SurfaceHolder h=holder;
while(grun)
{
Canvas ca=null;
try{ca = h.lockCanvas(null);
synchronized (h) {
update(); dodraw(ca);
}
}
finally
{
if(ca!=null)
h.unlockCanvasAndPost(ca);
}
}
}
public void dodraw(Canvas canvas)
{ canvas.drawBitmap(s, i, i , null);
canvas.restore();
}
public void update()
{
if(i==0)
i=100;
}
}
}
I made a tutorial for what it seems like you want to do here. You can check it out here. If I had to guess then it might be an issue with not clearing out the canvas. try changing it to (assuming your background is Bitmap backBG)
public void dodraw(Canvas canvas)
{
canvas.drawBitmap(backBG, 0, 0, null);
canvas.drawBitmap(s, i, i , null);
canvas.restore();
}
Related
there is class, that draws on canvas some field
package com.cerbertek;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Region;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class PlayGameView extends SurfaceView implements SurfaceHolder.Callback {
private CanvasThread canvasthread;
private Context mContext;
private Region firstRec;
private class CanvasThread extends Thread {
private SurfaceHolder _holder;
private boolean _run = false;
public CanvasThread(SurfaceHolder surfaceHolder) {
_holder = surfaceHolder;
}
public void setRunning(boolean run) {
_run = run;
}
#Override
public void run() {
Canvas c;
while (_run) {
c = null;
try {
c = _holder.lockCanvas(null);
synchronized (_holder) {
onDraw(c);
}
} finally {
if (c != null) {
_holder.unlockCanvasAndPost(c);
}
}
}
}
}
public PlayGameView (Context context, AttributeSet attrs) {
super(context, attrs);
SurfaceHolder holder = getHolder();
holder.addCallback(this);
canvasthread = new CanvasThread(getHolder());
setFocusable(true);
}
#Override
public void onDraw(Canvas canvas) {
Paint paint = new Paint ();
Bitmap wrench = BitmapFactory.decodeResource(getResources(), R.drawable.wrench);
canvas.drawColor(Color .BLACK);
for(int i = 0; i < 4; i++) {
for(int j = 0; j < 4; j++) {
int left = canvas.getWidth()/2 - wrench.getWidth()*2 + j*wrench.getWidth();
int top = 0 + i*wrench.getHeight();
canvas.drawBitmap(wrench, left, top, null);
Log.d(i + " " + j, left+ " " + top);
}
}
}
#Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
}
#Override
public void surfaceCreated(SurfaceHolder arg0) {
canvasthread.setRunning(true);
canvasthread.start();
}
#Override
public void surfaceDestroyed(SurfaceHolder arg0) {
boolean retry = true;
canvasthread.setRunning(false);
while (retry) {
try {
canvasthread.join();
retry = false;
} catch (InterruptedException e) {
// we will try it again and again...
}
}
}
}
so i want to detect where i click on(for exemple there is 2 rects and i want to detect what rect i click on). i can set setOnClickListener to my view, but how to get position of click?
then i want to set the regions while drawing( it is right, yeah? or not?) and in activity i'll check is click coordinates contains regions
so
1) how can i get coord of click
2) what is the pretty good way to do do all that stuff, because my ideas are poor often
Look at the setOnTouchListener.
The OnTouchListener implements a method with the following signature:
public boolean onTouch(View v, MotionEvent event)
The MotionEvent has information about where the touch actually happened. (event.getX() and event.getY())
It's a bit cheeky - but I was wondering if anyone could tell me what's wrong below.
This is messing around trying to understand android - not "real" code.
It's a surfaceView which is laid out in the main activity layout.
It works - until the phone's "off" button is tapped (sleep) and woken up again. Upon waking up, it goes crazy and android produces a "Force Close" diaglog.
I've been trying to follow the path with LogCat, but for some reason, some messages get dropped - OR - the path I think is being followed, isn't.
eg - on putting the phone to sleep, I will get surfaceDestroyed called (seems reasonable) but on waking, I do not get a surfaceCreated().
The basic logic is: the surfaceView creates a thread which paints the system time in seconds as text. That's it.
I've got a real app I'd like to write - but until I really understand the basics, that won't happen. I've been through a fair number of tutorials too.
Any pointers most gratefully recieved :)
Cheers
Tim
package net.dionic.android.bouncingsquid;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.SystemClock;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import java.lang.System;
public class WidgetSeconds extends SurfaceView implements SurfaceHolder.Callback {
private class CanvasThread extends Thread {
private SurfaceHolder _surfaceHolder;
private WidgetSeconds _surfaceView;
private boolean _run = false;
public CanvasThread(SurfaceHolder surfaceHolder, WidgetSeconds surfaceView) {
Log.i("WidgetSecs.CanvasThread", "constructor");
_surfaceHolder = surfaceHolder;
_surfaceView = surfaceView;
}
public void setRunning(boolean run) {
_run = run;
}
#Override
public void run() {
Canvas c;
while (_run) {
c = null;
try {
c = _surfaceHolder.lockCanvas(null);
synchronized (_surfaceHolder) {
_surfaceView.onDraw(c);
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} finally {
// do this in a finally so that if an exception is thrown
// during the above, we don't leave the Surface in an
// inconsistent state
if (c != null) {
_surfaceHolder.unlockCanvasAndPost(c);
}
}
}
}
}
private CanvasThread canvasthread;
public void Initalise() {
Log.i("WidgetSecs", "Initialise");
}
public WidgetSeconds(Context context, AttributeSet attrs) {
super(context, attrs);
Log.i("WidgetSecs", "constructor");
this.Initalise();
getHolder().addCallback(this);
setFocusable(true);
}
#Override
public void onDraw(Canvas canvas) {
Paint textPaint;
canvas.drawColor(Color.GRAY);
textPaint = new Paint();
textPaint.setTextSize(32);
canvas.drawText(System.currentTimeMillis()/1000 + " S", 10, 50, textPaint);
canvas.restore();
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
Log.i("WidgetSecs", "surfaceChanged");
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
Log.i("WidgetSecs", "surfaceCreated");
Log.i("WidgetSecs.CanvasThread", "Thread create");
canvasthread = new CanvasThread(getHolder(), this);
canvasthread.setRunning(true);
canvasthread.start();
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
Log.i("WidgetSecs", "surfaceDestroyed");
boolean retry = true;
while (retry) {
try {
Log.i("WidgetSecs", "Thread destroyed");
canvasthread.join();
canvasthread = null;
retry = false;
} catch (InterruptedException e) {
Log.i("WidgetSecs", "Thread join failed");
// we will try it again and again...
}
}
}
}
My view is written as follow:
package com.mycompany;
import android.view.View;
import java.util.concurrent.TimeUnit;
import java.util.ArrayList;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.util.AttributeSet;
import android.graphics.Paint;
import android.graphics.Point;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.widget.*;
public class GameEngineView extends View implements SensorEventListener {
GameLoop gameloop;
String txt_acc;
float accY;
ArrayList<Point> bugPath;
private SensorManager sensorManager;
private class GameLoop extends Thread {
private volatile boolean running = true;
public void run() {
while (running) {
try {
TimeUnit.MILLISECONDS.sleep(1);
postInvalidate();
pause();
} catch (InterruptedException ex) {
running = false;
}
}
}
public void pause() {
running = false;
}
public void start() {
running = true;
run();
}
public void safeStop() {
running = false;
interrupt();
}
}
public void unload() {
gameloop.safeStop();
}
public GameEngineView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
init(context);
}
public GameEngineView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
init(context);
}
public GameEngineView(Context context) {
super(context);
// TODO Auto-generated constructor stub
init(context);
}
private void init(Context context) {
txt_acc = "";
// Adding SENSOR
sensorManager=(SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
// add listener. The listener will be HelloAndroid (this) class
sensorManager.registerListener(this,
sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_NORMAL);
// Adding UI Elements : How ?
Button btn_camera = new Button(context);
btn_camera.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT,
LinearLayout.LayoutParams.FILL_PARENT));
btn_camera.setClickable(true);
btn_camera.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
System.out.println("clicked the camera.");
}
});
gameloop = new GameLoop();
gameloop.run();
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// TODO Auto-generated method stub
//super.onMeasure(widthMeasureSpec, heightMeasureSpec);
System.out.println("Width " + widthMeasureSpec);
setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);
}
#Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
// super.onDraw(canvas);
Paint p = new Paint();
p.setColor(Color.WHITE);
p.setStyle(Paint.Style.FILL);
p.setAntiAlias(true);
p.setTextSize(30);
canvas.drawText("|[ " + txt_acc + " ]|", 50, 500, p);
gameloop.start();
}
public void onAccuracyChanged(Sensor sensor,int accuracy){
}
public void onSensorChanged(SensorEvent event){
if(event.sensor.getType()==Sensor.TYPE_ACCELEROMETER){
//float x=event.values[0];
accY =event.values[1];
//float z=event.values[2];
txt_acc = "" + accY;
}
}
}
I would like to add a Button to the scene, but I don't know how to. Can anybody give me some lights?
UPDATE: Here is my Activity :
public class MyActivity extends Activity {
private GameEngineView gameEngine;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// add Game Engine
gameEngine = new GameEngineView(this);
setContentView(gameEngine);
gameEngine.requestFocus();
}
}
And I am following the this tutorial .
detailListView = (LinearLayout) findViewById(R.id.DetailsLinearLayout); // Find the layout where you want to add button
Button button = new Button(this);
button.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT
,ViewGroup.LayoutParams.WRAP_CONTENT));
detailListView.addView(button);//add view to add
I want to add image to Surface view. So i used below code
public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback{
Bitmap myicon;
Canvas canvas;
private Paint mBitmapPaint;
Paint p= new Paint();
#Override
protected void onDraw(Canvas canvas) {
Bitmap myicon=BitmapFactory.decodeResource(getResources(),R.drawable.icon);
canvas.drawColor(Color.BLACK);
canvas.drawBitmap(myicon, 0,0, p);
// canvas.drawBitmap(myicon, 0,0, null);
// canvas.drawBitmap(myicon, 25,25, null);
}
public MySurfaceView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
// TODO Auto-generated method stub
}
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
}
public void surfaceDestroyed(SurfaceHolder arg0) {
// TODO Auto-generated method stub
}
}
But it shows black screen. I didn't get what i did wrong in above code.
Please solve the problem
Thanks in advance.
Here is your solution Buddy, Also look at this link from where I got the solution
MainAct.java
public class MainAct extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mySurfaceView mySurfaceView = new mySurfaceView(getApplicationContext());
setContentView(mySurfaceView);
}
}
mySurfaceView.java
public class mySurfaceView extends SurfaceView implements
SurfaceHolder.Callback {
private TutorialThread _thread;
public mySurfaceView(Context context) {
super(context);
getHolder().addCallback(this);
_thread = new TutorialThread(getHolder(), this);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Bitmap _scratch = BitmapFactory.decodeResource(getResources(),
R.drawable.icon);
canvas.drawColor(Color.BLACK);
canvas.drawBitmap(_scratch, 10, 10, null);
}
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
}
public void surfaceCreated(SurfaceHolder arg0) {
_thread.setRunning(true);
_thread.start();
}
public void surfaceDestroyed(SurfaceHolder arg0) {
boolean retry = true;
_thread.setRunning(false);
while (retry) {
try {
_thread.join();
retry = false;
} catch (InterruptedException e) {
}
}
}
class TutorialThread extends Thread {
private SurfaceHolder _surfaceHolder;
private mySurfaceView _panel;
private boolean _run = false;
public TutorialThread(SurfaceHolder surfaceHolder, mySurfaceView panel) {
_surfaceHolder = surfaceHolder;
_panel = panel;
}
public void setRunning(boolean run) {
_run = run;
}
#Override
public void run() {
Canvas c;
while (_run) {
c = null;
try {
c = _surfaceHolder.lockCanvas(null);
synchronized (_surfaceHolder) {
_panel.onDraw(c);
}
} finally {
if (c != null) {
_surfaceHolder.unlockCanvasAndPost(c);
}
}
}
}
}
}
EDIT :
droidnova website is not available anymore.I have found alternative website here which is having same source.
I hope it will be helpful !!
There are some changes to your class
package com.sample;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class MSurface extends SurfaceView implements SurfaceHolder.Callback {
public MSurface(Context context) {
super(context);
getHolder().addCallback(this);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Bitmap icon = BitmapFactory.decodeResource(getResources(),R.drawable.icon);
canvas.drawColor(Color.BLACK);
canvas.drawBitmap(icon, 10, 10, new Paint());
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// TODO Auto-generated method stub
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
Canvas canvas = null;
try {
canvas = holder.lockCanvas(null);
synchronized (holder) {
onDraw(canvas);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (canvas != null) {
holder.unlockCanvasAndPost(canvas);
}
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
}
}
But I am not sure you need SurfaceView, cause it used not to draw bitmap once, but to draw a lot of times after user interaction
If your view is not interactive, would be better if you extend View instead of SurfaceView
Cheers
Im creating a game in android, and i noticed that the game has a memory leak. Iv managed to isolate the memory leak into a smaller application so that i can see well try and work out, how to fix it.
The application uses a surfaceview for its view and has a thread attached to that in order to do all the drawing to the screen. The memory leak happens when i start a new activity and close the one that im currently using. I can see this when i do a memory dump on my test application as all it does is open and close an activity (activity a -> activity b -> activity a). Iv kind of ran out of ideas as to how i can fix this as iv tried nulling all my references that i do create to the view (inside the thread), iv tried removing the callback from the surfaceview when i destroy the view, and also inside the activity, it doesn't seem to make any difference.
MemoryLeakActivity.java
package memory.leak;
import memory.leak.view.MemoryLeak;
import android.app.Activity;
import android.os.Bundle;
public class MemoryLeakActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new MemoryLeak(this));
}
}
MemoryLeakViewThread.java
package memory.leak.thread;
import memory.leak.view.MemoryLeak;
import android.view.SurfaceHolder;
import android.graphics.Canvas;
public class MemoryLeakViewThread extends Thread {
private MemoryLeak view;
private boolean run =false;
public MemoryLeakViewThread(MemoryLeak view) {
this.view =view;
}
public void setRunning(boolean run) {
this.run =run;
}
#Override
public void run() {
Canvas canvas =null;
SurfaceHolder holder =this.view.getHolder();
while(this.run) {
canvas =holder.lockCanvas();
if(canvas !=null) {
this.view.onDraw(canvas);
holder.unlockCanvasAndPost(canvas);
}
}
holder =null;
this.view =null;
}
}
MemoryLeak.java
package memory.leak.view;
import memory.leak.TestActivity;
import memory.leak.thread.MemoryLeakViewThread;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Canvas;
import android.graphics.Color;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.GestureDetector.OnGestureListener;
public class MemoryLeak extends SurfaceView implements SurfaceHolder.Callback, OnGestureListener {
private GestureDetector gesture;
private MemoryLeakViewThread vThread;
private Context context;
public MemoryLeak(Context context) {
super(context);
this.getHolder().addCallback(this);
this.vThread =new MemoryLeakViewThread(this);
this.gesture =new GestureDetector(this);
this.context =context;
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {}
public void surfaceCreated(SurfaceHolder holder) {
if(!this.vThread.isAlive()) {
this.vThread =new MemoryLeakViewThread(this);
this.vThread.setRunning(true);
this.vThread.start();
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
boolean retry = true;
if(this.vThread.isAlive()) {
this.vThread.setRunning(false);
while(retry) {
try {
this.vThread.join();
retry =false;
} catch(Exception ee) {}
}
}
this.vThread =null;
this.context =null;
}
public boolean onTouchEvent(MotionEvent event) {
return this.gesture.onTouchEvent(event);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
}
#Override
public void onDraw(Canvas canvas) {
canvas.drawColor(Color.WHITE);
}
#Override
public boolean onDown(MotionEvent e) {
return true;
}
#Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
return false;
}
#Override
public void onLongPress(MotionEvent e) {}
#Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
return false;
}
#Override
public void onShowPress(MotionEvent e) {}
#Override
public boolean onSingleTapUp(MotionEvent e) {
Intent helpScreenIntent =new Intent(this.context, TestActivity.class);
this.context.startActivity(helpScreenIntent);
if (this.context instanceof Activity)
((Activity) this.context).finish();
return true;
}
}
TestActivity.java
package memory.leak;
import memory.leak.view.Test;
import android.app.Activity;
import android.os.Bundle;
public class TestActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new Test(this));
}
}
TestViewThread.java
package memory.leak.thread;
import memory.leak.view.Test;
import android.view.SurfaceHolder;
import android.graphics.Canvas;
public class TestViewThread extends Thread {
private Test panel;
private boolean run =false;
public TestViewThread(Test panel) {
this.panel =panel;
}
public void setRunning(boolean run) {
this.run =run;
}
#Override
public void run() {
Canvas canvas =null;
SurfaceHolder holder =this.panel.getHolder();
while(this.run) {
canvas =holder.lockCanvas();
if(canvas !=null) {
this.panel.onDraw(canvas);
holder.unlockCanvasAndPost(canvas);
}
}
holder =null;
this.panel =null;
}
}
Test.java
package memory.leak.view;
import memory.leak.MemoryLeakActivity;
import memory.leak.thread.TestViewThread;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Canvas;
import android.graphics.Color;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.GestureDetector.OnGestureListener;
public class Test extends SurfaceView implements SurfaceHolder.Callback, OnGestureListener {
private GestureDetector gesture;
private TestViewThread vThread;
private Context context;
public Test(Context context) {
super(context);
this.getHolder().addCallback(this);
this.vThread =new TestViewThread(this);
this.gesture =new GestureDetector(this);
this.context =context;
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {}
public void surfaceCreated(SurfaceHolder holder) {
if(!this.vThread.isAlive()) {
this.vThread =new TestViewThread(this);
this.vThread.setRunning(true);
this.vThread.start();
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
boolean retry = true;
if(this.vThread.isAlive()) {
this.vThread.setRunning(false);
while(retry) {
try {
this.vThread.join();
retry =false;
} catch(Exception ee) {}
}
}
this.vThread =null;
this.context =null;
}
public boolean onTouchEvent(MotionEvent event) {
return this.gesture.onTouchEvent(event);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
}
#Override
public void onDraw(Canvas canvas) {
canvas.drawColor(Color.RED);
}
#Override
public boolean onDown(MotionEvent e) {
return true;
}
#Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
return false;
}
#Override
public void onLongPress(MotionEvent e) {}
#Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
return false;
}
#Override
public void onShowPress(MotionEvent e) {}
#Override
public boolean onSingleTapUp(MotionEvent e) {
Intent helpScreenIntent =new Intent(this.context, MemoryLeakActivity.class);
this.context.startActivity(helpScreenIntent);
if (this.context instanceof Activity)
((Activity) this.context).finish();
return true;
}
}
--Edit--
I made changes to the view class to its surfaceDestroyed(SurfaceHolder holder) so that it will set the view that the thread has to null when the thread is told to stop. The changes i made are
public void surfaceDestroyed(SurfaceHolder holder) {
boolean retry = true;
if(this.vThread.isAlive()) {
this.vThread.setRunning(false);
while(retry) {
try {
this.vThread.join();
retry =false;
} catch(Exception ee) {}
}
this.vThread.setRunning(false, null);
}
this.vThread =null;
this.context =null;
this.gesture =null;
}
you also need to change the surfaceCreated(SurfaceHolder holder) method to
public void surfaceCreated(SurfaceHolder holder) {
if(!this.vThread.isAlive()) {
this.vThread =new MemoryLeakViewThread();
this.vThread.setRunning(true, this);
this.vThread.start();
}
}
then on the thread class we need to change the following
public MemoryLeakViewThread() {
}
public void setRunning(boolean run) {
this.run =run;
}
public void setRunning(boolean run, MemoryLeak view) {
this.run =run;
this.view =view;
}
By doing this it seemed to of fixed the problem, the only problem now is the thread seems to stay in memory, due to the thread class and thread group. But im thinking this might be due to the debugger.
You should not create new Thread in the constructor when you are creating it in onSurfaceCreated. Compare your code to my example: How can I use the animation framework inside the canvas?
As you can see here:
http://developer.android.com/resources/articles/avoiding-memory-leaks.html
The easiest way to start a memory leak in Android is to pass a view's constructor the whole activity instead of the application context. Have you try to change this line:
setContentView(new MemoryLeak(this));
into this one:
setContentView(new MemoryLeak(Context.getApplicationContext()));
?
Hope it helps.