2017-05-26 81 views
1

所以大家好,這是我的第一篇文章中的計算器, 和我在1個問題得到stucked,延遲在for循環中,使麪包每2秒

的問題是: 哪能裏面添加一個延遲for循環

我做了很多研究,但都沒有工作 所以我決定問自己。

這裏是我的代碼

Handler handler1 = new Handler(); 

for (langId = 1; langId <= 3; langId++) { 
       handler1.postDelayed(new Runnable() { 
        @Override 
        public void run() { 
         if (langId == 1) { 
          Toast.makeText(KCRdestActivity.this, "1", Toast.LENGTH_LONG).show(); 
          delayTime += 2000; 
         } 
         if (langId == 2) { 
          Toast.makeText(KCRdestActivity.this, "2", Toast.LENGTH_LONG).show(); 
          delayTime += 2000; 
         } 
         if (langId == 3) { 
          Toast.makeText(KCRdestActivity.this, "3", Toast.LENGTH_LONG).show(); 
          delayTime += 2000; 
         } 
        } 
       }, delayTime); 
      } 

所以結果我想要的是:

"1" -> 2000ms -> "2" -> 2000ms -> "3" 

任何想法?

我試過Thread.sleep(2000),它工作,但它凍結了應用程序,我需要在該過程中做額外的事情。

編輯

問題解決了,這是工作的代碼,也是我的最終目標

 playBtn2.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      final Handler handler1 = new Handler(); 

      langId = 1; 
      max = 1; 
      delayTime = 0; 
      selectedMP = 1; 
      if (((RadioButton) findViewById(R.id.noneDepart)).isChecked()) max = 3; 
      else max = 6; 

      handler1.post(new Runnable() { 
       @Override 
       public void run() { 
        if (((RadioButton) findViewById(R.id.noneDepart)).isChecked()) { 
         String destdir = "KCR/Depart/" + Utils.getDestID(selectedDest) + "_"; 
         if (viaRAC.isChecked()) destdir = destdir + "via_rac_"; 
         destdir = destdir + langId + ".mp3"; 
         if (selectedMP == 1) { 
          try { 
           afd = getAssets().openFd(destdir); 
           mp1.reset(); 
           mp1.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength()); 
           mp1.prepare(); 
           mp1.start(); 
           //Utils.RunOnUiThread(KCRdestActivity.this, mp1, sb1); 
           ((Button) findViewById(R.id.Play1)).setText("❙❙"); 
           selectedMP = 2; 
           delayTime = mp1.getDuration() - 130; 
           Toast.makeText(KCRdestActivity.this, delayTime + "##" + destdir, Toast.LENGTH_LONG).show(); 

          } catch (Exception e) { 
           e.printStackTrace(); 
          } 
         } else { 
          try { 
           afd = getAssets().openFd(destdir); 
           mp2.reset(); 
           mp2.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength()); 
           mp2.prepare(); 
           mp2.start(); 
           //Utils.RunOnUiThread(KCRdestActivity.this, mp1, sb1); 
           ((Button) findViewById(R.id.Play1)).setText("❙❙"); 
           selectedMP = 1; 
           delayTime = mp2.getDuration() - 130; 
           Toast.makeText(KCRdestActivity.this, delayTime + "##" + destdir, Toast.LENGTH_LONG).show(); 

          } catch (Exception e) { 
           e.printStackTrace(); 
          } 
         } 

        } 
        if (langId > 3) { 
         return; 
        } 
        langId++; 
        handler1.postDelayed(this, delayTime); 
       } 
      }); 
     } 
    }); 
+0

你能描述一下你爲什麼要原因要做到這一點 ? –

+0

postDelayed意味着運行中的代碼塊將在延遲時間後觸發。這意味着延遲時間值在運行函數被調用之前已經被引用。 – tompee

+0

此外,與postDelayed形成鮮明對比的是,循環同步執行。因此,在第一次運行被調用之前,循環有很高的完成執行的可能性,這意味着延遲總是相同的。 – tompee

回答

0

有沒有必要寫的代碼,多行,試試這個:

Handler handler1 = new Handler(); 
int langId = 1; 
handler1.post(new Runnable() { 
       @Override 
       public void run() { 
        if (langId > 3) { 
         return; 
        } 
        Toast.makeText(KCRdestActivity.this, String.valueOf(langId++), Toast.LENGTH_LONG).show(); 
        handler1.postDelayed(this, 2000); // If delay time is constant! 
       } 
}); 
+0

