我們在《Android學習之Handler消息傳遞機制》(http://www.cnblogs.com/zhouhb/p/5812447.html)已提到過,Android只允許UI線程修改Activity里的UI組件,這樣會導致新啟動的線程無法動態改變界面組件的屬性值。為瞭解決新線程不能更新UI組 ...
我們在《Android學習之Handler消息傳遞機制》(http://www.cnblogs.com/zhouhb/p/5812447.html)已提到過,Android只允許UI線程修改Activity里的UI組件,這樣會導致新啟動的線程無法動態改變界面組件的屬性值。為瞭解決新線程不能更新UI組件的問題,除了可以藉助於Handler的消息傳遞機制來實現,還可以使用AsycTask。 1 AsyncTask使用方法簡介 AsyncTask<Params, Progress, Result>是一個抽象類,通常用於被繼承。繼承AsyncTask需要指定如下三個泛型參數:
- Params: 這個泛型指定的是我們傳遞給非同步任務執行時的參數的類型
- Progress: 這個泛型指定的是我們的非同步任務在執行的時候將執行的進度返回給UI線程的參數的類型
- Result: 這個泛型指定的非同步任務執行完後返回給UI線程的結果的類型
- onPreExecute(): 這個方法是在執行非同步任務之前的時候執行,通常我們在這個方法里做一些UI控制項的初始化的操作,例如彈出進度條等。
- doInBackground(Params... params): 這個方法就是用來處理非同步任務的方法。在該方法可以調用publishProgress(Progress)方法更新任務的執行進度。
- onProgressUpdate(Progess... values):在 doInBackground 方法中調用publishProgress(Progress) 方法會觸發該方法。
- onPostExecute(Result... result): 當doInBackground(Params... params)方法完成後,系統會自動調用該方法,並將doInBackground(Params... params)方法的返回值傳遞給該方法。
public class MainActivity extends Activity { private TextView show; private Button btn; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); show=(TextView)findViewById(R.id.show); show.setMovementMethod(ScrollingMovementMethod.getInstance()); btn=(Button)findViewById(R.id.btn); btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { // TODO Auto-generated method stub doTask(); } }); } private void doTask() { // TODO Auto-generated method stub DownTask task=new DownTask(this,show); try { task.execute(new URL("http://www.szit.edu.cn/")); } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } }
2.2 AsyncTask的子類DownTask代碼
public class DownTask extends AsyncTask<URL, Integer, String> { ProgressDialog progressDialog; int hasRead=0; Context context; TextView show; public DownTask(Context context,TextView show) { this.context=context; this.show=show; } @Override protected String doInBackground(URL... arg0) { // TODO Auto-generated method stub StringBuilder sb=new StringBuilder(); try { URLConnection conn=arg0[0].openConnection(); BufferedReader br=new BufferedReader(new InputStreamReader(conn.getInputStream(),"gb2312")); String line=""; while ((line=br.readLine())!=null) { sb.append(line+"\n"); hasRead++; publishProgress(hasRead); } } catch (Exception e) { // TODO: handle exception } return sb.toString(); } @Override protected void onPostExecute(String result) { // TODO Auto-generated method stub show.setText(result); progressDialog.dismiss(); } @Override protected void onPreExecute() { // TODO Auto-generated method stub progressDialog=new ProgressDialog(context); progressDialog.setTitle("任務執行中"); progressDialog.setMessage("敬請等待"); progressDialog.setCancelable(false); progressDialog.setMax(300); progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); progressDialog.setIndeterminate(false); progressDialog.show(); } @Override protected void onProgressUpdate(Integer... values) { // TODO Auto-generated method stub show.setText("已讀取"+values[0]+"行"); progressDialog.setProgress(values[0]); } }
AsyncTask的其他使用實例,可以進一步參考Android 多線程-----AsyncTask詳解(http://www.cnblogs.com/xiaoluo501395377/p/3430542.html)。