2012-01-20 50 views
1

我在更新每隔x秒的android视图时遇到问题。Android:在x秒后多次更新gridview

要了解Android的工作方式,我正在写一个小游戏。 它有一个GameController来保存游戏循环。在循环内部,逻辑被执行,然后gui将被通知变化。

问题是在视图中看不到变化。视图保持不变,直到游戏循环完成并更新一次。

这里是我的代码(重要部件):

GameController.java:

IGui gui; 

public void play() { 
    while (playing) { 
     getAndProcessInput(); 
     updateGui(); 
     try { 
      Thread.sleep(500); 
     } catch (InterruptedException ex) { 
     } 
    } 
} 

private void updateGui() { 
    gui.setPlayer(x, y); 
    // ... 
} 

GameActivity.java:

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    GridView gridview = (GridView) findViewById(R.id.GridView1); 
    TextAdapter = new TextAdapter(this); 
    gridview.setAdapter(textAdapter); 

    GameController c = new GameController(); 

    // here, the game loop shoud start. 
    // what i tried: 

    // new Thread(c).start(); <-- causes crash 

    // c.play();  <-- causes view to frease until game loop is done 

    this.runOnUiThread(c); <-- causes view to frease until game loop is done 
} 

TextAdapter.java:

public class TextAdapter extends BaseAdapter implements IGui { 

    private final Context context; 
    private final String[] texts; 

    public TextAdapter(Context context) { 
     this.context = context; 
     texts = new String[height * width]; 
     for (int i = 0; i < texts.length; i++) { 
      texts[i] = " "; 
     } 
    } 

    public int getCount() { 
     return height * width; 
    } 

    public Object getItem(int position) { 
     return null; 
    } 

    public long getItemId(int position) { 
     return position; 
    } 

    public View getView(int position, View convertView, ViewGroup parent) { 
     TextView tv; 
     if (convertView == null) { 
      tv = new TextView(context); 
      tv.setLayoutParams(new GridView.LayoutParams(25, 25)); 
     } else { 
      tv = (TextView) convertView; 
     } 

     tv.setText(texts[position]); 
     return tv; // <-- this happens only when game loop is done, not everytime something changed 
    } 

    @Override 
    public void setPlayer(int x, int y) { 
     texts[width * y + x] = "X"; 
     // this.notifyDataSetChanged(); <-- this does not help (view still freases) 
     //         gridview.invalidateViews(); does not help either 
    } 
} 

我google很多,并尝试了很多(我已经知道类似的问题,在这里已经问过,但他们也没有帮助我),但不知何故,它不起作用。 我无法得到它的工作,视图和逻辑运行在android中的不同角色,如果他们在同一个线程上运行的逻辑块视图。 任何帮助将不胜感激。

//编辑:

如果我尝试新的Thread(C)。开始(); logcat的赛斯: 了java.lang.RuntimeException:无法内螺纹已不叫Looper.prepare()

如果我添加Looper.prepare()创建的处理程序; : 了java.lang.RuntimeException:无法启动活动ComponentInfo {} GameActivity:了java.lang.RuntimeException:只有一条环线可以每个线程

如果我尝试this.runOnUiThread(三)创建;没有错误。

+0

堆栈跟踪告诉你什么?无法触及非UI视图的视图? – Rotemmiz

+0

我更新了我的问题,以便阅读。 – tim

回答

2

首先,这看起来并不像打包游戏的方式,您需要使用SurfaceViewGLSurfaceView来更好地做你想做的事情。 你也可以找Android的Cocos2d,它是一个2D平台(从iPhone移植过来),让你的生活更轻松: http://code.google.com/p/cocos2d-android/ 虽然我试过了几个月,但它不是生产级别但它不时崩溃。

无论如何,如果你仍然想继续前进的方式,我会尝试回答你的问题: 我认为你这些东西应该工作的方式太多。先尝试理解处理程序如何处理线程。

您是否想在你的线程东西:

new Thread(new Runnable() 
      { 
       @Override 
       public void run() 
       { 
        try 
        { 
         calculateGameChangesHere(); 
         handler.sendEmptyMessage(SUCCESS); 
        } 
        catch (Exception e) 
        { 
         handler.sendEmptyMessage(FAILURE); 
        } 
       } 
      }).start(); 

当你的数据准备好,告诉处理程序把它放在一个视图,并显示它:

protected Handler handler = new Handler() 
    { 
     @Override 
     public void handleMessage(Message msg) 
     { 
      if (msg.what == SUCCESS) 
      { 
       setCalculatedDataToaView(); // the data you calculated from your thread can now be shown in one of your views. 
      } 
      else if (msg.what == FAILURE) 
      { 
       errorHandlerHere();//could be your toasts or any other error handling... 
      } 
     } 
    }; 

这正好一切需要大量的处理/网络,不应该阻止你的UI线程。

希望这会有所帮助。

+0

谢谢你,我用它来处理它。但我肯定会研究SurfaceView,并在将来使用它。 – tim

0

不知道你想通过每隔几秒钟刷新一次listView来达到什么目的。无论如何,如果你正在写一些2D游戏,你必须使用SurfaceView,这是特别意味着持续刷新。

0

有相同的问题,并用一个非常简单的代码解决它。

提示:

  • GridView控件必须在UI线程刷新
  • 显示每一个改变,你必须保持环和睡眠方法从UI线程


解决方案:

  • 方法来更新网格(把你的活动,你首先建立你的GridView或其它地方)

    public void UpdateGrid(){ 
    //your logic 
    
    //your way to change grid values (there are tones of other ways) 
    CustomGridAdapter cga = new CustomGridAdapter(this, values); 
    
    gridView.setAdapter(cga); 
    gridView.invalidateViews(); 
    

    }

  • 构建非UI线程做的工作

公共类DataReceiver实现Runnable {

private MainActivity mainActivity; 

public DataReceiver(MainActivity ma) { 
    mainActivity = ma; 
} 

@Override 
public void run() { 

    for (int i = 0; i < 100; i++) { 

     mainActivity.runOnUiThread(new Runnable() { 
      public void run() { 
            //update the grid here 
       mainActivity.UpdateGrid(); 

      } 
     }); 
         //sleep here 
     try { 
      Thread.sleep(1000); 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 

} 

}