为什么要用AsyncTask?
平时在开发Android程序时遇到较耗时任务的处理,如I/O访问的数据库操作、网络访问等情况时造成UI假死等问题,通过 AsyncTask可以很好的解决这个问题,就今天以在Android中执行Downloader.downloadFile(url),可能会堵塞整个界面。
解决上述问题的方式
方法一:线程 + Handler
创建一个新的线程执行我们的任务,使用Thread类,在 run(){}中写入任务代码
new Thread(new Runnable() {
public void run() {
Downloader.downloadFile(url);
}
}).start();
方法二:AsyncTask
Android SDK为我们提供了一个后台任务的处理工具AsyncTask。AsyncTask就是一个封装过的后台任务类顾名思义就是异步任务,方便我们维护,Android开发网提示这样的好处可以解决一些线程安全问题,AsyncTask直接继承于Object类,位置为 android.os.AsyncTask。
三个泛型:
Param :任务执行器需要的数据类型
Progress :后台计算中使用的进度单位数据类型
Result :后台计算返回结果的数据类型
实例
public class NewsNet {
protected static final String TAG = "NewsNet";
private Callable callable;
private Context context;
public NewsNet(Context context,Callable callable){
this.callable = callable;
this.context = context;
}
public interface Callable{
public void success(ArrayList<String> news);
public void fail(Exception e);
}
public void execute(Integer count){
new AsyncTask<Integer, Integer, ArrayList<String>>(){
ProgressDialog pd;
//预处理方法,可以在这里创建进度框
@Override
protected void onPreExecute() {
pd = new ProgressDialog(context);
pd.setMax(100);
pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
// pd.setIndeterminate(true);
pd.setCancelable(false);
pd.show();
// pd = ProgressDialog.show(context,"",context.getResources().getString(R.string.load_newlist),true,false);
}
//在这里更新进度框的进度
@Override
protected void onProgressUpdate(Integer... values) {
pd.setProgress(values[0]);
Log.i(TAG, "onProgressUpdate-->" + values[0]);
if(values[0] == 100)
{
pd.dismiss();
pd = null;
System.gc();
}
}
@Override
protected ArrayList<String> doInBackground(Integer... params) {
int size = params[0];
ArrayList<String> result = new ArrayList<>(size);
for (int i = 1; i <= size; i++) {
result.add("新闻标题--" + i);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
publishProgress(i);
}
return result;
}
@Override
protected void onPostExecute(ArrayList<String> result) {
if(result != null && result.size() > 0){
callable.success(result);
}
else{
callable.fail(null);
}
}
}.execute(count);
}
}
下面的代码为调用AsyncTask的代码
/**
*
* 显示新闻列表Activity
*/
public class SimpleAsyncTaskAct extends ListActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
NewsNet newsNet = new NewsNet(this, new NewsNet.Callable(){
@Override
public void success(ArrayList<String> news) {
if(news != null || news.size() != 0){
ArrayAdapter<String> adapter = new ArrayAdapter<>(SimpleAsyncTaskAct.this, android.R.layout.simple_list_item_1, android.R.id.text1, news);
SimpleAsyncTaskAct.this.setListAdapter(adapter);
}
}
@Override
public void fail(Exception e) {
}});
newsNet.execute(100);
}
}