Handler的使用(二)

一、Handler与线程

    Handler在默认情况下,实际上它和调用它的Activity处于同一个线程。

    例如在Handler的使用(一)示例1当中,虽然声明了线程对象,但是在实际调用当中它并没有调用线程的start()方法,而是直接调用当前线程的run()方法。

    示例1:在Activity中创建Handler和线程对象,并且在Activity的onCreate方法中输出当前线程的Id和Name,然后在线程对象的run方法中也输出当前线程的Id和Name。如果结果一致,表示他们处于同一个线程。

public class HandlerActivity extends Activity{
  private Handler handler = new Handler();
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    //在设置布局文件之前先调用post方法,表示在执行完主线程之后才会显示布局文件的内容,而线程中又设置了休眠3秒,所以最终表示先显示应用程序主界面,等待3秒之后才显示布局文件中的内容
    handler.post(r);
   System.out.println("activityId ---> " + Thread.currentThread().getId());
   System.out.println("activityName ---> " + Thread.currentThread().getName());
 }
 
  Runnable r = new Runnable() {
   @Override
   public void run() {
     //如果这里输出的当前现场的Id和Name与上面onCreate方法中输出的Id、Name相同,表示他们使用同一个线程
      System.out.println("handlerId ---> " + Thread.currentThread().getId());
     System.out.println("handlerName ---> " + Thread.currentThread().getName());
     try {
      Thread.sleep(3000);//让线程休眠3秒
     } catch (InterruptedException e) {
      e.printStackTrace();
     }
   }
 };
}

根据测试证明,他们使用的是同一个线程。

activityId ---> 1

activityName ---> main

handlerId ---> 1

handlerName ---> main

如果,将onCreate中的代码改正如下,又会发生不同的结果

  //andler.post(r);
  Thread t = new Thread();
  t.start();

activityId ---> 1

activityName ---> main

handlerId ---> 8

handlerName ---> Thread-8

 

二、Bundle的用法

    Bundle是一个只能以String类型为键,以Object类型为值的mapping,相当于把数据当成一个包。在初学阶段可以把它当作是一个特殊的HashMap对象。Bundle就是数据存储的方式。

    下面通过一个示例说明Bundler如何在新线程中处理消息。要启用一个新的线程就要用到Logger对象,Logger是循环从消息队列中收取消息,如果在线程中使用Logger,那么Logger就会不停的收取消息,当队列中没有消息了,那么线程就会进入休眠状态。

    示例2:一个Android应用程序,先打印Activity当前使用的线程信息,然后再创建一个新线程,使用Bundle存储值,最后打印出Bundle中存储的值和线程的信息。

public class BundlerTest extends Activity{
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    System.out.println("activityName ---> " + Thread.currentThread().getName());
    //Looper对象很少去创建,因为Android的框架当中提供了HandlerThread类,提供了循环处理消息的功能
    //生成一个handlerThead对象,实现了使用Looper来处理消息队列的功能,这个类由Android应用程序框架提供
    HandlerThread handlerThead = new HandlerThread("headler_thread");//新线程的名称
    //在使用handlerThead.getLooper()方法之前,必须执行start,否则返回null
    handlerThead.start();
    MyHandler myHandler = new MyHandler(handlerThead.getLooper());
    Message msg = myHandler.obtainMessage();
    //sendToTarget表示发送到目标,目标就是由哪一个Handler获得的消息,就发送给哪一个Handler,也就会调用Handler的handleMessage方法
    msg.sendToTarget();
 }
 
  class MyHandler extends Handler{
   public MyHandler() {

   }
   //带有looper参数的构造函数,表示当前的Handler使用Looper所在的线程处理消息队列
   //把这个Handler(myHandler)绑定在另一个线程上,从消息队列中取消息
   public MyHandler(Looper looper){
     super(looper);
   } 
   
  @Override
  public void handleMessage(Message msg) {
     System.out.println("handlerName ---> " + Thread.currentThread().getName());
   }
  }
}

上面的程序公有两个线程,一个是Activity(ActivityName ---> "main"),另一个是HandlerThread(ThreadName ---> "handler-thread") 

三、在新线程当中处理消息的方法

    1、在msg中可以使用arg1、arg2传递数据

    2、可以使用msg.obj传递简单数据

       如:msg.obj = "abc";

   取值:String s = (String) msg.obj; 
   3、使用Bundle传递大量数据

       如:Bundle b = new Bundle();
               b.putString("name", "zhangsan");
               b.putInt("age", 12);
               msg.setData(b);
    取值:Bundle b = msg.getData();
                int age = b.getInt("age");
                String name = b.getString("name");

在Kotlin中,使用Handler调用另一个Handler有两种方法: 方法1:使用post方法 您可以使用post方法将Runnable对象发送到目标Handler的消息队列中,以便在稍后的时间执行。这可以通过以下方式完成: ```kotlin val handler1 = Handler(Looper.getMainLooper()) // 创建第一个Handler val handler2 = Handler() // 创建第Handler handler1.post(object : Runnable { override fun run() { // 在第一个Handler线程中执行 handler2.post(object : Runnable { override fun run() { // 在第Handler线程中执行 } }) } }) ``` 在这个例子中,我们创建了两个Handler。在第一个Handler的线程中,我们使用post方法将一个Runnable对象发送到第Handler的消息队列中,以便在稍后的时间执行。 方法2:使用sendMessage方法 您还可以使用sendMessage方法将Message对象发送到目标Handler的消息队列中,以便在稍后的时间执行。这可以通过以下方式完成: ```kotlin val handler1 = Handler(Looper.getMainLooper()) // 创建第一个Handler val handler2 = Handler() // 创建第Handler handler1.sendMessage(Message.obtain(handler2, object : Runnable { override fun run() { // 在第Handler线程中执行 } })) ``` 在这个例子中,我们创建了两个Handler。在第一个Handler的线程中,我们使用sendMessage方法将一个Message对象发送到第Handler的消息队列中,以便在稍后的时间执行。 请注意,这两种方法都可以在Kotlin中使用。您可以根据自己的需要选择其中一种方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值