美文网首页
Android子线程中更新UI

Android子线程中更新UI

作者: 艾剪疏 | 来源:发表于2018-04-02 11:20 被阅读14次

    之前做小桔灯的时候,就觉得把加载主UI的请求放入到网络数据的操作之后是一个不合适的地方。但是一直没有去弄,昨天,把这一块好好的学了一下,做个笔记。

    1 Android子线程中更新UI,如何操作?

    我没有Handler,就直接用的runOnUiThread
    http://gqdy365.iteye.com/blog/2112471

    @Override
        public void initData() {
            getUrlDatas();
            mActivity.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    getReadData(urls);//网络请求获取数据
                }
            });
        }
    
    

    解释如下:
    https://blog.csdn.net/lib739449500/article/details/43197181

    2 如果使用Handler,如何传递数据?

    首先,我需要获取两种数据

        private List<List<Object>> mAllDatas = new ArrayList();//初始化数据
        private List<Object> mDataType = new ArrayList();//布局类型
    

    最开始,找了一堆很NB的方法,做尝试,但是自己不是很理解,所以也没有做成功,但是下面的方法确实很有用,下次有合适的机会,一定搞懂:

    https://www.cnblogs.com/yunfang/p/5431435.html
    https://www.cnblogs.com/renqingping/archive/2012/10/25/Parcelable.html
    https://blog.csdn.net/wirelessqa/article/details/8589200
    https://www.jianshu.com/p/0a274564a4b1

    于是,找了下面的方法来完成该功能:使用 msg.obj = bean,将需要传递的数据封装到一个Bean 中,就可以了。

    这方法竟然是百度知道上面的答案,无语。

    Bean.java:
     
    public class Bean {
        public Bitmap bitmap;
        public HashMap<String, String> map;
    }
    MainActivity.java:
     
        private ImageView imageView;
        Handler handler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
     
                if (msg.what == 1) {
                    Bean obj = (Bean) msg.obj;
     
                    imageView.setImageBitmap(obj.bitmap);
                    Toast.makeText(MainActivity.this, obj.map.get("a"), Toast.LENGTH_LONG).show();
                }
            }
        };
     
        private HashMap<String, String> map = new HashMap<>(0);
     
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            imageView = (ImageView) findViewById(R.id.imageView);
            map.put("a", "1");
            map.put("b", "2");
            map.put("c", "3");
            map.put("d", "4");
            map.put("e", "5");
            new Thread(new Runnable() {
                @Override
                public void run() {
                    Bean bean = new Bean();
                    bean.bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
                    bean.map = map;
     
     
                    Message msg = handler.obtainMessage();
                    msg.what = 1;
                    msg.obj = bean;
     
                    handler.sendMessage(msg);
                }
            }).start();
        }
    

    3 主页面数据加载完成,但是非要我触摸页面,并滑动之,数据才能显示出来。

    这个bug,又搞了半天,到最后发现是方法的调用顺序又问题。

    最开始的代码是,先调getReadData方法,方法通过网络请求的数据,会赋值给全局变量,然后我在通过initRecycleViewData();获取全局变量数据,填充RecycleView。

    后来,我把initRecycleViewData();,放到getReadData方法中去执行就OK了,原因,我也不是太清楚,应该和方法的调用顺序有关,以后写类似的代码要注意。

    @Override
        public void initData() {
            getUrlDatas();
            mActivity.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    getReadData(urls);
                    initRecycleViewData();
                }
            });
        }
    

    相关文章

      网友评论

          本文标题:Android子线程中更新UI

          本文链接:https://www.haomeiwen.com/subject/ejgocftx.html