• Android实现异步的几种方法


    在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还有更多更强大的功能等你去发现。

  • 相关阅读:
    ☆ [HDU2157] How many ways?? 「矩阵乘法求路径方案数」
    [HDU2065] "红色病毒"问题
    [SP1043] GSS1
    [POJ3233] Matrix Power Series
    「网络流24题」圆桌问题
    [BZOJ4260] Codechef REBXOR
    [HDU5536] Chip Factory
    ☆ [HDU4825] Xor Sum「最大异或和(Trie树)」
    「网络流24题」最长不下降子序列问题
    「网络流24题」试题库问题
  • 原文地址:https://www.cnblogs.com/zhujiabin/p/9323351.html
Copyright © 2020-2023  润新知