AsynTask是Handler的轻量级形式,他可以用作专门的处理耗时操作。有时我们会发现,在主线程睡眠的时候,你执行别的操作的时候会出现“卡屏”状态,这样的效果极为不好。但是我们可以通过AsynTask去解决这个问题。
◆“卡屏”现象
(1)创建自定义类对象 模拟耗时操作
public class Mythread {//自定义类
public static void sleepy(){
try {
Thread.sleep(5000);//模拟耗时操作
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} |
public class MainActivity extends Activity implements OnClickListener{
private Button startBtn,printbtn;//声明按钮
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//查找资源
startBtn = (Button) findViewById(R.id.start);
printbtn =(Button) findViewById(R.id.printBtn);
//为按钮添加监听
startBtn.setOnClickListener(this);
printbtn.setOnClickListener(this);
}
@Override
public void onClick(View arg0) {
switch (arg0.getId()) {
case R.id.start:
//自定义线程类睡眠方法的调用
Mythread.sleepy();//这样使用的话会出现卡屏的状态
break;
case R.id.printBtn:
System.out.println("hello");
break;
}
}
} |
(3)结果:
◆若直接单击print方法没问题,后台输出正常
◆但若先单击start按钮,在单击任意次数的print按钮,都不会马上看见效果,而是等待睡眠5秒之后一并输出。
如何解决“卡屏”现象?先来看看AsynTast吧。
一:原理
其实启动AsynTask,就相当于又开辟了一个线程,在这个线程中专门处理耗时操作,从而不会耽误用户主UI的其他操作,提高用户体验。
二:创建及常用方法
1:创建
继承自AsynTask类,但有三个泛型,这里要注意一下,泛型用的全是包装类。
class MyAsynTask extends AsyncTask<泛型1, 泛型2, 泛型3> |
2:常用方法及参数
(1)泛型3 doInBackground(泛型1):核心的处理耗时工作。方法的返回值类型:泛型3;参数类型:泛型1。参数的值来自于主界面启动AsynTask时传递的值。
(2)onPostExecute(泛型3):异步结束时执行的方法。参数的值来自于doInBackground的返回值,因此参数的类型为:泛型3.
(3)onPreExecute():在异步开始时就会执行的方法,也就是会在doInBackground方法执行之前执行。
(4)onProgressUpdate(泛型2):与主线程UI的交互。参数类型:泛型2。参数的值来源于在doInBackground方法中通过publishProgress传递过来的值。
三:如何解决“卡屏现象”?
(1)创建继承自AsynTask的类,重写其中的doInBackground方法
(2)在doInBackground方法中调用耗时操作
public class MyAsynTask extends AsyncTask<Void, Void, String>{
@Override
protected String doInVoid... params) {
Mythread.sleepy();//专门处理耗时 的操作
return null;
}
} |
(3)在主线程start按钮的监听中,不再是直接调用耗时操作,而是创建AsynTask对象,通过execute启动线程
case R.id.start:
//MyAsynTask myAsynTask = new MyAsynTask();
//myAsynTask.execute();//启动AsynTask,这样就不会出现卡屏的状态了
break; |
四:AsynTask的应用
实现的功能:仍然是上一篇博文中进度条与TextView控件的同步使用。
(1)创建类继承自AsynTask,注意泛型类型的添加
(2)提供成员属性(主界面上要同步的控件),添加构造方法
private TextView tv;//成员变量
private ProgressBar bar;//成员变量
public MyAsynTask(TextView tv, ProgressBar bar) {
super();
this.tv = tv;
this.bar = bar;
} |
(3)重写onPreExecute()方法:让他给出提示“异步开始了”
// 在异步开始时就会执行的方法,也就是会在doInBackground方法执行之前执行
@Override
protected void onPreExecute() {
tv.setText("异步开始了");
super.onPreExecute();
} |
(4)重写doInBackground()方法:完成值的更新
/**
* 核心处理方法,它的参数有主界面的启动时传递进来
* 返回类型:泛型3
* 参数类型:泛型1
*/
@Override
protected String doInString... params) {
int count = 0;//初始化变量
for (count = 0; count <= 100; count++) {
try {
Thread.sleep(100);//每个一秒count加1
} catch (InterruptedException e) {
e.printStackTrace();
}
// 传给了onProgressUpdate方法
publishProgress(count);//这个count将会传给onProgressUpdate中参数
}
return count+"";//返回值给onPostExecute方法,以便于结束的判断
} |
// 异步结束时执行的方法,参数来自于doInBackground的返回值,也就是这里的vcount;
@Override
protected void onPostExecute(String result) {
if (result != null) {
tv.setText("异步结束了,当前的I值为:" + result+"");
}
super.onPostExecute(result);
} |
// 与主线程UI的交互,参数来自于doInBackground方法中的publishProgress的参数值
@Override
protected void onProgressUpdate(Integer... values) {
bar.setProgress(values[0]);//更新主Ui中的进度条
tv.setText(values[0] + "");//更新主UI中的文本框
super.onProgressUpdate(values);
} |
(7)主UI中为按钮添加监听,启动AsynTask
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//实例化AsynTask对象
MyAsynTask myAsynTask = new MyAsynTask(tv, bar);
//启动AsynTask
myAsynTask.execute();
} |
其中AsynTask的几个方法的返回值与参数类型还得自己继续的研究研究啊。。有点蒙。。
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。