去五金店买个钻,不是由于咱们须要钻,咱们只需须要孔,既然五金店没法买孔,退而求其次,买打孔的工具。一样的对于后台线程,咱们真正须要的是可以在UI主线程外进行处理,Android提供一个让程序员编写后台操做更为容易和透明AsyncTask。java
使用AsyncTask,须要建立AsyncTask的资料,并实现其中的抽象方法以及重写某些方法。利用AsyncTask咱们不须要本身来写后台线程,无需终结后台线程,例如stop()的方式。AsyncTask的方式对无限循环的方式并不太合适,可能更合适使用Runnable或者Thread。android
对于初次使用的人,AsyncTask看起来有一些复杂。咱们先学些AsyncTask的基本状况,而后给出一个小例子来验证。程序员
AsyncTask编程
AsyncTask中有三个参数(例如class MyTask extends AsyncTask<参数1,参数2,参数3>{})数组
其中参数1和参数2是一个varags,例如String…,至关于String[]。安全
对于AsyncTask的使用步骤以下:网络
一个小例子ide
有一个ListView的小例子,一开始List中没有内容,经过一个AsyncTask逐步在List中加入条目。工具
1)XML文件:简单的ListView布局布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout ... ...>
<ListView android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
2)例子代码
public class Chapter15Test3 extends ListActivity{
//这里是List Item内容,在这个例子中,将在后台任务中逐个加入
private static String[] items={"lorem", "ipsum", "dolor","sit", "amet", "consectetuer","adipiscing", "elit", "morbi","vel", "ligula", "vitae","arcu", "aliquet", "mollis","etiam", "vel", "erat","placerat", "ante","porttitor", "sodales","pellentesque", "augue","purus"};
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.chapter_8_test2);
//在这个例子中,咱们一开始并无导入items的数据,注意item数据为新建的ArrayList,即无内容
setListAdapter(new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,new ArrayList<String>()));
//步骤5:建立后台任务的对象,并经过execute()启动后台线程,调用doInBackground()的代码,execute中的参数类型为参数1,这里咱们不须要传递任何内容
new AddStringTask().execute();
}
//步骤1:建立AsyncTask子类,参数1是Void的范式类型,参数2是String的范式类型,参数3是Void 。其中参数1:向后台任务的执行方法传递参数的类型;参数2:在后台任务执行过程当中,要求主UI线程处理中间状态,一般是一些UI处理中传递的参数类型;参数3:后台任务执行完返回时的参数类型。
private class AddStringTask extends AsyncTask<Void, String,Void>{
//咱们加入一个检测信息的方法,打印当前在哪一个线程执行的信息
private void printInfo(String info){
Log.d("WEI", info + " : Tread is " + Thread.currentThread().getName());
}
//步骤2:实现抽象方法doInBackground(),代码将在后台线程中执行,由execute()触发,因为这个例子并不须要传递参数,使用Void...,具体书写方式为范式书写
protected Void/*参数3*/ doInBackground(Void...params/*参数1*/) {
for(String item : items){
//步骤3:通知UI主线程执行相关的操做(在onProgressUpdate中定义)
publishProgress(item/*参数2*/);
printInfo("doInBackgound " + item);
SystemClock.sleep(200);
}
return null;
}
//步骤3:定义收到pushProgress()触发后,在UI主线程执行的内容,在本例,将item加入list中。方法中的参数为范式方式,实质为数组,因为咱们只传递了item一个String,要获取,为values[0]
protected void onProgressUpdate(String... values/*参数2*/) {
printInfo("onProgressUpdate get param " + values[0]);
((ArrayAdapter<String>)getListAdapter()).add(values[0]);
}
//步骤4:定义后台进程执行完后的处理,本例,采用Toast
protected void onPostExecute(Void result/*参数3*/) {
printInfo("onPostExecute");
Toast.makeText(Chapter15Test3.this, "Done!", Toast.LENGTH_SHORT).show();
}
}
}
咱们根据printInfo跟踪各部分代码在哪里执行:doInBackground在后台线程执行,onProgressUpdate()和onPostExecute()在UI主线程执行。main就是UI主线程,而AsyncTask #1为后台线程,名字不同。
须要注意
虽然Android提供后台任务方便咱们处理,是否使用后台任务,以及如何使用后台任务,咱们要注意下面的内容:
可能在执行后台线程处理中,用户和UI之间存在交互,这些交换可能会对后台任务有重要的影响,所以须要通知后台线程,Android提供不少的类来处理,封装在java.util.concurrent包中,帮助与后台线程的安全通讯。可能在执行后台线程处理中,咱们的Activity就已经被kill了,例若有一个电话过来,而后发给短信,查看号码本。这时系统可能将你的activity踢走,接着后面咱们会学习Activity的生命周期,了解相关的状况。在编程中,出现这种状况,只要有可能,须要将后台进程关闭。可能在执行后台线程处理中,出现某种错误,例如后台在下载URL,而网络链接中断了。这种状况下关闭后台进程多是最好的处理。此外后台任务是消耗CPU和内存,是有代价的,咱们应该确保它处理的时候更为有效。
相关连接:个人Andriod开发相关文章