Java 主Ui线程在方法过程中不更新

Java 主Ui线程在方法过程中不更新,java,android,eclipse,user-interface,android-imageview,Java,Android,Eclipse,User Interface,Android Imageview,我是android sdk新手,所以请不要对我太苛刻。atm我正在使用我的第一个android应用程序。。差不多完成了,但我现在面临一个小问题 该应用程序是一款小型单人纸牌游戏,有4名玩家-3名电脑敌人 问题是在我采取行动之后。。计算机的敌人正在根据ki逻辑采取行动。。这样做很好。。但是只有玩家4的最后一步才会在方法结束后显示。即使我在每次ki移动后延迟方法过程。。它不会更新ImageView以显示当前的ki移动 我真的很迷路。。因为我找不到任何逻辑错误。。我感谢任何帮助。。thx用于阅读-非母

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

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

问题是在我采取行动之后。。计算机的敌人正在根据ki逻辑采取行动。。这样做很好。。但是只有玩家4的最后一步才会在方法结束后显示。即使我在每次ki移动后延迟方法过程。。它不会更新ImageView以显示当前的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);   
    }
ki4Moves()看起来是这样的:

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);
    }
}
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为我提供了线程、无痛线程、异步任务。。哇,谢谢你

  • 程序不是很繁重。。。没有数据库操作等
  • 如果我使用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)”。。。我不能让它加入。。因为正如我所说,主ui线程将被锁定。所以我需要将Ki4Move中的200行代码也打包成线程

    你看,这是有效的。。一举一动之后。。主ui已更新

    BUUUT ki4Moves是最简单的方法之一。。如果我通过了那怎么办。。cpu播放器进入一个循环来完成它。。我无法在此循环中分层访问主ui。。我又来了


    我不明白。。我花了两周的时间来实现这个逻辑。。因为这个游戏的规则很特别。。现在它按预期运行,ki很聪明。。由于UI锁定,它失败。。真可耻

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


    但这里有一个提示,如果可能的话,尝试使用可绘制而不是位图。

    给我们看一些代码。。。。你在图像视图中使用invalidate()吗?我添加了一些代码。。不,我没有使用invalidate()我希望invalidate能够解决问题,但它没有..:-(…我只使用1个主框架和其中的ImageView和按钮..这就像在过程中框架冻结,并在过程完成时显示最后的信息..我将查看drawable doc..thx以了解thoWell,如果在过程中冻结,它可能太重,应该放在AsyncTask中…而不是调用集中ImageBitmap()使用在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);   
        }