fabigol Posté(e) 12 octobre 2010 Share Posté(e) 12 octobre 2010 bonjour, j'ai recupere ce code d'un tutorial... j'ai un soucis de comprehension au niveau de synchronized.. je ne comprnd pas pourquoi on doit synchronized deux fois: onTouchEvent et onDraw... et pourquoi on synchronzed sur surfaceHolder?? package com.application.dessin2; import java.util.ArrayList; import android.app.Activity; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.os.Bundle; import android.view.MotionEvent; import android.view.SurfaceHolder; import android.view.SurfaceView; public class Main extends Activity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(new MySurface(this)); } public class MySurface extends SurfaceView implements SurfaceHolder.Callback{ private ThreadView _thread; private ArrayList _graphics = new ArrayList(); public MySurface(Context context) { super(context); _thread = new ThreadView(getHolder(),this); getHolder().addCallback(this); setFocusable(true); } protected void onDraw(Canvas canvas) { canvas.drawColor(Color.WHITE); Bitmap bitmap; GraphicObject.Coordinates coords; for(GraphicObject graphic:_graphics){ bitmap = graphic.getBitmap(); coords = graphic.getCoordinates(); graphic.moveBall(2,2); canvas.drawBitmap(bitmap,coords.getX(),coords.getY(),null); } } public boolean onTouchEvent(MotionEvent event) { synchronized(_thread.getSurfaceHolder()){ if(event.getAction() == MotionEvent.ACTION_DOWN){ GraphicObject graphic = new GraphicObject(BitmapFactory.decodeResource(getResources(), R.drawable.icon)); graphic.getCoordinates().setX((int)event.getX() - graphic.getBitmap().getWidth()/2); graphic.getCoordinates().setY((int)event.getY() - graphic.getBitmap().getHeight()/2); _graphics.add(graphic); } } return true; } public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } public void surfaceCreated(SurfaceHolder holder) { _thread.setRunning(true); _thread.start(); } public void surfaceDestroyed(SurfaceHolder holder) { boolean retry = true; _thread.setRunning(false); while(retry){ try{ _thread.join(); retry=false; }catch(InterruptedException e){ } } } } public class ThreadView extends Thread{ private SurfaceHolder _surfaceHolder; private MySurface _mySurface; private boolean _run = false; public ThreadView(SurfaceHolder surfaceHolder,MySurface mySurface){ _surfaceHolder = surfaceHolder; _mySurface = mySurface; } public void setRunning(boolean run){ _run = run; } public SurfaceHolder getSurfaceHolder(){ return _surfaceHolder; } public void run(){ Canvas c; while(_run){ c=null; try{ c=_surfaceHolder.lockCanvas(); synchronized(_surfaceHolder){ _mySurface.onDraw(c); } }finally{ if(c != null){ _surfaceHolder.unlockCanvasAndPost(c); } } } } } public class GraphicObject{ public Bitmap _bitmap; public Coordinates _coordinates; private boolean goRight = true; private boolean goDown = true; public class Coordinates{ private int _x = 100; private int _y = 100; public void setX(int value){ _x=value; } public int getX(){ return _x; } public void setY(int value){ _y=value; } public int getY(){ return _y; } } public GraphicObject(Bitmap bitmap){ _bitmap = bitmap; _coordinates = new Coordinates(); } public Bitmap getBitmap() { return _bitmap; } public Coordinates getCoordinates() { return _coordinates; } public void moveBall(int goX, int goY) { if (_coordinates.getX() > 270){ goRight = false; } if (_coordinates.getX() < 0){ goRight = true; } if (_coordinates.getY() > 400){ goDown = false; } if (_coordinates.getY() < 0){ goDown = true; } // move the x and y if (goRight){ _coordinates._x += goX; }else { _coordinates._x -= goX; } if (goDown){ _coordinates._y += goY; }else { _coordinates._y -= goY; } } } } merci de votre futur aide Lien vers le commentaire Partager sur d’autres sites More sharing options...
ichpa Posté(e) 13 octobre 2010 Share Posté(e) 13 octobre 2010 Bonjour, En lisant rapidement, je pense que les deux synchronised permettent de protéger l'accès concurrent à la liste _graphics. Dans onTouchEvent il ajoute un élément dans cette liste et la parcourt dans onDraw. Le synchronised garanti donc que le traitement ne va pas lire cette liste pendant qu'un élément est ajouté. Par contre, pour ma part je n'aurai probablement pas fait comme cela : j'aurai directement utilisé une liste synchronisée avec la méthode Collections.synchronizedList(list). ichpa Lien vers le commentaire Partager sur d’autres sites More sharing options...
fabigol Posté(e) 13 octobre 2010 Auteur Share Posté(e) 13 octobre 2010 Tu aurais utilise synchronisedlist pour ontouchevent??? La synchronisation consiste a locker un objet pour que 2 threads ne s'en servent pas en même temps??? Il suffirait de mettre en paramètre l objet a la fonction synchronized??? Si je comprends bien... J ai un peu de mal avec les threads.. C vieux pour moi mais très utile et flexible c pour ça que je veux bien tout comprendre.. Dans ce projet il y a 2 thread: - activité - le dessin Lien vers le commentaire Partager sur d’autres sites More sharing options...
ichpa Posté(e) 13 octobre 2010 Share Posté(e) 13 octobre 2010 Ton exemple utilise la même instance de SurfaceHolder comme verrou pour les deux blocs synchronised. Cela signifie effectivement qu'une thread ne pourra exécuter son bloc synchronised que si l'autre thread n'est pas en train d'exécuter son propre bloc. Dans mon exemple que je donne, j'aurai retiré les deux blocs synchronised qui me sont inutiles, puis j'aurai instancié la liste _graphics comme ceci : private List _graphics = Collections.synchronizedList(new ArrayList()); Techniquement Collections.synchronizedList créé une liste qui gère nativement les accès concurrents. Lien vers le commentaire Partager sur d’autres sites More sharing options...
Recommended Posts
Archivé
Ce sujet est désormais archivé et ne peut plus recevoir de nouvelles réponses.