现在的位置: 首页 > 综合 > 正文

android: Handler概念理解与运用

2018年07月16日 ⁄ 综合 ⁄ 共 5988字 ⁄ 字号 评论关闭

转自:http://blog.csdn.net/csf928437197/article/details/6632930

android.os.Handler是Android SDK中处理定时操作的核心类。通过Handler类,可以提交和处理一个Runnable对象。这个对象的run 方法可以立刻执行,也可以在指定时间之后执行(可以称为预约执行)。
        handler类允许你发送消息和处理线程消息队列中的消息及runnable对象。handler实例都是与一个线程和该线程的消息队列一起使用,一旦创建了一个新的handler实例,系统就把该实例与一个线程和该线程的消息队列捆绑起来,这将可以发送消息和runnable对象给该消息队列,并在消息队列出口处处理它们。
          handler类有两种主要用途:
               1、按照时间计划,在未来某时刻,对处理一个消息或执行某个runnable实例。
               2、把一个对另外线程对象的操作请求放入消息队列中,从而避免线程间冲突。 
        时间类消息通过如下方法使用:
                post(Runnable)
                postAtTime(Runnable, long)
                postDelayed(Runnable, long)
               sendEmptyMessage(int)
               sendMessage(Message)
               sendMessageAtTime(Message, long)
               andsendMessageDelayed(Message, long)
         methods. post之类函数可以传输一个runnable对象给消息队列,并在到达消息队列后被调用。sendmessage之类函数可以传送一个包含数据的message对象,该message对象可以被Handler类的handleMessage(Message) 方法所处理。 
          post之类函数和sendmessage之类的函数都可以指定消息的执行时机,是立即执行、稍后一段时间执行,还是在某个确定时刻执行。这可以用来实现超时、消息或其他时间相关的操作。
         当一个进程启动时,主线程独立执行一个消息队列,该队列管理着应用顶层的对象(如:activities、broadcast receivers等等)和所有创建的窗口。你可以创建自己的一个线程,并通过handler来与主线程进行通信。这可以通过在新的线程中调用主线程的handler的post和sendmessage操作来实现。          
          Handler类主要可以使用如下3个方法来设置执行Runnable对象的时间:

[plain] view
plain
copy

  1. //立即执行Runnable对象  
  2. public final boolean post(Runnable r);  
  3. //在指定时间uptimeMillis 后执行Runnable对象  
  4. public final boolean postAtTime(Runnable r,long uptimeMillis);  
  5. //在指定的时间间隔delayMillis 执行Runnable对象  
  6. public final boolean postDelayed(Runnable r,long delayMillis);  

        从上面的三个方法可以看出,第一个参数的类型都是Runnable ,因此,在调用这三个方法之前,需要有一个实现Runnable接口的类,Runnable接口的代码如下:

[html] view
plain
copy

  1. public interface Runnable  
  2. {  
  3.      public voic run();//线程要执行的方法  
  4. }  

        在Runnable接口中只有一个Run 方法,该方法为线程执行方法。

[plain] view
plain
copy

  1. Handler handler = new Handler();  
  2. handler.postDelayed(This,5000);  

         如果想在5秒内停止记时可以用如下代码:        

[html] view
plain
copy

  1. handler.removeCallbacks(this);  

         除此之外还可以用postAtTime方法指定未来的某一个精确时间来执行Runnable对象,代码如下:

[html] view
plain
copy

  1. Handler handler=new Handler();  
  2. handler.postAtTime(new RunToast(this){  },android.os.SystemClock.uptimeMillis()+15*1000);//在15秒后执行Runnable对象  

        其中RunToast是一个实现Runnable的接口的类,代码如下:

[html] view
plain
copy

  1. class RunToast implements Runnable  
  2. {  
  3.     private Context context;  
  4.     public RunaToast(Context context)  
  5.     {  
  6.          this.context;  
  7.     }  
  8.     @Override  
  9.     public void run()  
  10.     {  
  11.          Toast.makeText(context,"15秒后显示Toast提示信息",Toast.LENGTH_LONG).show();  
  12.     }   
  13. }  

       postAtTime的第二个参数表示一个精确的时间的毫秒数,如果从当前时间算起,需要使用android.os.SystemClock.uptimeMillis()获得基准时间。
        要注意的是,不管使用哪个方法来执行Runnable对,都只能运行一次。如果想循环执行,必须在执行完后再次调用post、postAtTime或postDelayed方法。
例如,在Run方法中再次调用postDelayed方法,代码如下:

