[solved] Mysterious thread in SurfaceView

Put your problem here if it does not fit any of the other categories.

[solved] Mysterious thread in SurfaceView

Postby imnewhere » Sat May 16, 2009 10:18 pm

Since it's my first post, greets to everyone

I experience some strange behaviour during work with SurfaceView,
I've added onTouchListener to the view, but the listener is invoked twice on a single touch.
Probably some mysterious thread runs around there, I don't have any idea how to solve it, so please help me with it.

below logs + snippets

thanks in advance for your help

05-16 20:56:04.555: INFO/ActivityManager(573): Start proc my.example for activity my.example/.SurfaceExampleActivity: pid=7633 uid=10023 gids={}
05-16 20:56:04.685: INFO/jdwp(7633): received file descriptor 20 from ADB
05-16 20:56:05.065: DEBUG/dalvikvm(7633): Trying to load lib /system/lib/libsoundpool.so 0x0
05-16 20:56:05.095: DEBUG/dalvikvm(7633): Added shared lib /system/lib/libsoundpool.so 0x0
05-16 20:56:05.435: DEBUG/SurfaceExampleView(7633): surfaceCreated
05-16 20:56:05.435: DEBUG/SurfaceExampleView(7633): start
05-16 20:56:05.455: DEBUG/SurfaceExampleView(7633): run
05-16 20:56:05.455: DEBUG/SurfaceExampleView(7633): surfaceChanged
05-16 20:56:05.485: INFO/ActivityManager(573): Displayed activity my.example/.SurfaceExampleActivity: 1118 ms
05-16 20:56:15.685: DEBUG/dalvikvm(616): GC freed 179 objects / 8512 bytes in 164ms
05-16 20:56:45.005: DEBUG/SurfaceExampleView(7633): onTouch
05-16 20:56:45.005: DEBUG/SurfaceExampleView(7633): playSounds
05-16 20:56:45.095: DEBUG/SurfaceExampleView(7633): onTouch
05-16 20:56:45.095: DEBUG/SurfaceExampleView(7633): playSounds


Activity
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.  
  2. package my.example;
  3.  
  4.  
  5.  
  6. import my.example.SurfaceExampleView.SurfaceExampleThread;
  7.  
  8. import android.app.Activity;
  9.  
  10. import android.os.Bundle;
  11.  
  12.  
  13.  
  14. public class SurfaceExampleActivity extends Activity {
  15.  
  16.  
  17.  
  18.     @Override
  19.  
  20.     public void onCreate(Bundle savedInstanceState) {
  21.  
  22.         super.onCreate(savedInstanceState);
  23.  
  24.  
  25.  
  26.         setContentView(R.layout.main);
  27.  
  28.  
  29.  
  30.         SurfaceExampleView  view = (SurfaceExampleView) findViewById(R.id.view);
  31.  
  32.         SurfaceExampleThread thread = view.getThread();
  33.  
  34.         thread.doStart();
  35.  
  36.     }
  37.  
  38. }
Parsed in 0.032 seconds, using GeSHi 1.0.8.4


