Android实现异步的几种方法

来源:互联网 发布:python class 自己 编辑:程序博客网 时间:2024/05/22 02:04

在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();    }}

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();    }}

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

new Thread(new Runnable() {            @Override            public void run() {                System.out.println("xxxx");            }        }).start();

从代码层面来看,继承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);        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);        }    }}

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();    }}

上面就是最简单的使用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();        }    }}

上面是主线程发消息给子线程,也是比较类似的,只不过在子线程中,需要初始化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);                    }                });    }}

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

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 手机存储卡坏了怎么办 回南天地板潮湿怎么办 lg滚筒洗衣机门打不开怎么办 西门子滚桶洗衣机门打不开怎么办 洗衣机离合器螺丝卸不动怎么办 门锁保险栓坏了怎么办 小车电瓶没电了怎么办 重装机兵战车底盘坏了怎么办 父亲沉迷安利十年该怎么办 脚的大脚骨痛怎么办 自考准考证号忘记了怎么办 有桌子老师不出马怎么办 电商遇到职业打假人怎么办 超市遇到职业打假人怎么办 阿里巴巴碰到职业打假人怎么办 商家遇到职业打假人怎么办 买过期食品不赔怎么办 淘宝卖假货遇到打假师怎么办 网店遇到职业打假人怎么办 职业打假师把我起诉法院怎么办 被职业打假举报了怎么办 车档杆拉不动显示不在p档怎么办 宜人贷还不起了怎么办 买高跟鞋一只脚合适一只脚挤怎么办 脚瘦穿高跟鞋撑不起来怎么办 银川市阅海幼儿园进不去怎么办 考编专业不对口怎么办 北京55中国际部怎么办 初中数学没学好高中怎么办 靴子大了一码怎么办 靴子买大了一码怎么办 马丁靴大了一码怎么办 社保掌上通登录密码忘记怎么办 录微课时忘词怎么办 微课掌上通看不到信息怎么办 五年级学生上课很吵新老师怎么办 跟财务老师吵起来怎么办 qq把微信冻结了怎么办 微信给封号了怎么办 微信久了没登录冻结了怎么办 换手机号了微店怎么办