使用AsyncTask实现异步操作
一、更新ui组件的方法
1、使用Handlers实现线程之间的通信
2、Activity.runOnUiThread(Runnable)
3、View.post(Runnable)
4、View.postDelayed(Runnable,long)
5、使用异步操作AsyncTask
二、AsyncTask<Params,Progress,Result>是一个抽象类,通常继承AsyncTask时需要指定如下的三个泛型参数。
1、Params启动任务时输入的参数类型
2、Progress后台任务完成的进度类型
3、Result后台任务完成返回的结果类型
三、根据需要实现AsyncTask的四个方法
1、doInBackground(Params...)该方法就是在后台完成任务,调用publishProgress方法更新任务执行进度
2、onPostExecute(Result result) 当doInBackground(Params...)完成后,系统自动调用
3、onPreExecute() 该方法通常会完成一些初始化的准备工作,比如界面显示进度条
4、onProgressUpdate当调在doInBackground中调用publishProgress时,触发该方法
四、AsyncTask子类的实例,调用execute()方法,开始执行耗时操作,其中的四个方法都应该由系统自动调用
五、使用异步操作任务执行下载任务
1、xml文件
<?xml version="1.0" encoding="utf-8"?> <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="开始下载" android:onClick="download" android:layout_gravity="center"/> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/text1"/> <EditText android:id="@+id/editText" android:layout_width="match_parent" android:layout_height="wrap_content" android:ems="10" android:inputType="phone" /> </LinearLayout> </ScrollView>
2、activity
public class AsyncTaskActivity1 extends AppCompatActivity { private TextView text1; protected void onCreate(Bundle saveInstanceSate) { super.onCreate(saveInstanceSate); setContentView(R.layout.async_task); text1=findViewById(R.id.text1); } public void download(View view) throws MalformedURLException { DownTask downTask=new DownTask(this); //调用execute()方法开始执行异步操作 downTask.execute(new URL("https://luna.58.com/m/autotemplate?city=cd&creativeid=119&utm_source=link&spm=m-39558317773073-ms-f-801.mjh_daquanmingzhan01")); } //AsyncTask<Params,Progress,Result> //Params:启动后台执行任务输入的参数 Progress:后台任务完成的进度值的类型 Result:后台执行任务完成后返回的结果类型 class DownTask extends AsyncTask<URL,Integer,String>{ //URL:为启动后台执行任务输入的参数 Integer:后台任务完成的进度值的类型 String:后台执行任务完成后返回的结果类型 ProgressDialog dialog; //定义记录已经读取的行数 int hasRead=0; Context mContext; public DownTask(Context mContext) { this.mContext = mContext; } //(完成后台下载)该方法后台线程将要完成任务,调用publishProgress方法更新任务执行进度 @Override protected String doInBackground(URL... urls) { StringBuilder sb=new StringBuilder(); try{ URLConnection conn=urls[0].openConnection(); //将conn获取的inputStream包装为BufferedReader BufferedReader reader=new BufferedReader(new InputStreamReader(conn.getInputStream())); String line=null; while ((line=reader.readLine())!=null){ sb.append(line+"\n"); hasRead++; //此方法更新任务的执行进度 publishProgress(hasRead); } return sb.toString(); /*OkHttpClient client = new OkHttpClient(); Request request = new Request.Builder() .url("http://www.taobao.com") .build(); Response response = client.newCall(request).execute(); String responseData = response.body().string(); return responseData;*/ } catch (IOException e) { e.printStackTrace(); } return null; } //(在完成下载后将网页的代码显示)在doInBackground(URL... urls)完成后,系统自动调用该方法,并将doInBackground(URL... urls)的返回值床底给这个方法 protected void onPostExecute(String result){ text1.setText(result); dialog.dismiss(); } //(开始下载前显示一个进度条)该方法通常会完成一些初始化的准备工作,比如界面显示进度条,将在后台执行费时操作之前调用 protected void onPreExecute(){ dialog=new ProgressDialog(mContext); dialog.setTitle("任务正在进行"); dialog.setMessage("任务正在进行中,敬请等待..."); dialog.setCancelable(false); dialog.setMax(202); dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); dialog.setIndeterminate(false); dialog.show(); } //(更新进度条)当调在doInBackground中调用publishProgress时,触发该方法 protected void onProgressUpdate(Integer... values){ text1.setText("已经读取到【"+values[0]+"】行!"); dialog.setProgress(values[0]); } } }