View and inner Thread
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.  
  2. package my.example;
  3.  
  4.  
  5.  
  6. import java.util.ArrayList;
  7.  
  8. import java.util.List;
  9.  
  10.  
  11.  
  12. import android.content.Context;
  13.  
  14. import android.graphics.Canvas;
  15.  
  16. import android.graphics.Color;
  17.  
  18. import android.graphics.Paint;
  19.  
  20. import android.media.AudioManager;
  21.  
  22. import android.media.SoundPool;
  23.  
  24. import android.util.AttributeSet;
  25.  
  26. import android.util.Log;
  27.  
  28. import android.view.MotionEvent;
  29.  
  30. import android.view.SurfaceHolder;
  31.  
  32. import android.view.SurfaceView;
  33.  
  34. import android.view.View;
  35.  
  36.  
  37.  
  38. public class SurfaceExampleView extends SurfaceView implements SurfaceHolder.Callback {
  39.  
  40.  
  41.  
  42.     private static final String TAG = SurfaceExampleView.class.getSimpleName();
  43.  
  44.  
  45.  
  46.     class SurfaceExampleThread extends Thread implements OnTouchListener {
  47.  
  48.  
  49.  
  50.         public static final int STATE_READY = 0x1;
  51.  
  52.         public static final int STATE_RUNNING = 0x2;
  53.  
  54.         public static final int STATE_PAUSE = 0x3;
  55.  
  56.  
  57.  
  58.         private boolean running;
  59.  
  60.         private SurfaceHolder surfaceHolder;
  61.  
  62.         private Context context;
  63.  
  64.         private int state = 0;
  65.  
  66.  
  67.  
  68.         private SoundPool soundPool;
  69.  
  70.         private int[] sounds = new int[7];
  71.  
  72.  
  73.  
  74.         private Paint paint;
  75.  
  76.  
  77.  
  78.         private List<Integer> soundsToPlay = new ArrayList<Integer>();
  79.  
  80.         private String textToDraw = "";
  81.  
  82.  
  83.  
  84.         public SurfaceExampleThread(SurfaceHolder pSurfaceHolder, Context pContext) {
  85.  
  86.             surfaceHolder = pSurfaceHolder;
  87.  
  88.             context = pContext;
  89.  
  90.             initGame();
  91.  
  92.         }
  93.  
  94.  
  95.  
  96.         @Override
  97.  
  98.         public synchronized void start() {
  99.  
  100.             Log.d(TAG, "start");
  101.  
  102.             super.start();
  103.  
  104.         }
  105.  
  106.  
  107.  
  108.         @Override
  109.  
  110.         public void run() {
  111.  
  112.             Log.d(TAG, "run");
  113.  
  114.             while (running) {
  115.  
  116.                 Canvas canvas = null;
  117.  
  118.                 try {
  119.  
  120.                     sleep(100);
  121.  
  122.                     canvas = surfaceHolder.lockCanvas(null);
  123.  
  124.                     synchronized (surfaceHolder) {
  125.  
  126.                         if (state == STATE_RUNNING) {
  127.  
  128.                             doDraw(canvas);
  129.  
  130.                         }
  131.  
  132.                     }
  133.  
  134.                 } catch (InterruptedException exception) {
  135.  
  136.                     Log.e(TAG, exception.getMessage());
  137.  
  138.                     exception.printStackTrace();
  139.  
  140.                 } finally {
  141.  
  142.                     if (canvas != null) {
  143.  
  144.                         surfaceHolder.unlockCanvasAndPost(canvas);
  145.  
  146.                     }
  147.  
  148.                 }
  149.  
  150.             }
  151.  
  152.         }
  153.  
  154.  
  155.  
  156.         private void playSounds() {
  157.  
  158.             if(!soundsToPlay.isEmpty()) {
  159.  
  160.                 Log.d(TAG, "playSounds");
  161.  
  162.                 for(int i=0; i<soundsToPlay.size(); i++) {
  163.  
  164.                     soundPool.play(soundsToPlay.get(i), 0.8f, 0.8f, 1, 0, 1f);
  165.  
  166.                 }
  167.  
  168.             }
  169.  
  170.         }
  171.  
  172.  
  173.  
  174.         private void doDraw(Canvas pCanvas) {
  175.  
  176.             pCanvas.drawColor(Color.BLACK);
  177.  
  178.             pCanvas.drawText(textToDraw, 10, 10, paint);
  179.  
  180.         }
  181.  
  182.  
  183.  
  184.         @Override
  185.  
  186.         public boolean onTouch(View pV, MotionEvent pEvent) {
  187.  
  188.             Log.d(TAG, "onTouch");
  189.  
  190.             if(pV.equals(SurfaceExampleView.this)) {
  191.  
  192.                 soundsToPlay.clear();
  193.  
  194.                 soundsToPlay.add(sounds[0]);
  195.  
  196.                 playSounds();
  197.  
  198.                 return true;
  199.  
  200.             }
  201.  
  202.             return false;
  203.  
  204.         }
  205.  
  206.  
  207.  
  208.         private void initGame() {
  209.  
  210.             setup();
  211.  
  212.             loadSounds();
  213.  
  214.         }
  215.  
  216.         private void setup() {
  217.  
  218.             paint = new Paint();
  219.  
  220.             paint.setARGB(255, 255, 0, 0);
  221.  
  222.         }
  223.  
  224.  
  225.  
  226.         private void loadSounds() {
  227.  
  228.             soundPool = new SoundPool(4, AudioManager.STREAM_MUSIC, 100);
  229.  
  230.             int[] soundResources = new int[] {R.raw.ne};
  231.  
  232.             for(int i=0; i<soundResources.length; i++) {
  233.  
  234.                 sounds[i] = soundPool.load(context, soundResources[i], 1);
  235.  
  236.             }
  237.  
  238.         }
  239.  
  240.  
  241.  
  242.         public void doStart() {
  243.  
  244.             synchronized (surfaceHolder) {
  245.  
  246.                 setState(STATE_RUNNING);
  247.  
  248.             }
  249.  
  250.         }
  251.  
  252.  
  253.  
  254.         public void doPause() {
  255.  
  256.             synchronized (surfaceHolder) {
  257.  
  258.                 if (state == STATE_RUNNING) {
  259.  
  260.                     setState(STATE_PAUSE);
  261.  
  262.                 }
  263.  
  264.             }
  265.  
  266.         }
  267.  
  268.  
  269.  
  270.         public void setRunning(boolean pRunning) {
  271.  
  272.             running = pRunning;
  273.  
  274.         }
  275.  
  276.  
  277.  
  278.         public void setState(int pState) {
  279.  
  280.             synchronized (surfaceHolder) {
  281.  
  282.                 state = pState;
  283.  
  284.             }
  285.  
  286.         }
  287.  
  288.  
  289.  
  290.     }
  291.  
  292.  
  293.  
  294.  
  295.  
  296.     SurfaceExampleThread thread;
  297.  
  298.  
  299.  
  300.     public SurfaceExampleView(Context pContext, AttributeSet pAttrs) {
  301.  
  302.         super(pContext, pAttrs);
  303.  
  304.  
  305.  
  306.         SurfaceHolder holder = getHolder();
  307.  
  308.         holder.addCallback(this);
  309.  
  310.         thread = new SurfaceExampleThread(holder, pContext);
  311.  
  312.  
  313.  
  314.         setOnTouchListener(thread);
  315.  
  316.     }
  317.  
  318.  
  319.  
  320.     @Override
  321.  
  322.     public void onWindowFocusChanged(boolean hasWindowFocus) {
  323.  
  324.         if (!hasWindowFocus) {
  325.  
  326.             thread.doPause();
  327.  
  328.         }
  329.  
  330.     }
  331.  
  332.  
  333.  
  334.     @Override
  335.  
  336.     public void surfaceCreated(SurfaceHolder pHolder) {
  337.  
  338.         Log.d(TAG, "surfaceCreated");
  339.  
  340.         thread.setRunning(true);
  341.  
  342.         thread.start();
  343.  
  344.     }
  345.  
  346.  
  347.  
  348.     @Override
  349.  
  350.     public void surfaceChanged(SurfaceHolder pHolder, int pFormat, int pWidth, int pHeight) {
  351.  
  352.         Log.d(TAG, "surfaceChanged");
  353.  
  354.     }
  355.  
  356.  
  357.  
  358.     @Override
  359.  
  360.     public void surfaceDestroyed(SurfaceHolder pHolder) {
  361.  
  362.         Log.d(TAG, "surfaceDestroyed");
  363.  
  364.         boolean retry = true;
  365.  
  366.         thread.setRunning(false);
  367.  
  368.         while (retry) {
  369.  
  370.             try {
  371.  
  372.                 thread.join();
  373.  
  374.                 retry = false;
  375.  
  376.             } catch (InterruptedException exception) {
  377.  
  378.                 Log.e(TAG, "Interrupted surface destroy", exception);
  379.  
  380.             }
  381.  
  382.         }
  383.  
  384.     }
  385.  
  386.  
  387.  
  388.     public SurfaceExampleThread getThread() {
  389.  
  390.         return thread;
  391.  
  392.     }
  393.  
  394.  
  395.  
  396. }
  397.  
  398.  
