2013-03-18 82 views
0

我是android sdk的新手,所以請不要苛刻我。 atm我在我的第一個Android應用程序..它幾乎完成,但我現在面臨一個小問題。主要Ui線程不會在方法過程中更新

該應用程序是一個小型單人玩家與4名玩家 - 3個電腦敵人。

問題是,在我做了一個動作之後,計算機敵人正在根據ki邏輯做他們的動作..而且工作得很好..但是隻有最後一招可以說玩家4在方法結束。即使我延遲每個ki移動後的方法過程..它不更新ImageViews顯示當前ki移動...

即時通訊真的很迷路..因爲我找不到任何邏輯錯誤..我明白任何形式的幫助.. THX閱讀 - 不以英語爲母語SRY爲:-)

好吧這裏去一些代碼.. cardDeck保持當前的移動

List<Card> cardDeck = new ArrayList<Card>(); 
List<Card> move = new ArrayList<Card>(); 
KI player2 = new KI(); 

but.setText("GO"); 
but.setOnClickListener(new OnClickListener() { 

@Override 
public void onClick(View vw) { 

if (!move.isEmpty()) { 

    if (Rules.checkIsPlayableHand(move)) { 
    sort(); 
    setClickAble(); 
     ki4Moves(vw); 
    } 

排序()看起來有點其中:

public void sort(){ 

    cardDeck.clear(); 
    cardDeck.addAll(move); 

    if (cardDeck.size() == 1) { 
     dkView1 = (ImageView) findViewById(R.id.dkView1); 
     Card card = cardDeck.get(0); 
     dkView1.setImageBitmap(card.getBitmap()); 
    } else { 
     dkView1 = (ImageView) findViewById(R.id.dkView1); 
     dkView1.setImageBitmap(blank); 
    } 
} 

和ki4Moves()看起來的這樣:

public void ki4Moves(View vw){ 

    player2.think(); 
    List<Card> kiMove = new ArrayList<Card>(); 
    kiMove = player2.getPossibleMove(cardDeck); 

    if (!kiMove.isEmpty()) { 

     trash.addAll(kiMove); 
     move.clear(); 
     move.addAll(kiMove); 
     sort(); 
    } 
    // same for the other both ki s 
} 

編輯:

後以及一些研究..閱讀的Android文檔我還沒有找到我的問題真正解決問題。

就是我想要做的是:強制主UI線程更新後的sort()......這樣的:

@Override 
public void onClick(View vw) { 

if (!move.isEmpty()) { 

    if (Rules.checkIsPlayableHand(move)) { 
    sort(); 
      // FORCE MAIN UI THREAD TO UPDATE .. just one line 
      // let SystemClock.sleep(2000); 
    setClickAble(); 
     ki4Moves(vw); 
    } 

現在..我不能強迫主線程更新或外部訪問它主線程。ANDROID爲我提供了線程,無痛線程,異步任務..哇感謝!

  1. 的過程不重加載中...沒有數據庫操作等
  2. 如果我使用的Thread.join ...主UI線程仍然鎖定

所以首先..我沒有看到任何邏輯理由使用線程..但我肯達要?所以還好這裏,我去..可以說,我改變這樣我的代碼:

Handler h = new Handler(); 
@Override 
public void onClick(View vw) { 

if (!move.isEmpty()) { 

    if (Rules.checkIsPlayableHand(move)) { 

      Thread t = new Thread(new Runnable){ 

       void run(){ 
       h.post(new Runnable(){ 
        // do some logic here 
       }); 
       h.post(new Runnable(){ 
        if (cardDeck.size() == 1) { 
       dkView1 = (ImageView) findViewById(R.id.dkView1); 
      Card card = cardDeck.get(0); 
      dkView1.setImageBitmap(card.getBitmap()); 
       } else { 
      dkView1 = (ImageView) findViewById(R.id.dkView1); 
      dkView1.setImageBitmap(blank); 
       } 
       }); 
       Thread.sleep(2000); 
       } 
      }); 
      t.start(); 

    setClickAble(); 
     ki4Moves(vw); 
    } 

所以你們這是工作的罰款。但哦..還有就是這種方法「ki4Moves(VW)」 ......我不能讓它t.join()..因爲我說主要的UI線程將被鎖定。所以我需要將ki4Moves中的200條線擦寫成線程以及..

和你們這是工作..在每一步之後..主要的用戶界面被更新。

BUUUT ki4Moves是最簡單的方法之一..如果我通過移動..和CPU播放器進入一個循環完成它..我不能在這個循環訪問主要用戶界面..所以那裏我再次。

我沒有得到它..它花了我2周的時間來實現邏輯..作爲這場比賽的規則是非常特殊的..現在,它是按預期運行,奇是智能..它失敗的原因的UI LOCKS UP ..恥辱在這..

+2

向我們展示一些代碼....並且您在圖像視圖中使用invalidate()嗎? – 2013-03-18 10:53:11

+0

我添加了一些代碼..並沒有我沒有使用invalidate() – user1386375 2013-03-18 11:38:29

回答

0

這段代碼對我來說看起來很複雜,但是如果我理解的很好,在setImageBitmap()之後調用dkView1上的invalidate()就可以解決問題。

但是,這裏有一個提示,如果可能,儘量使用drawable而不是Bitmap。

+0

我希望無效將解決問題,但它沒有.. :-(..我只使用1主框架和ImageViews和按鈕。 。它像框架在程序中凍結,並顯示過程完成後的最後信息...我會看看可繪製的文件.. thx關心壽 – user1386375 2013-03-18 12:08:55

+1

好吧,如果它在過程中凍結它可能太重並應放置在AsyncTask中...並且使用在UI線程創建的Handler調用setImageBitmap()。 – 2013-03-18 13:47:17