美文网首页
2019-04-23android进行异步更新控件的四种方式

2019-04-23android进行异步更新控件的四种方式

作者: 奥雷里亚诺下划线_上校 | 来源:发表于2019-04-23 15:02 被阅读0次

最近在尝试在app里对接百度ai的相关图片试别的api,发现网络请求是无法写在主线程中的(网路请求还需要申请权限),主要原因大致和主线程为了保护ui控件的正常使用而生成的一种保护机制。

1.Handler消息传递机制

public class MainActivity4Handler extends AppCompatActivity {
    private TextView tv;

    //事件更新器
    Handler handler = new Handler() {
        public void handleMessage(android.os.Message msg) {
            if (msg.what == 0x123) {
                //符合条件,更新控件
                tv.setText("更新后的TextView:" + (String) msg.obj);
            }
        }     
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tv = (TextView) findViewById(R.id.tv);
        new MyThread().start();//   启动一个新线程
    }

    class MyThread extends Thread {
        @Override
        public void run() {
            //异步处理事件
            //延迟两秒更新
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            //传递消息(只传递一个数字)
            //handler.sendEmptyMessage(0x123);
            //传递一个message对象
            Message message = new Message();
            String x = "ssss";
            message.what = 0x123;
            message.obj = x;//这里可以传json字符串
            handler.sendMessage(message);
        }
    }
}

2. 使用AsyncTask异步任务

public class MainActivity4Async extends AppCompatActivity {
    private TextView tv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tv = (TextView) findViewById(R.id.tv);
        new Yibu().execute(tv);//执行异步
    }

    //泛型参数分别代表,传入,中间,返回值
    class Yibu extends AsyncTask<TextView, String, String>{

        //预处理,可以随意提示一些信息
        @Override
        protected void onPreExecute() {
            Toast.makeText(MainActivity4Async.this, "这里是预处理", Toast.LENGTH_SHORT).show();
        }

        //调用publishProgress()方法后,该方法会很快执行,利用方法中携带的参数进行对界面进行刷新
        @Override
        protected void onProgressUpdate(String... values) {
            for (int i = 0; i < values.length; i++) {
                tv.setText(values[i]);
            }
        }

        //执行后台程序
        @Override
        protected String doInBackground(TextView... views) {
            //比如耗时多的联网操作等
            TextView tv = views[0];
            tv.setText("中途更新");

            publishProgress("string 字符串,可以是json格式,用来传递执行完成后的结果");
            return null;
        }

        //后台任务执行完毕后,可以通过此方法进行提示
        @Override
        protected void onPostExecute(String s) {
            Toast.makeText(MainActivity4Async.this, "处理完成", Toast.LENGTH_SHORT).show();

        }
    }
}

3. 使用runOnUiThread(action)方法

public class MainAc4UiThread extends AppCompatActivity {
    private TextView tv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tv = (TextView) findViewById(R.id.tv);
        new MyThread().start();//必须在Activity中实现
    }

    class MyThread extends Thread {
        @Override
        public void run() {
            //写这个方法,表示新开的ui更新线程
            runOnUiThread(new Runnable() {

                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    try {
                        //延迟两秒更新
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    tv.setText("更新后的TextView");
                }
            });
        }
    }
}

4. 使用Handler的post(Runnabel r)方法

这个没什么特别的,核心代码块。

 Handler handler = new Handler();
        handler.post(new Runnable(){
            @Override
            public void run() {
                try {
                    //延迟两秒更新
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                tv.setText("更新后的TextView");
            }

综合四种用法,个人还是喜欢使用使用第二种,生命周期很清楚,同时也是官方提供的一种方法,也便于实现代码的分离,在异步使用不多的情况下推荐使用。


最后更新一下,理解了以上四种原理后推荐使用RxAndroid框架,具体的文章可以参阅https://www.jianshu.com/p/1cad42c4bc04
可以省下大量的代码量。

相关文章

  • 2019-04-23android进行异步更新控件的四种方式

    最近在尝试在app里对接百度ai的相关图片试别的api,发现网络请求是无法写在主线程中的(网路请求还需要申请权限)...

  • android进行异步更新UI的四种方式

    原文引自http://segmentfault.com/a/1190000003702775 大家都知道由于性能要...

  • 同步异步区别

    同步、异步有什么区别 在进行网络编程时,我们通常会看到同步、异步、阻塞、非阻塞四种调用方式以及他们的组合。 其中同...

  • Qt学习——3-1

    connect 控件到槽 清除 QMessageBox toInt() 控件链接到槽的四种方式:connect...

  • 异步操作和Async函数

    异步操作和Async函数 异步操作 异步编程的四种方式:回调函数、事件监听、发布/订阅、Promise。 为什么N...

  • $.getJSON、$.get、$.post、$.ajax用法

    在WEB开发中异步请求方式普遍使用,ajax技术减少程序员的工作量,也提升用户交互体验。AJAX的四种异步请求方式...

  • AssetBundle入门笔记02

    AB包加载的四种方式 1.AssetBundle.LoadFromMemoryAsync(从内存中加载)异步: 同...

  • ajax 及同步与异步

    定义:无需加载整个页面,只更新部分网页的技术。通过与后台进行数据交换,使网页实现异步更新。 参数: 1、请求方式t...

  • 从0系统学Android--3.2四种基本布局

    从0系统学Android--3.2四种基本布局 本系列持续更新中.... 3.3 系统控件不够用?创建自定义控件 ...

  • React_setState

    setState : 修改组件内变量。 优点 可以对更新进行优化。(异步更新)setState会将大批量的更新进行...

网友评论

      本文标题:2019-04-23android进行异步更新控件的四种方式

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