0

我是 android sdk 的新手,所以请不要对我苛刻。atm 我正在使用我的第一个 android 应用程序 .. 它几乎完成了,但我现在面临一个小问题。

该应用程序是一个小型单人纸牌游戏,有 4 名玩家 - 3 个电脑敌人。

问题是,在我移动之后.. 计算机敌人正在根据 ki 逻辑进行移动.. 这工作得很好.. 但在方法结束后只显示玩家 4 的最后一步。即使我在每次 ki move 之后延迟方法过程 .. 它也不会更新 ImageViews 以显示当前的 ki move ...

我真的很迷茫..因为我找不到任何逻辑错误..我感谢任何形式的帮助..感谢阅读-不是以英语为母语的人对此表示遗憾:-)

好的,这里有一些代码.. 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);   
    }

sort() 看起来像这样:

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文档我还没有找到解决我问题的真正解决方案。

我想做的是:在 SORT() 之后强制主 UI 线程更新 .. 像这样:

 @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 玩家进入一个循环来完成它.. 我无法在这个循环中分层访问主 ui.. 所以我又来了。

我不明白.. 我花了大约 2 周的时间来实现逻辑.. 因为这个游戏的规则非常特别.. 现在它按预期运行,ki 很聪明.. 它失败的原因是 UI LOCKS UP ..对此感到羞耻..

4

1 回答 1

0

代码对我来说看起来有点复杂,但如果我理解得很好,在 setImageBitmap() 之后在 dkView1 上调用 invalidate() 可以解决问题。

但这里有一个提示,如果可能的话,尽量使用 drawable 而不是 Bitmap。

于 2013-03-18T11:48:03.250 回答