2012-01-26 55 views
2

我寫了一個遊戲(我給它取名爲「玩家」),其中我有以下的一般結構(代碼已經大大簡化):android應用程序的主線程在哪裏?

public class Gamer extends Activity implements View.OnClickListener 
{ 
    public void onCreate(Bundle savedInstanceState) 
    { 
     mpt = new MicksPanelThing(this); 
    } 
} 
public class MicksPanelThing extends SurfaceView implements SurfaceHolder.Callback 
{ 
    public MicksPanelThing(Context context) 
    { 
     super(context); 
     micks_thread_thing = new MicksThreadThing(getHolder(), this); 
     getHolder().addCallback(this); 
     setFocusable(true); 
    } 
    void updateView() 
    { 
     final SurfaceHolder holder = getHolder(); 

     try 
     { 
      Canvas canvas = holder.lockCanvas(); 
     if(canvas != null) 
      { 
      onDraw(canvas); 
      holder.unlockCanvasAndPost(canvas); 
     } 
     } 
     catch (Exception e) 
     { 
     e.printStackTrace(); 
     } 
    } 
    public void onDraw(Canvas canvas) 
    { 
     // blah 
    } 

} 
class MicksThreadThing extends Thread 
{ 
    public MicksThreadThing(SurfaceHolder surfaceHolder, MicksPanelThing mpt) 
    { 
     // blah 
    } 
    public void run() 
    { 
     while (this_thread_is_currently_active) 
     { 
      micks_panel_thing.updateView(); 
     } 
    } 
} 

本場比賽是所有工作的罰款和非常健壯。現在我想測試一個特定的條件,如果它是真的,則建立一個AlertDialog。我推測我可以把這段代碼放在我的onDraw方法中。然後我得到一條消息:「不能在線程內創建沒有調用Looper.prepare()的處理程序」 - 這讓我感到困惑,因爲我認爲onDraw方法正在被我認爲不需要的主線程執行設置任何東西。

我認爲我可以通過將我的測試和對話框移動到主線程(其中?)的某處或通過在某處添加一些Looper.prepare()代碼來解決此問題。

請有人告訴我哪個更容易 - 哪裏需要代碼。

回答

2

嘗試使用方法:runOnUIThread()迫使該應用上mainThread(這是UIThread)運行代碼,例如:

class MicksThreadThing extends Thread 
{ 
    public MicksThreadThing(SurfaceHolder surfaceHolder, MicksPanelThing mpt) 
    { 
     // blah 
    } 
    public void run() 
    { 
     Gamer.this.runOnUiThread(new Runnable(){ 
     @Override 
     public void run(){ 
      //update/create your views here 
      while (this_thread_is_currently_active) 
      { 
       micks_panel_thing.updateView(); 
      } 
     } 
    }); 
    } 
} 

其他的解決方案是:代替使用Thread,您可以使用AsyncTask

+0

這段代碼在哪裏? – Mick

+0

你說你想從你的線程顯示你的對話框,所以你的線程無法觸及或修改UI,唯一可以做到這一點的線程是UIThread,所以強制你的線程修改UI(創建對話框,視圖,修改視圖...等等)你應該重寫方法runOnUIThread()來強制你的線程在UIThread中運行該代碼, – Houcine

+0

或者你可以使用AsyncTask – Houcine

0

您可以撥打MicksThreadThing的onDraw(canvas);。顯然,它不是應用程序的主線程。主線程是你的活動的onCreate()被調用的那些線程。

0

您無法從普通線程更新UI。 使用runOnUiThread()更新UI。

1

做到這樣:

class MicksThreadThing extends Thread 
{ 
    public MicksThreadThing(SurfaceHolder surfaceHolder, MicksPanelThing mpt) 
    { 
     // blah 
    } 
    public void run() 
    { 
     while (this_thread_is_currently_active) 
     { 
      //micks_panel_thing.updateView(); 

      Gamer.this.runOnUiThread(new Runnable(){ 
       @Override 
       public void run(){ 
        micks_panel_thing.updateView(); 
       } 
      }); 
     } 
    } 
} 
+0

是否在運行內運行錯字? – Mick

+0

不......運行裏面Gamer.this.runOnUiThread會在你的UI線程上執行 – waqaslam

+0

嗯......代碼編譯 - 我看到遊戲狀態被繪製,但是它被凍結 - 沒有響應任何觸摸事件。 ..有什麼你可能已經忘記? – Mick

0

主線程是ui線程...因此您可以在AsyncTask中使用HandleronPostExecute() or onPreexecute()

相關問題