Parsed in 0.055 seconds, using GeSHi 1.0.8.4
Last edited by imnewhere on Mon May 18, 2009 11:22 am, edited 1 time in total.
imnewhere
Freshman
Freshman
 
Posts: 2
Joined: Sat May 16, 2009 9:52 pm

Top

Postby WarrenFaith » Mon May 18, 2009 9:42 am

i wouldnt implement the touchlistener with the thread.
why you didnt use the already existing implementation of SurfaceView and simply override the onTouchEvent() method?
I just wrote a part of my tutorial discussing the touch handling:
http://www.droidnova.com/playing-with-g ... i,176.html
WarrenFaith
Moderator
Moderator
 
Posts: 227
Joined: Fri Mar 13, 2009 10:59 am
Location: Berlin, Germany

Postby mangaluve » Mon May 18, 2009 10:48 am

Have you checked the type of action on the MotionEvent (by getAction())? perhaps you get a DOWN event, followed my a MOVE event or something like that?
mangaluve
Experienced Developer
Experienced Developer
 
Posts: 82
Joined: Mon Mar 23, 2009 8:59 pm

Postby imnewhere » Mon May 18, 2009 11:22 am

mangaluve, you were right!

There are two events, one for action Down and second is for Move.

I've change the implementation so that i check event action and everything works perfect!

Thx a lot and best regards
imnewhere
Freshman
Freshman
 
Posts: 2
Joined: Sat May 16, 2009 9:52 pm

Top

Return to Other Coding-Problems

Who is online

Users browsing this forum: No registered users and 19 guests