2011-06-08 6 views
0

J'essaie d'implémenter un multithreading dans mon application et je voudrais savoir comment je peux le faire. Fondamentalement dans une seule vue j'ai 2 blocs que je veux que ces deux blocs rebondissent autour de l'écran cependant je veux que chaque bloc fonctionne sur son propre fil. Donc vue unique multi-thread ... si c'est possible. Voici ce que j'ai jusqu'à présent:Android: Animation et multithread

public class mainActivity extends Activity { 


protected static final int GUIUPDATEIDENTIFIER = 0x101; 

//Thread myRefreshThread = null; 

BounceView myBounceView = null; 

Handler myGUIUpdateHandler = new Handler() { 

    @Override 
    public void handleMessage(Message msg){ 
     switch (msg.what){ 
     case mainActivity.GUIUPDATEIDENTIFIER: 
      myBounceView.invalidate(); 
      break; 
     } 
     super.handleMessage(msg); 
    } 
}; 


/** Called when the activity is first created. */ 
@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    this.requestWindowFeature(Window.FEATURE_NO_TITLE); 

    this.myBounceView = new BounceView(this); 
    this.setContentView(this.myBounceView); 

    new Thread (new RefreshRunner()).start(); 

} 

class RefreshRunner implements Runnable { 
    // @Override 
    public void run() { 
      while (!Thread.currentThread().isInterrupted()) { 
        // Send Message to the Handler which will call the invalidate() method of the BoucneView 
        Message message = new Message(); 
        message.what = mainActivity.GUIUPDATEIDENTIFIER; 
        mainActivity.this.myGUIUpdateHandler.sendMessage(message); 

        try { 
          Thread.sleep(100); // a 10th of a second 
        } catch (InterruptedException e) { 
          Thread.currentThread().interrupt(); 
        } 
      } 
    } 
} 


} 

Mon BounceView est:

public class BounceView extends View { 


protected Drawable mySprite; 
protected Point mySpritePos = new Point(0,0); 

protected enum HorizontalDirection {LEFT, RIGHT} 
protected enum VerticalDirection {UP, DOWN} 
protected HorizontalDirection myXDirection = HorizontalDirection.RIGHT; 
protected VerticalDirection myYDirection = VerticalDirection.UP; 


public BounceView(Context context) { 
     super(context); 

     this.mySprite = this.getResources().getDrawable(R.drawable.block); 
} 

@Override 
protected void onDraw(Canvas canvas) { 
     /* Check if the Ball started to leave 
     * the screen on left or right side */ 
     if (mySpritePos.x >= this.getWidth() - mySprite.getBounds().width()) { 
       this.myXDirection = HorizontalDirection.LEFT; 
     } else if (mySpritePos.x <= 0) { 
       this.myXDirection = HorizontalDirection.RIGHT; 
     } 

     /* Check if the Ball started to leave 
     * the screen on bottom or upper side */ 
     if (mySpritePos.y >= this.getHeight() - mySprite.getBounds().height()) { 
       this.myYDirection = VerticalDirection.UP; 
     } else if (mySpritePos.y <= 0) { 
       this.myYDirection = VerticalDirection.DOWN; 
     } 

     /* Move the ball left or right */ 
     if (this.myXDirection == HorizontalDirection.RIGHT) { 
       this.mySpritePos.x += 10; 
     } else { 
       this.mySpritePos.x -= 10; 
     } 
     /* Move the ball up or down */ 
     if (this.myYDirection == VerticalDirection.DOWN) { 
       this.mySpritePos.y += 10; 
     } else { 
       this.mySpritePos.y -= 10; 
     } 

     /* Set the location, where the sprite 
     * will draw itself to the canvas */ 
     this.mySprite.setBounds(this.mySpritePos.x, this.mySpritePos.y, 
         this.mySpritePos.x + 50, this.mySpritePos.y + 50); 

     /* Make the sprite draw itself to the canvas */ 
     this.mySprite.draw(canvas); 
} 
} 

donc cela fonctionne parfaitement mais cela ne gère que d'un seul bloc. Je voudrais ajouter un bloc secondaire (en utilisant le même graphique) qui est géré par un thread séparé. Comment puis-je faire ceci? dois-je faire une vue séparée pour l'autre bloc?

Répondre

0

Le boucleur utilisé pour lire les messages que vous envoyez à partir de votre thread est threadsafe, mais il séquence également les messages reçus, ce qui signifie qu'il ne peut traiter que 1 msg à la fois. Bien que vous puissiez, en théorie, soumettre des messages à ce gestionnaire très facilement à partir de deux threads distincts, je ne suis pas sûr qu'il va accomplir ce que vous voulez. Je suppose que vous recherchez une sorte d'amélioration des performances de l'utilisation de plusieurs threads?

Si vous tentez d'obtenir un gain de performance, deux éléments sont à l'œuvre. Dans le code ci-dessus, la mise à jour de l'interface utilisateur est effectuée par un seul thread. Quel que soit le nombre de threads envoyés à myGUIUpdateHandler, un seul message est en cours de traitement à la fois. Cela peut causer des tonnes et des tonnes d'invalidations, mais votre scène entière est en train d'être redessinée. Deuxièmement, vous ne pouvez avoir qu'un seul thread modifiant les éléments de l'interface utilisateur Android. Si vous espériez avoir deux threads retravaillant indépendamment deux boîtes différentes en utilisant une vue, ce n'est pas possible. En fait, je ne sais pas s'il est possible de le faire même en utilisant les vues basées sur opengl, car je pense que opengl dépend aussi d'un concept de looper. Ma réponse serait que ce n'est pas possible, à moins que vous ne vouliez clarifier pourquoi vous avez besoin de deux threads pour que je puisse essayer de former une solution alternative.

+0

Salut Nick merci pour votre réponse. Fondamentalement, j'ai une application dans laquelle il y a plusieurs animations qui se compose de 1. Jauge RPM 2. MPH jauge 3. mouvement de roue 0steve la raison pour moi d'essayer le multithread sur chaque bloc comme vu dans le code ci-dessus est que je peux mettre en œuvre un design similaire dans mon application réelle avec les jauges et la roue. Depuis les jauges et la roue chaque animation est indépendante et doit fonctionner simultanément j'ai pensé que la meilleure façon est d'exécuter chaque animation dans chaque fil dans une seule vue. Est-ce qu'il y a une meilleure approche? –

+1

Logiquement, vous souhaitez que les valeurs des différents composants de votre interface utilisateur soient mises à jour indépendamment. La grande chose est que, peu importe le nombre d'éléments ui que vous créez, il y a toujours un thread (les gens appellent cela des choses différentes comme 'ui thread' ou 'thread d'application') qui est le seul élément autorisé à mettre à jour les éléments ui. Donc, c'est un objectif de conception important pour séparer vos données de votre dessin. Vous avez besoin d'éléments de données mis à jour à partir de nombreux threads. Ceux-ci contiendraient des valeurs comme 'currentRPMs', etc. Ensuite, votre thread ui doit simplement comprendre comment dessiner cela à l'écran. –

+0

qui fait beaucoup de sens grâce à nick –