最近在看《Android Wireless Application Development Volume2》第一章,讲的主要是线程及异步操作,android中的主要UI线程,最好不要包括太耗时的操作,否则会让该线程阻塞,所以我们就需要将这些耗时的操作放在其他地方执行,而又与主要UI线程有一定关联。androidSDK提供了几种将操作从主UI线程移除的方法,这里主要介绍两种:1.使用AsyncTask类;2.使用标准Thread类。
现在完成一个计数任务,从1计到100,在TextView中显示进度。如果把这些循环加的操作放在onCreat()方法中,肯定会出现阻塞。利用AsyncTask类在后台进行操作,可以使主UI线程顺畅进行下去。这个类里主要涉及到3个方法,doInBackground(),onProgressUpdate(),onPostExecute(),这3个方法中的参数又和类中的3个变量有直接关系,AsyncTask<Void, Integer, Integer>.
doInBackground()就是在后台运行;onProgressUpdate()是在数据更新时调用,onPostExecute()是完成时调用
package com.example.chapter1; import android.os.AsyncTask; import android.os.Bundle; import android.os.SystemClock; import android.app.Activity; import android.widget.TextView; public class MainActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //实例化该任务,调用方法启动 CountingTask task=new CountingTask(); task.execute(); } private class CountingTask extends AsyncTask<Void, Integer, Integer>{ CountingTask(){} @Override /** * 在后台运行并处理后台操作 */ protected Integer doInBackground(Void... params) { // TODO Auto-generated method stub int i=0; while(i<100){ SystemClock.sleep(250); i++; if(i%5==0){ //每5%进度时更新一次UI publishProgress(i); } } return i; } /** * 将后台操作与主UI线程联系起来的方法,数据更新时调用 * @param progress 完成度 */ protected void onProgressUpdate(Integer... progress){ TextView tv=(TextView)findViewById(R.id.tv1); tv.setText(progress[0]+"% 已完成"); } /** * 将后台操作与主UI线程联系起来的方法,完成时调用 * @param result 结果 */ protected void onPostExecute(Integer result){ TextView tv=(TextView)findViewById(R.id.tv1); tv.setText("计数完成"+"计到了"+result.toString()); } } }
效果就是上面这样。
2.用Thread的方法,这个是传统的方法,代码如下:
new Thread(new Runnable() { public void run() { int i = 0; while (i < 100) { SystemClock.sleep(250); i++; final int curCount = i; if (curCount % 5 == 0) { //每过5%就更新UI tv.post(new Runnable() { public void run() { tv.setText(curCount + "%完成"); } }); } } tv.post(new Runnable() { public void run() { tv.setText("全部完成!"); } }); } }).start();