Android实现异步的几种方法

来源:互联网 发布:怎么查看当前linux版本 编辑:程序博客网 时间:2024/05/18 00:51

在Android项目中,有经验的开发人员都知道,一些耗时的IO操作等都必须在子线程中去操作,那么可以有哪些方法来开启子线程呢,一般可以使用Java中自带的几种方法,也可以使用Andorid特有的一些类。

用Java来实现异步

主要有两种方法来实现异步,继承Thread类和实现Runnable接口

1.继承Thread类

先上代码

public class MyThread extends Thread {    private String name;    public MyThread(String name){        this.name = name;    }    @Override    public void run() {        System.out.println(name);    }}public class MainTest {    public static void main(String[] args){        MyThread myThread1 = new MyThread("myThread1");        MyThread myThread2 = new MyThread("myThread2");        MyThread myThread3 = new MyThread("myThread3");        myThread1.start();        myThread2.start();        myThread3.start();    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

MyThread继承自Thread类,重写run()方法,在run()方法中写上子线程需要执行的任务就可以了。然后在测试的main()方法中new MyThread()。再调用start()方法。这样就完成了使用继承Thread,来实现子线程从创建到执行的整个过程。

2.实现Runnable接口

public class MyThreadRunnable implements Runnable {    private String name;    public MyThreadRunnable(String name){        this.name = name;    }    @Override    public void run() {        System.out.println(name);    }}public class MainTest {    public static void main(String[] args){        MyThreadRunnable r1 = new MyThreadRunnable("r1");        MyThreadRunnable r2 = new MyThreadRunnable("r1");        MyThreadRunnable r3 = new MyThreadRunnable("r1");        Thread t1 = new Thread(r1);        Thread t2 = new Thread(r2);        Thread t3 = new Thread(r3);        t1.start();        t2.start();        t3.start();    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

MyThreadRunnable实现Runnable接口,并且在run()方法中实现自己的任务,这跟前面的很类似,只是后面要开启线程的时候不仅需要new MyThreadRunnable()而且还需要new Thread()并且把前面的对象传入,再通过Thread调用start()方法来启动线程。 
上面的方法来开启子线程,还可以用静态内部类来实现,这样代码看起来会更加简洁。

new Thread(new Runnable() {            @Override            public void run() {                System.out.println("xxxx");            }        }).start();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

从代码层面来看,继承Thread看起来更加方便,但是java是单继承的,在实际生产中,一般都需要某个类,所以实现Runnable的用法会多一点。

使用Android特有的方法来实现异步

1.AsyncTask

public class MainActivity extends Activity {    private ProgressBar mProgressBar;    private ImageView mImageView;    @Override    public void onCreate(Bundle savedInstanceState, PersistableBundle persistentState) {        super.onCreate(savedInstanceState, persistentState);宁波整形医院http://www.zuanno.com/宁波最好的整形医院http://www.zuanno.com/        MyAsyncTask myAsyncTask = new MyAsyncTask();        myAsyncTask.execute("www.baidu.com/xxx.jpg");    }    class MyAsyncTask extends AsyncTask<String, Integer, Bitmap>{        @Override        protected void onPreExecute() {            //这里是开始线程之前执行的,是在UI线程            mProgressBar.setMax(100);            super.onPreExecute();        }        @Override        protected Bitmap doInBackground(String... params) {            //这是在后台子线程中执行的            Bitmap bitmap = null;            try {                URL url = new URL(params[0]);                HttpURLConnection connection = (HttpURLConnection) url.openConnection();                InputStream inputStream = connection.getInputStream();                bitmap = BitmapFactory.decodeStream(inputStream);                publishProgress(70);//这里是更新进度                inputStream.close();            } catch (Exception e) {                e.printStackTrace();            }            return bitmap;        }        @Override        protected void onCancelled() {            //当任务被取消时回调            super.onCancelled();        }        @Override        protected void onProgressUpdate(Integer... values) {            super.onProgressUpdate(values);            //更新进度            mProgressBar.setProgress(values[0]);        }        @Override        protected void onPostExecute(Bitmap bitmap) {            super.onPostExecute(bitmap);            //当任务执行完成是调用,在UI线程            mImageView.setImageBitmap(bitmap);        }    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63

MyAsyncTask基础自AsyncTask,三个泛型分别为,String:是传入参数类型,可以传多个,Integer:是进度显示的参数类型,也可以传多个,Bitmap:是任务执行完的返回类型,这里就是返回一个Bitmap。 
使用AsyncTask来实现异步的有点就是简单便捷,各个过程都有明确的回调,过程可控。但是缺点就是要是执行多个异步,就会变得很复杂。

2.Handler

public class HandlerTestActivity extends Activity {    Handler mHandler = new Handler(){        @Override        public void handleMessage(Message msg) {            super.handleMessage(msg);            int what = msg.what;            if(what == 0){                //在主线程中需要执行的操作,一般是UI操作            }        }    };    @Override    public void onCreate(Bundle savedInstanceState, PersistableBundle persistentState) {        super.onCreate(savedInstanceState, persistentState);        Thread thread = new Thread(new Runnable() {            @Override            public void run() {                //在子线程中执行任务,执行完成或需要通知UI线程时调用以下方法                mHandler.sendEmptyMessage(0);            }        });        thread.start();    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

上面就是最简单的使用Handler完成子线程和主线程的通信(子线程发消息给主线程)

public class LooperThreadActivity extends Activity {    private Handler mHandler = null;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        new MyThread().start();        //发消息到目标子线程        mHandler.obtainMessage(0).sendToTarget();    }    class MyThread extends Thread{        @Override        public void run() {            super.run();            //1.建立消息循环,初始化Looper            Looper.prepare();            mHandler = new Handler(){                @Override                public void handleMessage(Message msg) {                    super.handleMessage(msg);                    int what = msg.what;                    if(what == 0){                        //                    }                }            };            //启动消息循环            Looper.loop();        }    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

上面是主线程发消息给子线程,也是比较类似的,只不过在子线程中,需要初始化Looper.prepare()和Looper.loop()。

RxJava

这个比较新,学习路线比较陡峭,但是一旦入门,使用起来真的很爽。

public class RxJavaTestActivity extends Activity {    private ImageView mImageView;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        Observable.just("")                .map(new Func1<String, Bitmap>() {                    @Override                    public Bitmap call(String s) {                        //可以在这里执行耗时操作,比如下载网络图片,然后转化为Bitmap                        return null;                    }                }).subscribeOn(Schedulers.io())//把工作线程指定为了IO线程                .observeOn(AndroidSchedulers.mainThread())//把回调线程指定为了UI线程                .subscribe(new Action1<Bitmap>() {                    @Override                    public void call(Bitmap bitmap) {                        //这里是在UI线程,这里显示了图片                        mImageView.setImageBitmap(bitmap);                    }                });    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

这里是最简单的使用了RxJava,来实现异步操作。RxJava还有更多更强大的功能等你去发现。