Android中使用Handler机制更新UI的三种解决方案

最近想把学习Android过程中的Handler使用经验写下来,供自己以后查看,也与大家一起分享。

使用Handler其实不得不与Android中的线程或者说Java中的多线程扯上关系。本篇文章只会用到最基本的线程使用,不会涉及太难的,关于Android的线程我们以后再讨论。在Android中每新建一个Activity,该Activity(理解为界面)就是一个线程,是一个主线程,也称之为UI线程。主线程可以更新界面元素,不会出现问题。每当新建一个线程new Thread,该线程就是一个子线程,Android规定子线程是不能直接更新UI界面的,否则会出问题。

下面将会使用Android提供的Handler机制在子线程中更新UI.分别使用3种方式,3种方式相互联系又有区别。

(1)Handler.post()方式

该方法使用Handler中的post()方法更新UI,这里会涉及Thread,Runnable两个线程的概念,先暂且忽略吧。该方法比较简单,容易理解。先贴上代码:

public class MainActivity extends Activity {

    private TextView text;
    private Handler handler = new Handler();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        text = (TextView) findViewById(R.id.id_text);

        /**
         * new Thread()在该线程中实现你具体的业务逻辑,比如网络请求,耗时操作等等;
         * new Thread()是一个子线程,是非UI线程,如果在该线程中需要更新界面,则需要使用Handler;
         *
         */
        new Thread() {
            @Override
            public void run() {//在run()方法实现业务逻辑;
                //...

                //更新UI操作;
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        text.setText("使用Handler更新了界面");
                    }
                });

            }
        }.start();
    }
}

注意看其中的注释。开发者的对线程的业务逻辑操作写在Thread.run()方法中,更新UI的操作写到Runnable.run()方法中。实现效果如下:

(2)Handler.post(),内部类实现Runnable接口方式

该方法与方法1非常像,只是新建了一个内部类,并且实现了Runnable接口,然后在post()方法中不用new一个匿名内部类了。相对来说逻辑上更加清楚。思路同方法1.贴上代码如下:

public class MainActivity extends Activity {

    private TextView text;
    private Handler handler = new Handler();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        text = (TextView) findViewById(R.id.id_text);
        final MyRunnable myRunnable = new MyRunnable();//定义MyRunnable的对象;

        new Thread() {

            @Override
            public void run() {
                handler.post(myRunnable);//调用Handler.post方法;
            }
        }.start();
    }

    class MyRunnable implements Runnable {//内部类实现Runnable接口;

        @Override
        public void run() {//还是在Runnable重写的run()方法中更新界面;
            text.setText("使用Handler更新了界面");
        }
    }
}

注意提醒一点:Thread必须调用start()方法,否则线程不会被执行。实现效果如下:

(3)sendMessage(),handleMessage()方式

在Handler中有两个非常重要的方法,sendMessage()和handleMessage()方法,sendMessage()方法用于在线程中向Handler发送一个消息,handleMessage()用于捕获该消息,并且更新UI.代码如下:

public class MainActivity extends Activity {

    private TextView text;
    private Handler handler = new Handler() {

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case 1:
                    text.setText("使用Handler更新了界面");
                    break;
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        text = (TextView) findViewById(R.id.id_text);

        new Thread() {

            @Override
            public void run() {
                //...你的业务逻辑;
                Message message = new Message();//发送一个消息,该消息用于在handleMessage中区分是谁发过来的消息;
                message.what = 1;
                handler.sendMessage(message);
            }
        }.start();
    }
}

实现效果同上述两个方法:

至此,已经基本实现了在子线程中使用Handler更新了UI界面。能满足最基本的开发需要。当然Handler中还有很多细节以及注意事项,请听下回分解。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-07 00:59:56

Android中使用Handler机制更新UI的三种解决方案的相关文章

Android中的Handler机制

直接在UI线程中开启子线程来更新TextView显示的内容,运行程序我们会发现,如下错 误:android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.翻译过来就是:只有创建这个控件的线程才能去更新该控件的内容. 所有的UI线程要去负责View的创建并且维护它,例如更新冒个TextView的显示,都必

android中实现service动态更新UI界面

案例:通过service向远程服务器发送请求,根据服务器返回的结果动态更新主程序UI界面,主程序可实时关闭或重启服务. 注册BroadcastReceiver 在主程序activity中注册一个BroadcastReceiver,用于接收Service发布的广播. @Override protected void onStart() {//重写onStart方法 dataReceiver = new DataReceiver(); IntentFilter filter = new Intent

Android笔记(二十九) Android中的Handler机制

Android的UI操作并不是线程安全的,这就意味着如果有多个线程并发操作UI组件,可能会导致线程安全问题,为了解决这个问题,Android制定了一条简单的规则:只允许UI线程修改Activity里的UI组件,如果其他线程去修改UI组件,则会抛出异常,简单示例演示: 实现点击按钮5秒钟之后,改编TextView的文字. package cn.lixyz.handlertest; import android.app.Activity; import android.support.v7.app.

Java中实现文件上传下载的三种解决方案

第一点:Java代码实现文件上传 FormFile file=manform.getFile(); String newfileName = null; String newpathname=null; String fileAddre="/numUp"; try { InputStream stream = file.getInputStream();// 把文件读入 String filePath = request.getRealPath(fileAddre);//取系统当前路径

Android 在子线程中更新UI的几种方法

第一种: new Handler(context.getMainLooper()).post(new Runnable() { @Override public void run() { // 在这里运行你要想的操作 比方直接在这里更新ui或者调用回调在 在回调中更新ui } }); context是你传过来的context对象 另外一种: // 假设当前线程是UI线程,那么行动是马上运行.假设当前线程不是UI线程,操作是公布到事件队列的UI线程 // 由于runOnUiThread是Activ

Android中的Handler消息机制

转自:http://blog.csdn.net/liuhe688/article/details/6407225 在分析Android消息机制之前,我们先来看一段代码: public class MainActivity extends Activity implements View.OnClickListener { private TextView stateText; private Button btn; @Override public void onCreate(Bundle

Android中的Handler的机制与用法详解

概述: 很多android初学者对android 中的handler不是很明白,其实Google参考了Windows的消息处理机制, 在Android系统中实现了一套类似的消息处理机制.在下面介绍handler机制前,首先得了解以下几个概念:     1. Message 消息,理解为线程间通讯的数据单元.例如后台线程在处理数据完毕后需要更新UI,则可发送一条包含更新信息的Message给UI线程.     2. Message Queue 消息队列,用来存放通过Handler发布的消息,按照先

Android攻城狮 Android中更新UI的几种方式

Android中更新UI的几种方式: 1. Activity 的 runOnUiThread() 2. Handler 的 post() 3. Handler 的 sendMessage() 4. View 的 post() 1 public class FiveActivity extends Activity { 2 3 private TextView textView; 4 5 private Handler handler = new Handler() { 6 public void

Android 更新UI的两种方法——handler和runOnUiThread() - $firecat的代码足迹$ - 博客频道 - CSDN.NET

文章来源:http://www.2cto.com/kf/201302/190591.html Android 更新UI的两种方法——handler和runOnUiThread() 在Android开发过程中,常需要更新界面的UI.而更新UI是要主线程来更新的,即UI线程更新.如果在主线线程之外的线程中直接更新页面显示常会报错.抛出异常:android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread th