浅谈Android多线程之AsyncTask

来源:互联网 发布:idea修改js不重启 编辑:程序博客网 时间:2024/06/09 23:15

Android多线程

       在Android系统中,系统会为每个程序分配一个主线程,我们称为UI线程,在默认的情况下,程序UI组件的所有操作都在UI线程中完成,包括组件的点击,组件生命周期方法调用,组件更新等。。除了主线程之外的线程我们称为Work线程,在非UI线程的其他地方,我们不能对UI组件做任何操作。

 

为什么需要异步线程

       在Android系统中,系统不会为程序组件创建新的线程,这意味着我们对组件的操作都在UI线程中,但很多时候我们的程序需要时间去完成我们当前所下发的指令,如数据的读取、网络数据下载等,如果这些都在UI线程中完成,会导致我们的程序阻塞,甚至导致ANR(Application Not Responding)问题,这是我们无法容忍的。另外,UI线程不是线程安全的,所以我们不能在UI线程之外对组件进行操作。所以,在Android编程中,我们需要遵循以下两点:

1.   不能在UI线程中进行耗时的操作,以免阻塞程序

2.   不能在UI线程之外操作UI元素

所以,当我们需要做一些耗时的工作时,需要将其放在其他线程中

AsyncTask

       异步任务,简单来说,就是在UI线程之外异步的完成其他的任务。AsyncTask允许我们在后台执行一些耗时的工作,并可以随时获取操作的结果返回给UI组件和更新UI。

 

如何使用AsyncTask

使用AsyncTask,需要定义自己的类继承AsyncTask这个抽象类

AsyncTask类的泛型:

     

AsyncTask<Params,Progress,Result>

Params:传递给异步任务执行的参数类型

Progress:异步任务在执行的时候将执行的进度返回给UI线程的参数类型

Result:异步任务结束时返回给UI线程的结果类型

(在继承AsyncTask类时需要指定这三个泛型的类型,如果不指定的话,则需要将其指定成Void)

AsyncTask<void,void,void>

在执行AsyncTask任务时,需要执行以下4步

onPreExecute():这个方法在异步任务之前执行,在UI线程中执行,通常用于执行一些初始化工作

doInBackground(Params...params):这个方法在onPreExecute()执行之后执行,这个方法中编写异步任务的具体内容,并将结果返回给onPostExecute(Result…result),

onProgressupdate(Params...params):这个方法将异步任务的执行进度返回给UI界面,在UI线程中执行

onPostExecute(Result…result):在异步任务完成之后执行,在UI线程中执行,,并将结果显示在界面上


样例代码

package com.example.asyncapplication;import android.app.ProgressDialog;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.os.AsyncTask;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.view.Menu;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.ImageView;import java.io.IOException;import java.io.InputStream;import java.net.HttpURLConnection;import java.net.MalformedURLException;import java.net.URL;public class MainActivity extends AppCompatActivity {    private ImageView imageView ;    private Button button ;    private ProgressDialog dialog ;    private String image_path =            "https://image.baidu.com/search/detail?ct=503316480&z=0&ipn=d&word=%E5%AE%A4%E6%88%B7%E5%A0%87&step_word=&hs=2&pn=4&spn=0&di=153458700120&pi=0&rn=1&tn=baiduimagedetail&is=0%2C0&istype=0&ie=utf-8&oe=utf-8&in=&cl=2&lm=-1&st=undefined&cs=1934965698%2C3194616689&os=3255993430%2C2867249202&simid=3382483548%2C193253425&adpicid=0&lpn=0&ln=72&fr=&fmq=1497268616166_R&fm=&ic=undefined&s=undefined&se=&sme=&tab=0&width=undefined&height=undefined&face=undefined&ist=&jit=&cg=&bdtype=0&oriquery=&objurl=http%3A%2F%2Fg.hiphotos.baidu.com%2Fbaike%2Fs%3D220%2Fsign%3D2b60320ce6dde711e3d244f497efcef4%2F960a304e251f95ca2fca10bfca177f3e670952f8.jpg&fromurl=ippr_z2C%24qAzdH3FAzdH3Fkwthj_z%26e3Bkwt17_z%26e3Bv54AzdH3FetjoAzdH3Fba09l9_z%26e3Bip4%3Fu6%3Dwsw11tg&gsm=0&rpstart=0&rpnum=0" ;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        //添加弹出的对话框        dialog = new ProgressDialog(this) ;        dialog.setTitle("提示") ;        dialog.setMessage("正在读取,请稍后···") ;        imageView = (ImageView)findViewById(R.id.imageView) ;        button = (Button)findViewById(R.id.button) ;        button.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                //点击按钮时,执行异步任务的操作                new DownTask().execute(image_path) ;            }        }) ;    }    public class DownTask extends AsyncTask<String, Void, Bitmap> {        @Override        protected void onPreExecute() {            dialog.show() ;        };        protected Bitmap doInBackground(String... params) {  //三个点,代表可变参数            URL url = null;            Bitmap bitmap = null ;            try {                //网络图片下载                url = new URL(image_path);                HttpURLConnection conn = (HttpURLConnection) url.openConnection();                conn.setConnectTimeout(5000);                conn.setRequestMethod("GET");                conn.setDoInput(true);                InputStream inputStream = conn.getInputStream();                bitmap = BitmapFactory.decodeStream(inputStream);                inputStream.close();            } catch (MalformedURLException e) {                e.printStackTrace();            } catch (IOException e) {                e.printStackTrace();            }            return bitmap;        }        //主要是更新UI        @Override        protected void onPostExecute(Bitmap result) {            super.onPostExecute(result);            imageView.setImageBitmap(result) ;//更新UI            dialog.dismiss() ;        }    }    @Override    public boolean onCreateOptionsMenu(Menu menu) {        // Inflate the menu; this adds items to the action bar if it is present.        return true;    }}