AsyncTask专题之二 AsyncTask基础
2016-07-10 15:05
211 查看
概念性的东西,自行百度,我就说下怎么用的。分如下几个部分
1.AsyncTask中四个方法分别在哪个线程中执行的,因为我们知道我们只能在UI线程中去更新UI
protected String doInBackground(Integer… params) 这个方法是必须要重写的。
2.AsyncTask中重写方法的用途,以及参数说明
3.写一个小demo来总结一下使用过程
一、AsyncTask中四个方法分别在哪个线程中执行的。通过打印
LOg的方式
从上面可以看出来,只有doInBackground()方法是执行在子线程中,而另外三个方法,都是执行在UI线程(主线程)中的。
二、AsyncTask的操作步骤:
使用前提:有耗时操作,使用子线程,需要在耗时操作后将子线程的数据,传递给主线程更新UI
*
* 使用步骤:
*
* step1:创建一个子类,继承AsyncTask。(抽象类)
*
* step2:确定参数,的泛型。
* 第一个参数:params:要启动异步任务需要传递的参数数据。一般是String。因为大多数的异步任务耗时操作是网络下载,需要网址。
* Params, the type of the parameters sent to the task upon execution.
第二个参数:Progress:耗时操作过程中,用于显示完成的进度。如果耗时的过程中需要向外发布进度,一般使用Integer,如果不需要发布进度:Void
Progress, the type of the progress units published during the background computation.
第三个参数:Result:耗时操作结束后,返回给UI线程的结果。String,byte[],Bitmap
Result, the type of the result of the background computation.
* step3:重写对应的方法:
* onPreExecute()—>耗时操作前执行的,一般用于做准备工作,比如创建一个进度条
* doInBackground()–>耗时操作,子线程中执行。比如网络访问
* publishProgress()–>发布进度对应onProgressUpdate()更新进度。。
* onPostExecute()–>耗时操作完成后,要执行的方法。一般用于跟新UI。
三、跟着老王写例子:
先看下效果图:
主界面
执行中
执行后
布局:
代码:
1.AsyncTask中四个方法分别在哪个线程中执行的,因为我们知道我们只能在UI线程中去更新UI
protected String doInBackground(Integer… params) 这个方法是必须要重写的。
2.AsyncTask中重写方法的用途,以及参数说明
3.写一个小demo来总结一下使用过程
一、AsyncTask中四个方法分别在哪个线程中执行的。通过打印
LOg的方式
07-10 06:53:40.136 1750-1750/? D/===onPreExecute: 线程id=1,线程名=main --------- beginning of /dev/log/system 07-10 06:53:40.144 1750-1772/? D/===doInBackground: 线程id=111,线程名=AsyncTask #2 07-10 06:53:40.272 1750-1750/? D/===onProgressUpdate: 线程id=1,线程名=main 07-10 06:53:40.352 1750-1750/? D/===onProgressUpdate: 线程id=1,线程名=main 07-10 06:53:40.472 1750-1750/? D/===onProgressUpdate: 线程id=1,线程名=main 07-10 06:53:40.552 1750-1750/? D/===onProgressUpdate: 线程id=1,线程名=main 07-10 06:53:40.644 1750-1750/? D/===onProgressUpdate: 线程id=1,线程名=main 07-10 06:53:40.644 1750-1750/? D/===onPostExecute: 线程id=1,线程名=main
从上面可以看出来,只有doInBackground()方法是执行在子线程中,而另外三个方法,都是执行在UI线程(主线程)中的。
二、AsyncTask的操作步骤:
使用前提:有耗时操作,使用子线程,需要在耗时操作后将子线程的数据,传递给主线程更新UI
*
* 使用步骤:
*
* step1:创建一个子类,继承AsyncTask。(抽象类)
*
* step2:确定参数,的泛型。
* 第一个参数:params:要启动异步任务需要传递的参数数据。一般是String。因为大多数的异步任务耗时操作是网络下载,需要网址。
* Params, the type of the parameters sent to the task upon execution.
第二个参数:Progress:耗时操作过程中,用于显示完成的进度。如果耗时的过程中需要向外发布进度,一般使用Integer,如果不需要发布进度:Void
Progress, the type of the progress units published during the background computation.
第三个参数:Result:耗时操作结束后,返回给UI线程的结果。String,byte[],Bitmap
Result, the type of the result of the background computation.
* step3:重写对应的方法:
* onPreExecute()—>耗时操作前执行的,一般用于做准备工作,比如创建一个进度条
* doInBackground()–>耗时操作,子线程中执行。比如网络访问
* publishProgress()–>发布进度对应onProgressUpdate()更新进度。。
* onPostExecute()–>耗时操作完成后,要执行的方法。一般用于跟新UI。
最后,别忘了去启动我们的异步任务: 类似下面这样: new MyAsyncTask().execute(num);
三、跟着老王写例子:
先看下效果图:
主界面
执行中
执行后
布局:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.yztc.day0710_wang_02.MainActivity" android:id="@+id/root"> <TextView android:id="@+id/tv_show" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="显示进度" android:layout_marginTop="50dp"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="显示状态" android:id="@+id/tv_status" android:layout_below="@id/tv_show"/> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/tv_status" android:text="启动子线程" android:onClick="onStartSubThread"/> </RelativeLayout>
代码:
package com.yztc.day0710_wang_02; import android.os.AsyncTask; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.View; import android.widget.ProgressBar; import android.widget.RelativeLayout; import android.widget.TextView; public class MainActivity extends AppCompatActivity { private TextView mTextView;//显示当前进度 private TextView tv_status;//当进度达到100%,显示执行完成 public static final b358 String TAG = "MainActivity"; private RelativeLayout root;//布局根元素的ID,用于把代码中生成的进度条加进布局中 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mTextView = (TextView) findViewById(R.id.tv_show); tv_status = (TextView) findViewById(R.id.tv_status); root = (RelativeLayout) findViewById(R.id.root); } //响应按钮事件 public void onStartSubThread(View view) { //点击按钮启动异步任务 //向子线程中传入的参数 int num = 100; //点击按钮执行异步操作 new MyAsyncTask().execute(num); } class MyAsyncTask extends AsyncTask<Integer, Integer, String> { private ProgressBar progressBar; @Override protected void onPreExecute() { Log.d("===onPreExecute","线程id="+Thread.currentThread().getId() + ",线程名=" + Thread.currentThread().getName()); //这个方法里面主要是做一些准备性的工作,例如初始化一个滚动条 progressBar = new ProgressBar(MainActivity.this); //设置进度条显示 progressBar.setVisibility(View.VISIBLE); //把进度条添加到RelativeLayout中去 root.addView(progressBar); } @Override protected String doInBackground(Integer... params) { Log.d("===doInBackground","线程id="+Thread.currentThread().getId() + ",线程名=" + Thread.currentThread().getName()); if (params != null && params.length > 0) { //我们传入的参数存在 int i = 0; int total = params[0]; while (i < total) { i++; try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } publishProgress(i, total);//把进度发布出去 } } return "执行完成"; } @Override protected void onPostExecute(String s) { Log.d("===onPostExecute","线程id="+Thread.currentThread().getId() + ",线程名=" + Thread.currentThread().getName()); if (s != null && s.length() > 0) { //当进度条执行完成就显示当前进度为完成,并让进度条不再显示 tv_status.setText(s); progressBar.setVisibility(View.GONE); } } //只要在doinbackground()方法中执行了publishProgress(i,total); //那么onProgressUnpdate()方法就会被执行 @Override protected void onProgressUpdate(Integer... values) { Log.d("===onProgressUpdate","线程id="+Thread.currentThread().getId() + ",线程名=" + Thread.currentThread().getName()); if (values != null && values.length > 0) { int current = values[0]; int total = values[1]; progressBar.setProgress(current); progressBar.setMax(total); //如果这里不加“%”android.content.res.Resources$NotFoundException: String resource ID #0x1 //显示下载进度 百分比变化 mTextView.setText(100 * current / total + "%"); } } } }
相关文章推荐
- MYSQL的笔记
- 189. Rotate Array
- JavaScript - MutationObserver
- Long类型比较的陷阱
- 调试中关于__FILE__, __LINE__ 及 __FUNCTION__ 用法
- blockchain名词解析
- C#单例模式
- Tomcat 部署详解
- DNS子域授权
- Java-坦克大战
- 正确、安全地停止SpringBoot应用服务
- 用cmd运行php代码、socket
- LeetCode 292. Nim Game
- 正则表达式详解
- Redis(五):关于过期键(2)过期键的删除
- NYOJ-111 分数加减法
- git 使用部分总结
- Hibernate 笔记4 实现对数据库的增删改查
- 移动的导航栏的实现
- Linux下编译FFmpeg之下载源文件并编译