非常感謝你!!!!!你的代碼完美工作 – i998979

+0

@ i998979隨時歡迎來到:) –

0

您可以在doInBackground方法

0

您使用asyntask用了Thread.sleep(2000)沿需要將代碼移出run方法並直接放入for循環。在運行方法中只放置敬酒。

實現定時器任務,每2秒後安排其

int value = 1; 
Timer timer = new Timer(); 


TimerTask task = new TimerTask() { 
    @Override 
    public void run() { 
     Toast.makeText(KCRdestActivity.this, value, Toast.LENGTH_LONG).show(); 
     value++; 
    } 
}; 

timer.schedule(task, 2000); 

OR

2.更改您的代碼以

嘗試

for (langId = 1; langId <= 3; langId++) { 
    delayTime += 2000; 
    Handler handler = new Handler(); 
    handler.postDelayed(new Runnable() { 
     @Override 
     public void run() { 
      Toast.makeText(KCRdestActivity.this, String.valueOf(langId), Toast.LENGTH_LONG).show(); 

     } 
    }, delayTime); 
} 
+0

處理程序不能在循環外定義一次嗎? – mrida

+0

是的,你也可以在外面定義它 – Pehlaj

+0

在這裏要注意並糾正我,如果我錯了,run方法內的更新值可能對主線程不可見。因此,主線程可能看不到更新的值。值可以被聲明爲volatile以確保這種可見性。 – mrida

1
Handler handler1 = new Handler(); 
int langId = 1; 
handler1.postDelayed(new Runnable() { 
       @Override 
       public void run() { 
        if (langId > 3) { 
         return; 
        } 
        if (langId == 1) { 
         Toast.makeText(KCRdestActivity.this, "1", Toast.LENGTH_LONG).show(); 
         delayTime = 2000; 
        } 
        if (langId == 2) { 
         Toast.makeText(KCRdestActivity.this, "2", Toast.LENGTH_LONG).show(); 
         delayTime = 2000; 
        } 
        if (langId == 3) { 
         Toast.makeText(KCRdestActivity.this, "3", Toast.LENGTH_LONG).show(); 
         delayTime = 2000; 
        } 
        langId++; 
        handler1.postDelayed(this, delayTyme); 
     } 
} 
0

試試這個..

MainActivity..... 
    long Delay = 2000; 
    oncreate()......... 
    Timer Run = new Timer(); 

    TimerTask Show = new TimerTask() { 
     @Override 
     public void run() { 
      do something......... 
     } 
    }; 

    Run.schedule(Show, Delay); 
} 
0

您可以使用此一AsyncTask

public class MyAsyncTask extends AsyncTask<Void, Integer, Void> { 

    @Override 
    protected Void doInBackground(Void... params) { 
     for (int langId = 1; langId <= 3; langId++) { 
      publishProgress(langId); 
      try { 
       Thread.sleep(2000); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 
     return null; 
    } 

    @Override 
    protected void onProgressUpdate(Integer... values) { 
     super.onProgressUpdate(values); 
     Toast.makeText(KCRdestActivity.this, String.valueOf(values[0]), Toast.LENGTH_LONG).show(); 
    } 
} 
-2

一個快速和骯髒的方式來實現這一目標使用Thread.sleep(2000)

public static void main(String[] args) { 

    Runnable forLoop =() -> { 
     for (int i = 1; i <= 3; i++) { 
      System.out.print(i); // Do your stuff 
      try { 
       Thread.sleep(2000); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 
    }; 

    new Thread(forLoop).start(); 

} 

輸出:

1 -> 2000ms -> 2 -> 2000ms -> 3

+0

將主線置於睡眠狀態始終是個壞主意 –

+0

@AliAhsan現在好了嗎? – steven

+0

不要個人。我剛剛在評論中提到,勸阻人們嘗試任何解決方案,儘管不推薦文檔 –

0

使用這種方法

聲明全局這些類

private int TIME_STAMP_INTERVAL = 2000; 
private Runnable runnable = null; 
private int count=0; 
final Handler handler = new Handler(); 

然後在方法中添加這其中U調用

runnable = new Runnable() { 
     @Override 
     public void run() { 

      Toast.makeText(context, ""count++, Toast.LENGTH_SHORT).show(); 

      handler.postDelayed(runnable, TIME_STAMP_INTERVAL); 
     } 
    }; 
    handler.post(runnable);