Perhaps this would be a better way to inspire feedback. Is it possible to pause and resume a view based upon SurfaceView? What would be the correct way to restart the view so that the thread can begin drawing again?
On Fri, Apr 24, 2009 at 1:29 PM, Jason Van Anden <jason.van.an...@gmail.com> wrote: > I created a toy app that demos my problem ... the complete code can be > found here: http://www.smileproject.com/SurfCodeExample.zip > > Feedback super appreciated. Here is the code from the activity and > view only ... > > public class Surf extends Activity { > /** Called when the activity is first created. */ > > private SurfView mView; > private SurfThread mThread; > > private static final int COLOR_MENU_ID = Menu.FIRST; > public static final int ACTIVITY_ASSIGN_COLOR = 0; > > �...@override > public void onCreate(Bundle savedInstanceState) { > > super.onCreate(savedInstanceState); > > mView= new SurfView(this, null); > setContentView(mView); > } > > �...@override > protected void onPause() { > // TODO Auto-generated method stub > super.onPause(); > > System.out.println ("PAUSED"); > mThread.pause(); > } > > �...@override > protected void onResume() { > // TODO Auto-generated method stub > super.onResume(); > > System.out.println ("RESUMED"); > > mThread = mView.getThread(); > mThread.resume(); > } > > �...@override > public boolean onCreateOptionsMenu(Menu menu) { > > boolean result = super.onCreateOptionsMenu(menu); > > menu.add(0, COLOR_MENU_ID, 0, R.string.menu_color); > > return result; > } > > �...@override > public boolean onPrepareOptionsMenu(Menu menu) { > super.onPrepareOptionsMenu(menu); > return true; > } > > �...@override > public boolean onOptionsItemSelected(MenuItem item) { > > super.onOptionsItemSelected(item); > > switch (item.getItemId()) { > > case COLOR_MENU_ID: > Intent i = new Intent(this, SurfChooser.class); > startActivityForResult(i, ACTIVITY_ASSIGN_COLOR); > return true; > } > > return true; > } > > @Override > protected void onActivityResult(int requestCode, int resultCode, > Intent data) { > // TODO Auto-generated method stub > super.onActivityResult(requestCode, resultCode, data); > > Bundle extras; > > if (data == null) return; > > extras = data.getExtras(); > > switch(requestCode) { > > case ACTIVITY_ASSIGN_COLOR: > Log.w(this.getClass().getName(), "back"); > if (data == null) return; > > } > } > } > > class SurfView extends SurfaceView implements SurfaceHolder.Callback, > OnGestureListener { > > private String TAG = "SurfView"; > private boolean is_dirty = true; > > private boolean block_block = false; > private boolean block_after_draw = true; > > /** The thread that actually draws the animation */ > private SurfThread thread; > private GestureDetector mGestureDetector; > > > public float offset_x = 0; // review this later > public float offset_y = 0; > > public float x_velocity = 0; // review this later > public float y_velocity = 0; > > private float last_pos_x = 0; > private float last_pos_y = 0; > > private int keep_on_trucking = -1; > > // used for managing timing in physics > private long start_time = System.currentTimeMillis(); > private long end_time = 0; > private long sleep_time = 0; > private long diff_time = 0; > private long action_period = 20; // 50 = 20fps > > /** coords of bg circle */ > private float bX; > private float bY; > > /** coords of pointer (m == mouse). */ > private float mX; > private float mY; > > /** Handle to the surface manager object we interact with */ > private boolean hasSurface; > > class SurfThread extends Thread { > > private int mCanvasWidth = -1; > private int mCanvasHeight = -1; > > /** !!! Message handler used by thread to interact with TextView */ > // private Handler mHandler; > > /** Used to figure out elapsed time between frames */ > private long mLastTime; > > /** The state of the game. One of READY, RUNNING, PAUSE, > LOSE, or WIN */ > private int mMode; > > /** Scratch rect object. */ > private RectF mScratchRect; > > Paint mPaint = new Paint(); > > int transparent_white; > > /** Indicate whether the surface has been created & is ready to > draw */ > private boolean mRunning = false; > public boolean is_drawing = false; > > private ConditionVariable mCondition = new ConditionVariable(); > > private SurfaceHolder mHolder; > private Context mContext; > > public SurfThread(SurfaceHolder holder, Context context){ > > mHolder = holder; > mContext = context; > > mRunning = false; > init(); > } > > public void init(){ > mPaint.setColor(Color.RED); > } > > public void pause(){ > synchronized (this) { > Log.v("PeepThread", "pause?"); > //requestExitAndWait(); > > setRunning(false); > mCondition.open(); > //holdup = false; > > } > } > > public void setRunning(boolean b) { > mRunning = b; > } > > public boolean holdup = false; > > public void do_draw(){ > > is_dirty = true; > block_after_draw = true; > mCondition.open(); > } > > /** this is key to most everything */ > �...@override > public void run() { > > SurfaceHolder surfaceHolder = mHolder; > mCondition = new ConditionVariable(false); > > Log.v("Peep Thread", "restarted?"); > > mRunning = true; > > while (mRunning) { > > Log.v("Peep Thread", "run?"); > > while (holdup){ > > mCondition.block(100); > System.out.println ("not running?"); > > if (!mRunning){ > is_dirty = false; > break; > } > } > > is_drawing = true; > > updatePhysics(); > > if (is_dirty){ > > Canvas c = null; > > c = surfaceHolder.lockCanvas(null); // moved this out > of "try" loop as per Stoyan suggestion > > try { > synchronized (surfaceHolder) { > draw_me(c); > } > > } 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); > } > } > is_dirty = false; > } > > start_time = System.currentTimeMillis(); > > is_drawing = false; > > // !!! this needs to work off a stack > if (block_after_draw) { > mCondition.close(); > mCondition.block(); > } > } > > System.out.println ("thread killed?"); > > } > > public void requestExitAndWait(){ > > mRunning = false; > > try { > join(); > } catch (InterruptedException ex){ > // nothing is supposed to happen here > // (left intentionally blank) > } > } > > /* Callback invoked when the surface dimensions change. */ > public void setSurfaceSize(int width, int height) { > // synchronized to make sure these all change atomically > > // !!! TODO: make sure center of screen stays. Might make > sense to draw a mini-screen_bubble to confirm. > > synchronized (mHolder) { > > // this can be improved - ask ben to write something that > will determine the smallest circle that will fit around the largest > square > System.out.println ("setSurfaceSize"); > > mCanvasWidth = width; > mCanvasHeight = height; > } > } > > > public void unpause() { > > // Move the real time clock up to now > synchronized (mHolder) { > } > > thread.do_draw(); > } > > /** > * Draw operations go in here > */ > private void draw_me(Canvas canvas) { > > canvas.drawColor(Color.WHITE); // draw background color > > canvas.save(); > canvas.translate(offset_x, offset_y); > > canvas.drawCircle(mX, mY, 60, mPaint); > > canvas.restore(); > canvas.translate(offset_x * -1, offset_y * -1); > } > > /** > * Figures the lander state (x, y, fuel, ...) based on the passage of > * realtime. Does not invalidate(). Called at the start of draw(). > * Detects the end-of-game and sets the UI to the next state. > */ > private void updatePhysics() { > > end_time = System.currentTimeMillis(); > diff_time = (end_time - start_time); > sleep_time = action_period - diff_time; > > if (sleep_time < 1) sleep_time = 1; > > try { > Thread.sleep(sleep_time); > } > catch(InterruptedException ex) { > > } > > is_dirty = true; > > } > } > > private void init(){ > // register our interest in hearing about changes to our surface > > mGestureDetector = new GestureDetector(this); > mGestureDetector.setIsLongpressEnabled(false); // true > > setLongClickable(false); > > hasSurface = false; > } > > public SurfView(Context context, AttributeSet attrs) { > super(context, attrs); > > init(); // prep stuff for view > > SurfaceHolder holder = getHolder(); > holder.addCallback(this); > holder.setType(SurfaceHolder.SURFACE_TYPE_GPU); > > thread = new SurfThread(holder, context); > } > > /** > * Fetches the animation thread corresponding to this View. > * > * @return the animation thread > */ > public SurfThread getThread() { > return thread; > } > > /** > * Standard window-focus override. Notice focus lost so we can pause on > * focus lost. e.g. user switches to take a call. > */ > �...@override > public void onWindowFocusChanged(boolean hasWindowFocus) { > > } > > /* Callback invoked when the surface dimensions change. */ > public void surfaceChanged(SurfaceHolder holder, int format, int > width, int height) { > thread.setSurfaceSize(width, height); > // if (thread != null) thread.setSurfaceSize(width, height); > } > > /* > * Callback invoked when the Surface has been created and is ready to be > * used. > */ > public void surfaceCreated(SurfaceHolder holder) { > // start the thread here so that we don't busy-wait in run() > // waiting for the surface to be created > > is_dirty = true; > > Log.w(this.getClass().getName(), thread.isAlive() + "?"); > > > try { > thread.start(); > } catch (Exception e){ > // thread.run(); > System.out.println ("resurfaced"); // DEAL WITH THIS > DIFF > } > > } > > /* > * Callback invoked when the Surface has been destroyed and must no longer > * be touched. WARNING: after this method returns, the Surface/Canvas must > * never be touched again! > */ > public void surfaceDestroyed(SurfaceHolder holder) { > // we have to tell thread to shut down & wait for it to finish, or else > // it might touch the Surface after we return and explode > boolean retry = true; > > thread.setRunning(false); > > while (retry) { > try { > thread.join(); > retry = false; > } catch (InterruptedException e) { > > } > } > > Log.v(this.getClass().getName(), "SURFACE DESTROYED"); > > } > > �...@override > public boolean onTouchEvent(MotionEvent event) { > return false; > } > > > �...@override > public boolean dispatchTouchEvent(MotionEvent event) { > > boolean returnValue = false; > > is_dirty = true; > > returnValue = mGestureDetector.onTouchEvent(event); > returnValue = returnValue ? returnValue : > onTouchEvent(event); > > return returnValue; > } > > public boolean onDown(MotionEvent event) { > > System.out.println ("down"); > thread.do_draw(); > return true; > } > > public boolean onFling(MotionEvent first_event, MotionEvent > last_event, float velocityX, float velocityY) { > return false; > } > > public void onLongPress(MotionEvent event) { > thread.do_draw(); > } > > public boolean onScroll(MotionEvent arg0, MotionEvent event, float > distance_x, float distance_y) { > return false; > } > > public void onShowPress(MotionEvent arg0) { > // TODO Auto-generated method stub > } > > public boolean onSingleTapUp(MotionEvent event) { > > mX = event.getX(); > mY = event.getY(); > thread.do_draw(); > > return false; > } > > } > > Thank You, > Jason > > > > > > > > > On Fri, Apr 24, 2009 at 12:03 PM, robotissues <jason.van.an...@gmail.com> > wrote: >> I am stuck. My main activity creates and starts a SurfaceView. My >> app needs to access a listview via the options menu to change >> properties of the items shown in the view. >> >> Two strange things occur: >> >> 1.) When I scroll the listview quickly, the list sometimes gets >> farklempt. Words overlap each other. >> >> 2.) When I select the item and the app returns to the main activity, >> the thread is no longer alive. >> >> If someone out there can offer help I will post the code. This will >> take a little effort. My code is loosely based upon LunarLander and >> the GLSurfaceView examples. If there is a good example (more recent >> example) someone can point me to, that would be boss. >> >> Thank You > --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Android Developers" group. To post to this group, send email to android-developers@googlegroups.com To unsubscribe from this group, send email to android-developers-unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/android-developers?hl=en -~----------~----~----~----~------~----~------~--~---