Android事件处理之五 异步任务

来源:互联网 发布:网络拒绝接入怎么解决 编辑:程序博客网 时间:2024/05/20 04:31
AsyncTask
Android的UI线程主要负责处理用户的按键事件、用户触屏事件及屏幕绘制事件等,因此开发者的其它操作不应该也不能阻塞UI线程
为避免UI线程失去响应,Android建议将耗时操作放在新线程中完成,但新线程可能需要动态更新UI组件,而新线程是不允许直接更新UI组件的。
为解决新线程不能更新UI组件这一个问题,Android提供了如下方案:
  • 使用Handler实现线程间通信
  • Activity.runOnUiThread(Runnable)
  • View.post(Runnable)
  • View.postDelayed(Runnable, long)
Handler处理已作说明,而后三种方式编程略显繁琐,而异步任务(AsyncTask)则可进一步简化这种操作
AsyncTask<Params, Progress, Result>是抽象类,它定义了如下三种泛型:
  • Params:启动任务执行输入参数的类型
  • Progress:后台任务完成的进度值类型
  • Result:后台执行任务完成后返回结果的类型
使用AsyncTask的3个步骤:
  1. 创建AsyncTask子类,并为三个泛型参数指定类型(不需要的可指定为void)
  2. 据需要,实现AsyncTask的方法:
     fun1:doInBackground(Params):重写该方法就是后台程序将要完成的任务,该方法可以调用publishProgress(Params..)更新任务执行进度
     fun2:onProgressUpdate(Progress value):在doInBackground()方法中调用publishProgress()更新进度后将触发该方法
     fun3:onPreExecute():该方法将在执行后台耗时操作前被调用。通常用于完成一些初始化的操作,如在界面上显示进度条
     fun4:onPostExecute(Result result):当doInBackground()完成后,系统会自动调用onPostExecute()方法,并将doInBackground方法的返回值传给该方法
  3.调用AsyncTask子类的实例的execute(Params... params)开始执行耗时任务
使用AsyncTask时必须遵守如下规则:
1.必须在UI线程中创建AsyncTask实例
2.必须在UI线程中调用AsyncTask的execute()方法
3.AsyncTask的onPreExecute()、onPostExecute(Result result)、doInBackground(Params params),onProgressUpdate(Progress values)方法由Android系统负责调用
4.每个AsyncTask只能被执行一次,多次调用将会引发异常
示例代码如下:
publicclassMainActivity extends Activity {

privateTextView show;
   
@Override
   
protected void onCreate(Bundle savedInstanceState) {
       
super.onCreate(savedInstanceState);
        setContentView(R.layout.
activity_main);
       
show = (TextView) findViewById(R.id.show);
    }
   
public void download(View source)throwsMalformedURLException
    {
    DownTask task =
new DownTask(this);
    task.execute(
newURL("http:www.crazyit.org/ethos.php"));
    }
   
class DownTask extends AsyncTask<URL, Integer, String>
    {
    ProgressDialog
pdialog;
   
int hasRead = 0;
    Context
mContext;
   
public DownTask(Context ctx)
    {
   
mContext = ctx;
    }
   
@Override
   
protected String doInBackground(URL... params)
    {
    StringBuilder sb =
new StringBuilder();
   
try
    {
    URLConnection conn = params[0].openConnection();
    BufferedReader br =
new BufferedReader(
   
new InputStreamReader(conn.getInputStream()
    ,
"utf-8"));
    String line =
null;
   
while((line = br.readLine()) !=null)
    {
    sb.append(line +
'\n');
   
hasRead++;
publishProgress(
hasRead);
//    setProgress(hasRead);
    }
   
return sb.toString();
    }
   
catch (Exception e)
    {
    e.printStackTrace();
    }
   
return null;
    }
   
@Override
   
protected void onPostExecute(String result)
    {
   
show.setText(result);
   
pdialog.dismiss();
    }
   
@Override
   
protected void onPreExecute()
    {
   
pdialog = new ProgressDialog(mContext);
   
pdialog.setTitle("mission executing");
   
pdialog.setMessage("processing , please wait");
   
pdialog.setCancelable(false);
   
pdialog.setMax(202);
   
pdialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
   
pdialog.setIndeterminate(false);
   
pdialog.show();
    }
   
@Override
   
protected void onProgressUpdate(Integer...values )
    {
   
show.setText("has read "+ values[0]+"rows");
   
pdialog.setProgress(values[0]);
    }
    }
}
另外,程序需要使用网络,所以需要在android_manifest.xml文件中声明权限
    <uses-permission android:name="android.permission.INTERNET"/>
0 0