如何利用Handler更新android的UI

 

提出问题

新手刚开始接触Android线程编程的时候,会想到如下使用如下代码:

复制到剪贴板  Java代码

  1. new Thread( new Runnable() {    
  2.     public void run() {    
  3.          myView.invalidate();   
  4.      }           
  5. }).start();  

 

但是:该实现方法是不可行的。

分析问题:

因为:Android UI操作并不是线程安全的,这些操作必须在UI线程中执行

1.myView.invalidate()是UI操作;

2.new Thread创建了一个新的线程,是一个子线程,而不是UI线程,在这个新的线程里面对view进行刷新,这样是不安全的。

解决问题:

那么如何解决这个问题呢?

答案:使用Handler来实现UI线程的更新的。

实现步骤:

1.在view类里面定义一个Handler变量,这并没有开启一个新的线程,因此在handler里面更新本view是安全的;

2.然后我们创建一个线程,通过这个线程来给activity的handler变量发送消息,同时通过这个线程进行延时。

 

意即:

1.Handler接收消息和处理消息;

2.创建一个线程,来给Handler发送消息;

 

消息处理三部曲:

1.发送消息;

2.接收消息;

3.处理消息;

代码参考

首先创建简单的View,代码如下:

复制到剪贴板  Java代码

  1. package com.ray.handler;  
  2. import android.content.Context;  
  3. import android.graphics.Canvas;  
  4. import android.graphics.Color;  
  5. import android.graphics.Paint;  
  6. import android.graphics.Point;  
  7. import android.graphics.drawable.Drawable;  
  8. import android.view.View;  
  9.    
  10. public class BounceView extends View {  
  11.    
  12.     float x = 40;  
  13.     public BounceView(Context context) {  
  14.          super(context);  
  15.     }  
  16.    
  17.     @Override  
  18.     protected void onDraw(Canvas canvas) {  
  19.          x+=10;  
  20.          Paint mPaint = new Paint();  
  21.          mPaint.setAntiAlias(true);  
  22.          mPaint.setColor(Color.GREEN);  
  23.          canvas.drawCircle(x, 40, 40, mPaint);  
  24.     }  
  25. }  
  26.    

创建Activity类,代码如下:

复制到剪贴板  Java代码

  1. package com.ray.handler;  
  2. import android.app.Activity;  
  3. import android.content.Context;  
  4. import android.graphics.Canvas;  
  5. import android.graphics.Color;  
  6. import android.graphics.Paint;  
  7. import android.os.Bundle;  
  8. import android.os.Handler;  
  9. import android.os.Message;  
  10. import android.view.View;  
  11. import android.view.Window;  
  12.    
  13. public class TestHandler extends Activity {  
  14.      protected static final int GUIUPDATEIDENTIFIER = 0x101;  
  15.    
  16.      Thread myRefreshThread = null;  
  17.      BounceView myBounceView = null;  
  18.    
  19.      Handler myHandler = new Handler() {//在主线程中创建Handler对象  
  20.           public void handleMessage(Message msg) {//处理消息  
  21.                switch (msg.what) {  
  22.                     case TestHandler.GUIUPDATEIDENTIFIER://  
  23.                          myBounceView.invalidate();//UI界面更新  
  24.                          break;  
  25.                }  
  26.                super.handleMessage(msg);  
  27.           }  
  28.      };  
  29.    
  30.    
  31.      public void onCreate(Bundle savedInstanceState) {  
  32.    
  33.           super.onCreate(savedInstanceState);  
  34.           this.requestWindowFeature(Window.FEATURE_NO_TITLE);  
  35.           this.myBounceView = new BounceView(this);  
  36.           this.setContentView(this.myBounceView);  
  37.    
  38.           new Thread(new myThread()).start();//创建一个子线程  
  39.    
  40.      }  
  41.    
  42. //线程类,这个线程只是发送消息,然后延时而已。  
  43.    
  44.      class myThread implements Runnable {  
  45.    
  46.           public void run() {  
  47.    
  48.                while (!Thread.currentThread().isInterrupted()) {   
  49.    
  50.                       
  51.    
  52.                     Message message = new Message();  
  53.    
  54.                     message.what = TestHandler.GUIUPDATEIDENTIFIER;  
  55.    
  56.                       
  57.    
  58.                     TestHandler.this.myHandler.sendMessage(message); //发送一次消息,自动调用上面handler类的handleMessage函数,从而更新view类。  
  59.    
  60.                     try {  
  61.    
  62.                          Thread.sleep(100); //延时  
  63.    
  64.                     } catch (InterruptedException e) {  
  65.    
  66.                          Thread.currentThread().interrupt();  
  67.    
  68.                     }  
  69.    
  70.                }  
  71.    
  72.           }  
  73.    
  74.      }  
  75.    
  76. }  
时间: 2024-09-14 13:48:07

如何利用Handler更新android的UI的相关文章

自定义Notification并利用Handler更新Notification

  在消息通知的时候,我们经常用到两个控件Notification和Toast.特别是重要的和需要长时间显示的信息,用Notification最合适不过了.他可以在顶部显示一个图标以标示有了新的通知,当我们拉下通知栏的时候,可以看到详细的通知内容. 最典型的应用就是未看短信和未接来电的显示,还有QQ企鹅,我们一看就知道有一个未接来电或者未看短信,正在挂QQ.同样,我们也可以自定义一个Notification来定义我们自己的程序想要传达的信息. Notification我把他分为两种,一种是默认的

Handler更新UI的几种方法

handler使用Message 1.定义一个Handler 2.重写消息处理函数 3.发送消息 //创建简单的View import android.content.Context;  import android.graphics.Canvas;  import android.graphics.Color;  import android.graphics.Paint;  import android.graphics.Point;  import android.graphics.dra

更新ui-求指点,Handler更新UI线程问题

问题描述 求指点,Handler更新UI线程问题 public Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { // TODO Auto-generated method stub super.handleMessage(msg); switch (msg.what) { case 0x123: one.setImageResource(imageIds[currentIm

Android实现在子线程中更新Activity中UI的方法_Android

本文实例讲述了Android实现在子线程中更新Activity中UI的方法.分享给大家供大家参考,具体如下: 在Android平台下,进行多线程编程时,经常需要在主线程之外的一个单独的线程中进行某些处理,然后更新用户界面显示.但是,在主线线程之外的线程中直接更新页面显示的问题是:系统会报这个异常: ERROR/AndroidRuntime(1222): android.view.ViewRoot$CalledFromWrongThreadException: Only the original

activity-使用 Handler 更新 UI

问题描述 使用 Handler 更新 UI 我实现了一个Android应用程序,,包含四个activity(A,B,C,D) A 调用 B; B调用 C,并且 C调用 D. Activity A 实现了一个Handler Handler handler=new Handler(){ public void handleMessage(Message msg){ Bundle bundle = new Bundle(); bundle = msg.getData(); String key = b

Android实现在子线程中更新Activity中UI的方法

本文实例讲述了Android实现在子线程中更新Activity中UI的方法.分享给大家供大家参考,具体如下: 在Android平台下,进行多线程编程时,经常需要在主线程之外的一个单独的线程中进行某些处理,然后更新用户界面显示.但是,在主线线程之外的线程中直接更新页面显示的问题是:系统会报这个异常: ERROR/AndroidRuntime(1222): android.view.ViewRoot$CalledFromWrongThreadException: Only the original

textview-如何利用广播更新UI界面

问题描述 如何利用广播更新UI界面 我想利用广播给另一个activity中界面的textview重新赋值 请问该怎么做 intent.setClass(context.getApplicationContext() MainActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.getApplicationContext().startActivity(intent); 解决方案 在另一个界面接收广播后直接

android用的handler更新进度条但是显示不出来并且进度条的高不能改总是那么高

问题描述 android用的handler更新进度条但是显示不出来并且进度条的高不能改总是那么高 xml文件 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="fill_parent" android:layo

android中UI主线程与子线程深入分析_Android

本文较为深入的分析了android中UI主线程与子线程.分享给大家供大家参考.具体如下: 在一个Android 程序开始运行的时候,会单独启动一个Process.默认的情况下,所有这个程序中的Activity或者Service(Service和 Activity只是Android提供的Components中的两种,除此之外还有Content Provider和Broadcast Receiver)都会跑在这个Process. 一个Android 程序默认情况下也只有一个Process,但一个Pr