【Android】使用AsyncTask处理耗时任务

来源:互联网 发布:excel如何保护数据 编辑:程序博客网 时间:2024/05/16 14:18

开发中进行耗时操作时,如网络请求,数据存储等,为了不阻塞UI线程,需要在子线程中进行。当进行网络操作后对UI的控件进行数据的更新时往往需要在主UI线程中进行操作。为了解决这一问题,AsyncTask是一个很好的选择。

根据官方文档:

AsyncTask类的三个泛型参数<Params, Progress, Result>

Params:启动任务时的输入参数,在doInBackground中作为参数传入

Progress:后台任务执行的百分比

Result:后台执行任务的返回结果,doInBackground返回值

 

AsyncTask中可以实现的方法:

onPreExecute():在后台操作前被UI线程调用。可以不用被实现

doInBackground(Params...):在上述执行后执行,处理耗时的工作,被开启在新的线程中。可以调用publishProgress()方法实时更新任务进度。该方法必须被实现

onProgressUpdate(Progress...):在publishProgress()调用后执行被UI线程调用

onPostExecute(Result):将被UI线程调用,后台计算结果通过该方法传递到UI(参数Result),可以在此方法中改变控件的数据

 

需要注意:

1.Task必须在UI线程中被创建

2.execute方法必须在UI线程中被调用

3.不要手动调用上述的几个方法


下面模拟网络操作对AsyncTask的使用进行介绍

创建一个AsyncTask的导出类并重写伤处的这些方法:

package com.example.wayne_t.asynctaskdemo;import android.content.Context;import android.os.AsyncTask;import android.widget.TextView;import android.widget.Toast;/** * Created by Wayne-T on 2015/6/15. */public class SubAsyncTask extends AsyncTask<String, Integer, String[]> {    private Context context;    private TextView tv;    public SubAsyncTask(Context _context, TextView _tv) {        context = _context;        tv = _tv;    }    @Override    protected String[] doInBackground(String... params) {        // 这里执行网络操作等,用来获取数据        // params可用来传递URL和参数等        // 这里仅仅做测试,省略网络操作的请求过程        publishProgress(1);        return params;    }    @Override    protected void onPreExecute() {        super.onPreExecute();        Toast.makeText(context, "This is onPreExecute method", Toast.LENGTH_SHORT).show();    }    @Override    protected void onPostExecute(String[] s) {        super.onPostExecute(s);        // 处理返回结果,被UI线程调用        tv.setText(s[0] + " " + s[1]);    }    @Override    protected void onProgressUpdate(Integer... values) {        super.onProgressUpdate(values);        Toast.makeText(context, "This is onProgressUpdate method" + values, Toast.LENGTH_SHORT).show();    }    @Override    protected void onCancelled(String[] strings) {        super.onCancelled(strings);        Toast.makeText(context, "This is onCancelled method", Toast.LENGTH_SHORT).show();    }}

注意doInBackground方法中应该进行耗时操作,这里省略直接返回要更改的数据

返回值在onPostExecute中以参数的形式传递进去,然后可以在这个方法中进行UI的更新

需要进行操作的Activity中实例化该方法,调用execute方法执行,execute方法中的参数被用于AsyncTask的第1个参数,即初始状态时要处理的参数。如果是进行网络操作则可以把url及请求参数的数据变量传递进来。

package com.example.wayne_t.asynctaskdemo;import android.support.v7.app.ActionBarActivity;import android.os.Bundle;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.widget.Button;import android.widget.TextView;public class MainActivity extends ActionBarActivity {    private TextView tv;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        Button btn = (Button) findViewById(R.id.Get);        tv = (TextView) findViewById(R.id.content);        btn .setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                SubAsyncTask sa = new SubAsyncTask(MainActivity.this, tv);                sa.execute("test1", "test2");            }        });    }    @Override    public boolean onCreateOptionsMenu(Menu menu) {        // Inflate the menu; this adds items to the action bar if it is present.        getMenuInflater().inflate(R.menu.menu_main, menu);        return true;    }    @Override    public boolean onOptionsItemSelected(MenuItem item) {        // Handle action bar item clicks here. The action bar will        // automatically handle clicks on the Home/Up button, so long        // as you specify a parent activity in AndroidManifest.xml.        int id = item.getItemId();        //noinspection SimplifiableIfStatement        if (id == R.id.action_settings) {            return true;        }        return super.onOptionsItemSelected(item);    }}


点击按钮即可实现界面的更改,并且可以看到Toast信息来确认重写的方法的调用顺序

0 0
原创粉丝点击