Java 主Ui线程在方法过程中不更新
我是android sdk新手,所以请不要对我太苛刻。atm我正在使用我的第一个android应用程序。。差不多完成了,但我现在面临一个小问题 该应用程序是一款小型单人纸牌游戏,有4名玩家-3名电脑敌人 问题是在我采取行动之后。。计算机的敌人正在根据ki逻辑采取行动。。这样做很好。。但是只有玩家4的最后一步才会在方法结束后显示。即使我在每次ki移动后延迟方法过程。。它不会更新ImageView以显示当前的ki移动 我真的很迷路。。因为我找不到任何逻辑错误。。我感谢任何帮助。。thx用于阅读-非母语为英语的sry用于阅读:-) 好的,这里有一些代码。。cardDeck保持当前移动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用于阅读-非母
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为我提供了线程、无痛线程、异步任务。。哇,谢谢你
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);
}