Java 在android中为循环添加延迟,而不暂停UI线程
我已经查看了所有Android Studio文档和StackOverflow,但我似乎找不到一种方法来做与IOS中相同的事情: 在Android中 我尝试使用处理程序,但没有像下面那样运行代码:Java 在android中为循环添加延迟,而不暂停UI线程,java,android,Java,Android,我已经查看了所有Android Studio文档和StackOverflow,但我似乎找不到一种方法来做与IOS中相同的事情: 在Android中 我尝试使用处理程序,但没有像下面那样运行代码: // Iteration 1 // Delay of 500ms // Iteration 2 // Delay of 500ms // ... 代码的运行方式如下所示: // Iteration 1 // Iteration 2 // Delay of 500ms // next state 我使
// Iteration 1
// Delay of 500ms
// Iteration 2
// Delay of 500ms
// ...
代码的运行方式如下所示:
// Iteration 1
// Iteration 2
// Delay of 500ms
// next state
我使用的代码结构如下:
Handler myHandler = new Handler();
while (someCondition) {
myHandler.postDelayed(new Runnable() {
public void run() {
myFunction();
}
}, 500);
}
我在运行此活动时看到的行为是跳过它,500毫秒后它进入下一个活动(具有预期的结果),但不向用户显示发生了什么
我如何延迟循环,以便用户可以看到发生了什么
克拉维: 在再次执行while循环的逻辑之前,需要显示当前状态(在moveCard()之后)x ms 直到达到最终状态为止 然后开始下一个活动
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.horserace_游戏);
this.cardDeck=findviewbyd(R.id.deck);
this.game_end=false;
this.deck=新deck();
this.aces=新的ArrayList();
this.acesPos=新的ArrayList();
this.hidden=new ArrayList();
//移除甲板上的所有ACE,并将其放入ACE中
//resetDeck在面上创建一个有序的数据组(因此Ace SDH、两个SDH等),这非常方便。
本.甲板.重置甲板(1);
对于(int i=0;i<4;i++){
this.aces.add(this.deck.removeCard(0));
//为卡添加新的pos
本.acesPos.add(0);
}
//洗牌
this.deck.shuffleDeck();
//从牌组顶部取出7张牌放在牌组上
//并将其正面朝下放置在屏幕上
对于(int i=0;i<7;i++){
this.hidden.add(this.deck.removeCard(0));
}
//当游戏仍在进行时,从牌组中选择一张牌,并用相同的套装移动王牌
而(!这场比赛结束了){
//从牌组中选择下一张牌
this.next=this.deck.removeCard(0);
setImageResource(getCardImage(下一个));
//找到和这套衣服一样的王牌。下一步,将其设置为“得分”++
对于(卡片ace:this.aces){
如果(ace.getSuit().equals(next.getSuit())){
this.acesPos.set(ace.getSuit().ordinal(),this.acesPos.get(ace.getSuit().ordinal())+1);
打破
}
}
//最终状态:最后一个ace的pos>7,此ace为结果。开始新活动
if(this.acesPos.get(next.getSuit().ordinal())>7){
this.game_end=true;
意向赢家=新意向();
winner.putExtra(“winner”,next.getSuit().ordinal());
setResult(结果确定,获胜者);
完成();
//如果王牌不在最后位置,移动它
//并在下一次迭代中选择一张新卡。
}否则{
//移动卡
myHandler.postDelayed(新的Runnable(){
公开募捐{
Log.e(“运行:”,“移动卡”);
moveCard();
}
}, 500);
}
}
}
moveCard()并等待移动到新的目的地:
while (!this.game_ended) {
// Pick the next card from the deck
this.next = this.deck.removeCard(0);
cardDeck.setImageResource(getCardImage(next));
// Find the ace with the same suit as this.next and set it's 'score'++
for (Card ace : this.aces) {
if (ace.getSuit().equals(next.getSuit())) {
this.acesPos.set(ace.getSuit().ordinal(), this.acesPos.get(ace.getSuit().ordinal()) + 1);
break;
}
}
// Final state: the last ace now has a pos >7, this ace is the result. start new Activity
if (this.acesPos.get(next.getSuit().ordinal()) > 7) {
this.game_ended = true;
myHandler.postDelayed(new Runnable() {
public void run() {
Intent winner = new Intent();
winner.putExtra("winner",next.getSuit().ordinal());
setResult(RESULT_OK, winner);
finish();
}
}, 500);
// If the ace is not at it's final position, move it
// and pick a new card in the next iteration.
} else {
// Move card
Log.e("run: ", "moveCard");
moveCard();
}
}
也许创造这样的东西应该有用
protected static void startTimer() {
timer.schedule(new TimerTask() {
public void run() {
mHandler.obtainMessage(1).sendToTarget();
}
}, 500);
}
public Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
myFunction();
}
};
考虑使用
计时器
,这是一种轮询模型,其中计时器将独立运行,并根据您定义的频率在关联的计时器任务
中执行代码
Timer timer = new Timer();
timer.schedule (new TimerTask()
{
@Override public void run()
{
// your program logic here
if (game_ended)
return;
// Pick the next card from the deck
next = deck.removeCard(0);
.
.
.
}
}, 0, 500);
这将立即启动计时器,触发器之间有500毫秒的延迟。每次计时器触发时,TimerTask中的run()
方法将执行
在
onCreate
中创建计时器,在onResume
中启动/计划计时器,在onPause
中停止计时器。在TimerTask run()方法中,您可以移动程序逻辑。取决于您如何进入下一个活动,但它应该发生在run()函数中的myFunction()之后“我如何延迟循环,以便用户可以看到发生了什么?”--您没有任何表示“发生了什么”的代码。您可能希望将您的代码扩展为您正在运行的实际代码。通常,在onCreate()中有类似这样的循环或类似的方法是一个注定要失败的方法。希望有一个更具代表性的人给我们推荐一个替代的方法。谢谢,我在下一个活动中添加了一个解释:“皮尔兰谢谢你的回应”@ CommonsWare,我也加入了我的OnCube函数。考虑一下我的答案,我已经使用了TimeTaskA。我想这应该可以解决你的问题。我添加了其他注释,我正在等待最终状态,但我的目标是在每个moveCard()之间进行转换(无动画),这样用户就可以看到卡片在移动。也许我不明白,你怎么知道最终状态已经达到?通过一个变量?一个函数?如果是这样,你可以设置一个重复计时器来检查该状态,或者如果它是一个函数,则在该函数的末尾移动到intent this.acesPos.get(next.getSuit().ordinal())>7 this.acesPos是一个数组列表,其中包含每张卡片的当前分数。next.getSuit().ordinal()返回下一步拥有的套装类型的索引。如果当前pos为8,那么>7,则达到最终状态。@Pearloh,但你说你的卡可能仍在移动。我不明白为什么你不能将我发布的代码移动到移动的末尾,所以当移动完最后一张卡时,它会检查游戏是否结束并移动到下一个活动?Unl如果你有多张牌同时移动,那么你只需要一个计数器,当你调用移动卡时计数器上升,当它结束时计数器下降,然后你检查游戏是否结束,计数是否为0。如果卡的位置不大于7,则该卡只移动,因为当它是时,它是赢家,因此我开始显示该卡的新活动需要的是逻辑->移动卡()->等待x毫秒->继续逻辑
Timer timer = new Timer();
timer.schedule (new TimerTask()
{
@Override public void run()
{
// your program logic here
if (game_ended)
return;
// Pick the next card from the deck
next = deck.removeCard(0);
.
.
.
}
}, 0, 500);