您的位置:首页 > 其它

AsyncTask专题之二 AsyncTask基础

2016-07-10 15:05 211 查看
概念性的东西,自行百度,我就说下怎么用的。分如下几个部分

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 + "%");

}

}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: