这是Android线程的安全使用吗?

时间:2015-07-24 21:23:37

标签: java android multithreading imageview

我使用vanilla Android SDK和线程在Android中创建了一款游戏。我的大部分游戏逻辑都包含在Runnables中,它们被发布到Handlers或Views。

例如:

发布可运行到视图并在runnable中编辑该视图

private int currentRotation =0;
private Runnable rotateRunnable = new Runnable(){
    @Override
    public void run() { 
        currentRotation+=DEFAULT_ROTATION_SPEED * direction;
        Gravity_MeteorView.this.setRotation(currentRotation);
        Gravity_MeteorView.this.postIfAlive(this,2*MovingView.HOW_OFTEN_TO_MOVE);
    } 
};
public Gravity_MeteorView(Context context) {
    super(context);//ImageView

    //...
    this.post(rotateRunnable);
}

将Runnable发布到处理程序并编辑Runnable中的某些视图

Handler spawningHandler = new Handler();
public final void spawnMeteorShower(final int numMeteors,final int millisecondsBetweenEachMeteor) {
    spawningHandler.post(
            new Runnable(){
            private int numSpawned=0;

            @Override
            public void run() {
                Gravity_MeteorView bob = new Gravity_MeteorView(context);
                someLayout.addView(bob);
                //...
                if(numSpawned<numMeteors){
                    spawningHandler.postDelayed(this,millisecondsBetweenEachMeteor);
                }
           }
       });
}

大多数情况下一切正常。流星一直产生并旋转。但是,非常非常罕见,流星会产生但是看不见并且不受损害。我想知道这些奇怪的错误是否可能是由于我对游戏线程的处理不当造成的。

我在Android文档中注意到了

  

[修改]来自工作线程而不是UI线程的ImageView会导致未定义和意外的行为,这可能很难追踪并且非常耗时。

http://developer.android.com/guide/components/processes-and-threads.html

似乎第一个片段可能没问题,而第二个片段可能会导致问题(如果它没有在UI线程或其他东西上运行)。我是否违反了Android最佳做法?

谢谢!

1 个答案:

答案 0 :(得分:1)

  

似乎第一个片段可能没问题,而第二个片段可能会导致问题(如果它没有在UI线程或其他东西上运行)。我是否违反了Android最佳做法?

spawningHandler附加到UI线程Looper,因为您在那里使用View。否则你会崩溃,因为你不能从工作线程那样做。

它是线程安全的,因为没有并行执行。您发布的所有Runnable转到同一MessageQueue。我没有看到您发布的代码中的线程问题。