2011-06-08 100 views
0

我想在我的应用程序中实现多线程,我想知道我该如何做到这一点。基本上在一个视图中,我有2个块,我希望这两个块在屏幕上反弹,但是我希望每个块都在它自己的线程上运行。所以单视图多线程...如果这是可能的。这是我到目前为止有:Android:动画和多线程

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(); 
        } 
      } 
    } 
} 


} 

我BounceView是:

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); 
} 
} 

所以这个工作完全然而这仅处理一个块。我想添加一个由单独线程处理的辅助块(使用相同的图形)。我怎样才能做到这一点?我是否必须为另一个区块制作单独的视图?

回答

0

用于读取从线程发送的消息的Looper是线程安全的,但也会对接收到的消息进行排序,这意味着它在任何给定时间只能处理1 msg。理论上,你可以很容易地从两个不同的线程向这个处理程序提交消息,但我不确定它会完成你想要的。我假设你使用多线程寻求某种性能提升?

如果您试图获得性能提升,有两件事情对您不利。在上面的代码中,UI更新由单个线程完成。无论有多少线程向myGUIUpdateHandler发送消息,一次只能处理一条消息。这可能会导致无数次失效,但您的整个场景正在重绘。其次,你只能有一个线程修改Android UI元素。如果你希望有两个线程独立重绘使用View的两个不同的盒子,这是不可能的。实际上,即使使用基于opengl的视图,我也不知道是否可以这样做,因为我认为opengl也依赖于looper概念。

我的答案是,它是不可能的,除非你想澄清为什么你需要两个线程,以便我可以尝试形成一个替代解决方案。

+0

嗨尼克感谢您的回复。基本上我有一个应用程序,其中有多个动画,其中包括1. RPM Gauge 2. MPH Gauge 3.方向盘运动 我试图在上面的代码中看到的每个块上的多线程的原因是,我可以在我的实际应用中使用量表和车轮实施类似的设计。由于使用量表和轮子,每个动画都是独立的,需要同时运行,我认为最好的方法是在单个视图中的每个线程中运行每个动画。有更好的方法吗? – 2011-06-08 14:30:30

+1

逻辑上,您希望独立更新UI的不同组件的值。最重要的是,无论你制作多少个UI元素,总是有一个线程(人们称之为“UI线程”或“应用程序线程”),这是唯一允许更新UI元素的元素。所以,它是将数据与绘图分开的重要设计目标。您需要从多个线程更新的数据元素。这些将包含像'currentRPMs'等值。然后,您的UI线程需要简单地了解如何将其绘制到屏幕上。 – 2011-06-08 18:48:06

+0

这使得很多感谢尼克 – 2011-06-08 19:40:25