AsyncTask介绍
Android的AsyncTask比Handler更轻量级一些,适用于简单的异步处理。
首先明确Android之所以有Handler和AsyncTask,都是为了不阻塞主线程(UI线程),且UI的更新只能在主线程中完成,因此异步处理是不可避免的。
Android为了降低这个开发难度,提供了AsyncTask。AsyncTask就是一个封装过的后台任务类,顾名思义就是异步任务。
AsyncTask直接继承于Object类,位置为android.os.AsyncTask。要使用AsyncTask工作我们要提供三个泛型参数,并重载几个方法(至少重载一个)。
AsyncTask定义了三种泛型类型 Params,Progress和Result。
Params 启动任务执行的输入参数,比如HTTP请求的URL。
Progress 后台任务执行的百分比。
Result 后台执行任务最终返回的结果,比如String。
使用过AsyncTask 的同学都知道一个异步加载数据最少要重写以下这两个方法:
1.doInBackground(Params…) 后台执行,比较耗时的操作都可以放在这里。注意这里不能直接操作UI。此方法在后台线程执行,完成任务的主要工作,通常需要较长的时间。在执行过程中可以调用publicProgress(Progress…)来更新任务的进度。
2.onPostExecute(Result) 相当于Handler 处理UI的方式,在这面可以使用在doInBackground 得到的结果处理操作UI。 此方法在主线程执行,任务执行的结果作为此方法的参数返回
有必要的话你还得重写以下这三个方法,但不是必须的:
onProgressUpdate(Progress…) 可以使用进度条增加用户体验度。 此方法在主线程执行,用于显示任务执行的进度。
onPreExecute() 这里是最终用户调用Excute时的接口,当任务执行之前开始调用此方法,可以在这里显示进度对话框。
onCancelled() 用户调用取消时,要做的操作
使用AsyncTask类,以下是几条必须遵守的准则:
Task的实例必须在UI thread中创建;
execute方法必须在UI thread中调用;
不要手动的调用onPreExecute(), onPostExecute(Result),doInBackground(Params...), onProgressUpdate(Progress...)这几个方法;
该task只能被执行一次,否则多次调用时将会出现异常;
MainActivity.java
package ghw.com.usingasynctask;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
public class MainActivity extends AppCompatActivity {
TextView text;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
text = (TextView) findViewById(R.id.textView);
findViewById(R.id.read).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ReadURL("http://www.pku.edu.cn/");
}
});
}
public void ReadURL(String url) {
new AsyncTask<String, Void, String>() {
@Override
protected String doInBackground(String... params) {
try {
URL url = new URL(params[0]);
URLConnection connection = url.openConnection();
InputStream iStream = connection.getInputStream();
InputStreamReader isr = new InputStreamReader(iStream);
BufferedReader br = new BufferedReader(isr);
String line;
StringBuilder builder = new StringBuilder();
while ((line = br.readLine()) != null) {
builder.append(line);
}
br.close();
iStream.close();
return builder.toString();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPreExecute() {
Toast.makeText(MainActivity.this, "开始读取", Toast.LENGTH_SHORT).show();
super.onPreExecute();
}
@Override
protected void onPostExecute(String s) {
Toast.makeText(MainActivity.this, "读取完成", Toast.LENGTH_SHORT).show();
text.setText(s);
super.onPostExecute(s);
}
@Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
@Override
protected void onCancelled(String s) {
super.onCancelled(s);
}
@Override
protected void onCancelled() {
super.onCancelled();
}
}.execute(url);
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="ghw.com.usingasynctask.MainActivity"
android:orientation="vertical">
<Button
android:id="@+id/read"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button"
tools:layout_editor_absoluteX="16dp"
tools:layout_editor_absoluteY="16dp" />
<ScrollView
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
tools:layout_editor_absoluteX="154dp"
tools:layout_editor_absoluteY="128dp" />
</ScrollView>
</LinearLayout>
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="ghw.com.usingasynctask">
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Android Studio添加网络权限
使用Android Studio添加用户网络权限的时候和ADT的可视化添加是不同的,具体做法是在AndroidManifest文件中添加一行代码,添加的地方如图:
程序运行图片