2013-09-21 30 views
1

如何在while循環中使用延遲而不延遲UIThread? 我的while循環應該在每次應用程序運行循環時更新UI,但也應該有可能與按鈕進行交互。我目前使用的版本存在的問題是,當while循環開始時,應用暫停,直到while循環完成,然後更新UI。我希望它能在每次傳遞時更新UI。睡在線程while循環沒有睡在UIThread

你有什麼想法,也可能是更有效的替代方式?

這是我目前的版本:

import android.app.Fragment; 
import android.os.Bundle; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.TextView; 
import android.widget.Button; 
import android.widget.ProgressBar; 
import android.view.View.OnClickListener; 
import android.widget.Toast; 
import java.util.regex.Pattern; 


public class ReaderFragment extends Fragment 
{ 

ProgressBar progress_in_main_thread; 
private int progressBarStatus = 0; 
TextView main_text; 
Pattern p = Pattern.compile(" "); 
String[] splitted_text; 
Button start_button; 
Button pause_button; 
public boolean paused; 
int index = 0; 
long wait = 1000; 

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
//Layout des Fragments verknuepfen 
{ 
    View ReaderFragmentView = inflater.inflate(R.layout.reader_fgmt, container, false); 

    progress_in_main_thread = (ProgressBar) ReaderFragmentView.findViewById(R.id.reader_progress); 
    progress_in_main_thread.setProgress(0); 
    progress_in_main_thread.setVisibility(progress_in_main_thread.VISIBLE); 

    main_text = (TextView) ReaderFragmentView.findViewById(R.id.center_view); 

    start_button = (Button) ReaderFragmentView.findViewById(R.id.go); 
    start_button.setOnClickListener(new OnClickListener() 
    { 
     @Override 
     public void onClick(View view) 
     { 
      if(InputFragment.text.trim().length() == 0) 
      { 
       Toast.makeText(getActivity().getApplicationContext(), "Es wurde kein Text eingegeben!", Toast.LENGTH_SHORT).show(); 
      } 
      else 
      { 
       paused = false; 
       splitted_text = p.split(InputFragment.text); 
       progress_in_main_thread.setMax(splitted_text.length-1); 

       mainThread(); 
      } 

     } 
    }); 

    pause_button = (Button) ReaderFragmentView.findViewById(R.id.pause); 
    pause_button.setOnClickListener(new OnClickListener() 
    { 
     @Override 
     public void onClick(View view) 
     { 
       paused = true; 
     } 
    }); 




    return ReaderFragmentView; 
} 

private void mainThread() 
{ 
    new Thread(new Runnable() 
    { 
     @Override 
     public void run() 
     { 
      while(progressBarStatus < (splitted_text.length)-1) 
      { 
       progressBarStatus = index; 

       progress_in_main_thread.setProgress(progressBarStatus); 
      } 
     } 
    }).start(); 

    getActivity().runOnUiThread(new Runnable() 
    { 
     public void run() 
     { 

     while(!paused) 
     { 
      main_text.setText(splitted_text[index]); 

      if(paused) 
      { 
       break; 
      } 
      else if(index == (splitted_text.length)-1) 
      { 
       Toast.makeText(getActivity().getApplicationContext(), "Ende", Toast.LENGTH_LONG).show(); 
       break; 
      } 
      index++; 
      try 
      { 
       Thread.sleep(wait); 
      } 
      catch (InterruptedException e) 
      { 
       e.printStackTrace(); 
      } 
     } 

     } 

    }); 
} 
} 

謝謝大家!

回答

1

根據定義,不能延遲UI線程而不延遲UI線程。

從根本上說,您需要從循環風格的節目切換到事件驅動的一個,這其中Android的UI必須處理。你的程序不會有一個while循環 - 相反,Android框架會調用你的代碼來執行事件函數,每個函數都必須儘快返回。

的Android已經這樣做了開箱即用,提供用戶互動活動,如觸摸,並按下按鈕,以及生命週期事件。要添加用於定期演化UI的事件(您嘗試使用while循環和延遲),可以創建一個Timer並使其TimerTask使用RunOnUiThread將一些與UI相關的工作推到UI線程上;如果你需要做的並不涉及UI,那麼你可以在後臺線程中執行TimerTask。

在你貼的代碼,它看起來像你可能試圖創造條件,運行與睡眠延遲一個循環,推動工作與RunOnUiThread UI線程你自己的後臺線程;從技術上講這是可行的,但與定時器方法相比,並沒有真正鼓勵。但是,有兩個問題是你做的方式:

  • 首先,你命名你的後臺線程mainThread,這是一個有點混亂的Android手機上的「主線」的發射方法和「 UI線程「是一樣的 - 最好將其稱爲createBackgroundThread()或其他東西。

  • 其次,你必須出現的,它推動到執行的UI線程,這是行不通的代碼中,而與睡眠。您將需要移動while循環並睡到後臺線程,而是在需要推入UI時反覆使用RunOnUiThread線程可以立即完成的小批量工作,例如每個實際的可視化更新。

你也可能要考慮一些問題,如果您的實現最終可能創造多個並行的後臺線程爲重複按鍵的結果推動,或者你的一個線程仍在運行時顯著活動生命週期事件發生。

+0

非常感謝您的回答!無論如何,你能舉一個例子來說明你的第二點嗎?我想我不知道該怎麼做。 – reedts

+0

只需在內部移動RunOnUiThread,以便它只包含ui更新工作,而不包含循環或睡眠。 –

+0

好吧,並執行它與TimerTask?知道了,謝謝 – reedts