2012-01-20 49 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(); 
     } 
    } 

} 

}