[html] view
plain
copy

  1. public void run()  
  2. {  
  3.     tvCount.setText("Count:" + String.valueOf(++count));  
  4.     //现次调用postDelayed方法,5秒后run方法仍被调用,然后再一次同用postDelayed方法,这样就行成了循环调用  
  5.     handler.postDelayed(this, 5000);  
  6. }  

下面是一个运用实例:
完整代码如下:csf.java

[plain] view
plain
copy

  1. package csf.handler;  
  2.   
  3. import android.app.Activity;  
  4. import android.content.Context;  
  5. import android.os.Bundle;  
  6. import android.os.Handler;  
  7. import android.view.View;  
  8. import android.view.View.OnClickListener;  
  9. import android.widget.Button;  
  10. import android.widget.TextView;  
  11. import android.widget.Toast;  
  12.   
  13. public class csf extends Activity implements OnClickListener, Runnable  
  14. {  
  15.     private Handler handler;  
  16.     private TextView tvCount;  
  17.     private int count = 0;  
  18.   
  19.     class RunToast implements Runnable  
  20.     {  
  21.         private Context context;  
  22.   
  23.         public RunToast(Context context)  
  24.         {  
  25.             this.context = context;  
  26.         }  
  27.         @Override  
  28.         public void run()  
  29.         {  
  30.             Toast.makeText(context, "15秒后显示Toast提示信息", Toast.LENGTH_LONG)  
  31.                     .show();  
  32.         }  
  33.     }  
  34.     @Override  
  35.     public void onClick(View view)  
  36.     {  
  37.         switch (view.getId())  
  38.         {  
  39.             case R.id.btnStart:  
  40.                 handler.postDelayed(this, 5000);  
  41.                 break;  
  42.             case R.id.btnStop:  
  43.                 handler.removeCallbacks(this);  
  44.                 break;  
  45.             case R.id.btnShowToast:  
  46.                 handler.postAtTime(new RunToast(this)  
  47.                 {  
  48.                 }, android.os.SystemClock.uptimeMillis() + 15 * 1000);  
  49.                 break;  
  50.         }  
  51.     }  
  52.     @Override  
  53.     public void run()  
  54.     {  
  55.         tvCount.setText("Count:" + String.valueOf(++count));  
  56.         handler.postDelayed(this, 5000);  
  57.     }  
  58.     @Override  
  59.     public void onCreate(Bundle savedInstanceState)  
  60.     {  
  61.         super.onCreate(savedInstanceState);  
  62.         setContentView(R.layout.main);  
  63.         Button btnStart = (Button) findViewById(R.id.btnStart);  
  64.         Button btnStop = (Button) findViewById(R.id.btnStop);  
  65.         Button btnShowToast = (Button) findViewById(R.id.btnShowToast);  
  66.         tvCount = (TextView) findViewById(R.id.tvCount);  
  67.         btnStart.setOnClickListener(this);  
  68.         btnStop.setOnClickListener(this);  
  69.         btnShowToast.setOnClickListener(this);  
  70.         handler = new Handler();  
  71.     }  
  72. }  

布局文件代码如下:main.xml

[html] view
plain
copy

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout   
  3.     xmlns:android="http://schemas.android.com/apk/res/android"  
  4.     android:orientation="vertical"   
  5.     android:layout_width="fill_parent"  
  6.     android:layout_height="fill_parent">  
  7.     <TextView   
  8.     android:id="@+id/tvCount"   
  9.     android:layout_width="fill_parent"  
  10.     android:layout_height="wrap_content"   
  11.     android:textSize="20dp" />  
  12.     <Button   
  13.     android:id="@+id/btnStart"   
  14.     android:layout_width="fill_parent"  
  15.     android:layout_height="wrap_content" android:text="开始计数" />  
  16.     <Button   
  17.     android:id="@+id/btnStop"   
  18.     android:layout_width="fill_parent"  
  19.     android:layout_height="wrap_content"   
  20.     android:text="停止计数" />  
  21.     <Button   
  22.     android:id="@+id/btnShowToast"   
  23.     android:layout_width="fill_parent"  
  24.     android:layout_height="wrap_content"   
  25.     android:text="15秒后显示Toast信息框" />  
  26. </LinearLayout>  

               运行后,单击   [开始计数]  按钮,5秒后,会在按钮上方显示计数信息。然后单击   [15秒后显示Toast信息框]   按钮,过15秒后,会显示一个Toast信息框。

抱歉!评论已关闭.