Android子线程中更新UI

2018-04-02  本文已影响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();
            }
        });
    }
上一篇 下一篇

猜你喜欢

热点阅读