下面我会用具体例子解释如何在安卓程序中使用AsyncTask来实现子线程的创建
//AsycTask内部类,用于倒计时并跳转
static class loading extends AsyncTask<Void,Integer,Void> {
public Integer s=0;//用于计时的一个整数变量
public loading(ProgressBar progressBar, MyViewModel myViewModel, TextView textView, AVIMTextMessage msg, FragmentWebQuestionBinding binding,Button button) { //这一大段代码你可以理解为这个子线程启动需要预先加载的对象,这些对象也是子线程运作中会涉及到的。
this.progressBar = progressBar;
this.myViewModel = myViewModel;
this.textView = textView;
this.msg = msg;
this.binding = binding;
this.button = button;
//这里就是给前面创建的对象连接上真正存在的对象
}
@Override
protected void onCancelled(Void unused) {//这个方法就是定义任务结束之后会做什么,多半是资源的回收
super.onCancelled(unused);
}
private Button button;
private ProgressBar progressBar;
private MyViewModel myViewModel;
private TextView textView;
private AVIMTextMessage msg;
private FragmentWebQuestionBinding binding;
@Override
protected Void doInBackground(Void... voids) {//这个方法简单地理解就是子线程运行的任务
while (s<100){
if (isCancelled()) break;
onProgressUpdate(s);
s+=1;
try {
Thread.sleep(40);//这里使用线程休眠的方法,比较简单地去实现计时
} catch (InterruptedException e) {
e.printStackTrace();
}
// if(s==100){
// s=0;
// }
if (isCancelled()) break;
}
return null;
}
@Override
protected void onProgressUpdate(Integer... values) {
//这个方法简单地理解就是子线程在运行任务的某一阶段要做什么
int value = values[0];
progressBar.setProgress(value,true);//这里就是利用计时的整数变量来改变控件的状态,这里其实容易出问题,但是没有出问题,稍微解释一下就是,安卓只允许控件状态的改变发生在主线程中,而在子线程中如果尝试去改变那么程序就会崩溃,但是这里没有崩溃,原因是这里其实只是改变控件外观,没有实质性地去改变它的状态,倘若这里你尝试去让一个按钮不可用,那么程序一定会崩溃,要解决问题其实很简单,只要在主线程里改变就好了,但这里就涉及到了线程之间的通讯,这个之后我会写一篇文章解释一下。
if (value==99){
msg = new AVIMTextMessage();
msg.setText("dead");
myViewModel.getConversation().sendMessage(msg, new AVIMConversationCallback() {
@Override
public void done(AVIMException e) {
if (e == null) {
}
}
});
Message msg = new Message();
msg.what = COMPLETED;
handler.sendMessage(msg);
//这里就涉及到线程之间的通讯了
binding.iDead.setText("dead");
this.cancel(true);
}
}
}