当前位置:   article > 正文

Android网络请求完成之后更新UI的几种方法_android 主线程怎么启动一个阻塞的网络请求,根据结果更新ui

android 主线程怎么启动一个阻塞的网络请求,根据结果更新ui

首先我们需要明确几点:
1、网络请求因为是耗时操作,不能再主线程中进行,所以只能在子线程中进行
2、更新UI是必须在主线程中进行的
所以,我们要在网络请求之后更新UI需要做以下几个步骤:
1、在主线程中new一个子线程
2、在子线程中进行网络请求
3、网络请求结束之后更新UI
对于上面的3个步骤有两种方法可以供选择,一个是采用Thread和Handler,另外一种就是采用AsynTask。
(1)对于Thread加Handler,就是在子线程(Thread)中完成加载之后,利用Handler将网络请求得到的数据放在Message中,并在Handler中实现UI更新。
(2)对于AsynTask,就是要重写doInBackground()方法完成网络加载这样的耗时操作,重写onPostExecute()方法,因为onPostExecute()实在主线程中进行的,所以在onPostExecute()中进行UI的更新。下面的代码是我的一个例子,首先是类BitmapTask继承自AsyncTask

 class BitmapTask extends AsyncTask<Object, Void, Bitmap> {

        private ImageView ivPic;
        private String url;

        /**
         * 后台耗时操作,存在于子线程中
         *
         * @param params
         * @return
         */
        @Override
        protected Bitmap doInBackground(Object[] params) {
            ivPic = (ImageView) params[0];//在网上加载完图片之后,更新的ImageView
            url = (String) params[1];//网络图片的URL地址
            return downLoadBitmap(url);
        }
        /**
         * 耗时方法结束后执行该方法,主线程中
         *
         * @param result
         */
        @Override
        protected void onPostExecute(Bitmap result) {
            if (result != null) {
                ivPic.setImageBitmap(result);//更新UI
            }
        }
    }
    /**
     * 网络下载图片
     * @param url
     * @return
     */
    private Bitmap downLoadBitmap(String url) {
        HttpURLConnection conn = null;
        try {
            conn = (HttpURLConnection) new URL(url).openConnection();
            conn.setConnectTimeout(5000);
            conn.setReadTimeout(5000);
            conn.setRequestMethod("GET");

            int responseCode = conn.getResponseCode();
            if (responseCode == 200) {
                /**图片压缩
                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inSampleSize=2;//宽高压缩为原来的1/2
                options.inPreferredConfig=Bitmap.Config.ARGB_4444;
                bitmap = BitmapFactory.decodeStream(conn.getInputStream(),null,options);
                 */
                bitmap=BitmapFactory.decodeStream(conn.getInputStream());
                return bitmap;
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            conn.disconnect();
        }
        return null;
    }
  • 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

写好AsynTask之后,就是在主线程中调用AsynTask的execute方法

 new BitmapTask().execute(ImageView1, url);//启动AsyncTask
  • 1

这样就可以实现在网络请求完之后更新UI。
但是上面两个方法都存在一个问题就是:若我有两个界面A和B,我的界面A需要在网络上获取图片然后显示在界面上,并且我在界面A中采用上面的两个方法其中一个,因为网络请求是耗时操作,并且什么时候请求完成是说不准的,如果我在网络请求还没有结束的时候切换到了界面B,这时如果在网络结束要更新UI了,但是此时的界面是B,那么程序就会报错。
对于这个问题的解决办法就是:
(1)加载界面时显示之前缓存的界面,在下拉刷新中进行网络请求和更新UI
(2)设置一个public static int flag;用flag来标志当前是界面A还是界面B,若网络加载完成时是界面A,再进行UI更新
这两个方法各有适用场合,根据实际场合进行选择。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/465203
推荐阅读
相关标签
  

闽ICP备14008679号