美文网首页
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();
            }
        });
    }

相关文章

  • 封装工具类无法使用runOnUiThread解决办法

    由于Android中不能在子线程中更新ui,所以平时在子线程中需要更新ui时可以使用Android提供的RunOn...

  • Android多线程

    1.沿用java的子线程创建 2.在子线程中不能更新UI,那么在Android中更新UI的方法 runOnUiTh...

  • 【Android】AsyncTask源码分析

    在Android中ui是非线程安全的,更新ui只能在主线程操作,所以我们平时如果遇到子线程更新UI的情况,必须要切...

  • Android Handler探索

    在日常开发中,我们常用Handler来在子线程更新主线程UI,这是因为Android系统不允许我们在子线程更新UI...

  • Android 进阶之 Handler 消息机制

    众所周知,在 Android 中,非 UI 线程中是不能更新 UI 的,如果在子线程中做 UI 相关操作,可能会出...

  • Android 跨线程更新 UI

    在 Android 中,视图组件并不是线程安全的。出于线程保护,Android 会拒绝子线程对主线程 UI 的更新...

  • Android多线程编程

    1.在子线程中更新UI Android中更新UI元素,必须在主线程中进行,否则就会出现异常。 运行以上程序,你会发...

  • Handler内存泄露原理及解决方法

    前言 因为Android采取了单线程UI模型,开发者无法在子线程中更新UI,为此Android为我们提供了Hand...

  • Android在线程中更新UI和在协程中更新UI

    1、在子线程里面更新UI 我们都知道Android只能在主线程里面对UI更新,所以谷歌提供了很多在子线程里面更新U...

  • Handler使用原理

    Android中UI的更新在主线程中完成,为了避免ANR异常所以耗时的操作需要在子线程中完成。由于主线程和子线程中...

网友评论

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

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