zoukankan      html  css  js  c++  java
  • Android之Handler探索

    Handler背景理解: 

     Handler被最多的使用在了更新UI线程中,但是,这个方法具体是什么样的呢?我在这篇博文中先领着大家认识一下什么是handler以及它是怎么样使用在程序中,起着什么样的作用。

      示例说明:

        首先先建立两个按钮:一个是start按钮,作用是开启整个程序。另一个是终止按钮end,作用是结束整个的程序。这两个按钮的相互对比就会让大家明白Handlerd的基本的工作原理。

    运行结果截图:

    MainActivity.class

    package com.example.testhandler;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.os.Handler;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    
    public class MainActivity extends Activity {
    	
    	private Button start,end;
    
    	//实例化一个handler对象
    	private Handler handler = new Handler();
    	//开启一个新的线程:开启线程有两种方式,一种是使用普通的Thread方法,另一个中是使用Runnable方法
    	Runnable update = new Runnable() {
    		
    		@Override
    		public void run() {
    			System.out.println("update");
    			handler.postDelayed(update, 3000);
    		}
    	};
    	
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_main);
    		start = (Button)this.findViewById(R.id.btn_start);
    		end = (Button)this.findViewById(R.id.btn_end);
    		
    		start.setOnClickListener(new OnClickListener() {
    			
    			@Override
    			public void onClick(View v) {
    				//加入到队列中去执行
    				handler.post(update);
    			}
    		});
    		
    		end.setOnClickListener(new OnClickListener() {
    			
    			@Override
    			public void onClick(View v) {
    				//将消息移除队列中去
    				handler.removeCallbacks(update);
    			}
    		});
    		
    	}
    
    }
    

      当点击Start按钮时的效果图如下:

    当点击end按钮时的效果图如下:

    注意:

      Handler中的post方法并没有开启一个新的线程,他的操作是在主线程中执行的。下面咱们就来验证一下这个观点。

      首先先贴一下运行截图:

      

      等过10s之后的运行结果是:

      

    这里只是测试一下handler的post()方法是否是在主线程中进行的。所以没有布局。

    设计思路:

    在主线程中输出主线程当前的ID和Name,然后使用Runnable方式新建一个线程,在这个新线程中让程序睡眠10s,将这个线程使用Handler的post()方法发送到主线程中,看是否是执行异步加载。也就是验证handler是否是异步加载方式。结论:Handler不是异步加载方式。

    MainActivity:

    package com.example.handlertest1;
    
    import android.os.Bundle;
    import android.os.Handler;
    import android.app.Activity;
    import android.view.Menu;
    
    public class MainActivity extends Activity {
    
    	private Handler mhandler = new Handler();
    	
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		//将多线程发送到消息队列中
    		mhandler.post(r);
    		//不会立刻加载界面,这说明了handler并不是开辟了一个新的线程而是在主线程中进行的。
    		setContentView(R.layout.activity_main);
    		System.out.println("Activity-->"+Thread.currentThread().getId());
    		System.out.println("Activity-->"+Thread.currentThread().getName());
    	}
    
    	Runnable r = new Runnable() {
    		public void run() {
    			System.out.println("Handler--->"+Thread.currentThread().getId());
    			System.out.println("handler--->"+Thread.currentThread().getName());
    			try {
    				Thread.sleep(10000);
    			} catch (Exception e) {
    				e.printStackTrace();
    			}
    		}
    	};
    	
    }
    

    LogCat文件的输出:

     

    在这里通过ID号很明显的看出这不是执行的是多线程加载

    在上面的主线程中重新新建一个线程则实现了多线程的加载:

    将上面的onCreate()中的代码替换为:

    protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            //将多线程发送到消息队列中
    //        mhandler.post(r);
            //不会立刻加载界面,这说明了handler并不是开辟了一个新的线程而是在主线程中进行的。
            setContentView(R.layout.activity_main);
            //这是另外开启了一个新的线程,会发现这里输出的速率会比上次的快很多
            Thread t = new Thread(r);
            t.start();
            System.out.println("Activity-->"+Thread.currentThread().getId());
            System.out.println("Activity-->"+Thread.currentThread().getName());
        }

    效果截图如下:

    LogCat文件中的输出结果截图为:

    在这里通过ID号很明显的看出了这是执行了多线程加载。

      Handler要想开辟一个新的线程需要使用HanderThread()方法。下面就是HandlerThread()的用法:

    设计思路:

      通过使用handler方法传输数据,然后使用HandlerThread,实现了使用Looper来处理消息队列的功能。输出当前的Activity的ID和Name,以及Handler的ID和Name以及传输的数据

    代码如下:

     1 package com.example.handlertest1;
     2 
     3 import android.app.Activity;
     4 import android.os.Bundle;
     5 import android.os.Handler;
     6 import android.os.HandlerThread;
     7 import android.os.Looper;
     8 import android.os.Message;
     9 
    10 public class HandlerTest2 extends Activity{
    11 
    12     @Override
    13     protected void onCreate(Bundle savedInstanceState) {
    14         super.onCreate(savedInstanceState);
    15         setContentView(R.layout.activity_main);
    16         
    17         //打印当前线程的ID和当前线程的名字
    18         System.out.println("Activity-->"+Thread.currentThread().getId());
    19         System.out.println("Activity-->"+Thread.currentThread().getName());
    20         
    21         //HandlerThread是以键值对的形式进行存储的,这里的handler_thread就是该handler的键名
    22         //生成一个HandlerThread对象,实现了使用Looper来处理消息队列的功能。这是有android来提供的并不是java中的Thread提供
    23         HandlerThread handlerthread = new HandlerThread("handler_thread");
    24         handlerthread.start();
    25         MyHandler myhandler = new MyHandler(handlerthread.getLooper());
    26         Message msg = myhandler.obtainMessage();
    27         //传送多的数据的时候使用的setData()方法,使用Bundle()将数据包装
    28         Bundle b = new Bundle();
    29         b.putInt("age", 20);
    30         b.putString("name", "张三");
    31         msg.setData(b);
    32         //将消息发送给目标,目标就是生成该msg对象的handler
    33         msg.sendToTarget();
    34         
    35     }
    36     
    37     class MyHandler extends Handler{
    38         
    39         public MyHandler(){
    40             
    41         }
    42         public MyHandler(Looper looper){
    43             super(looper);
    44         }
    45         
    46         @Override
    47         public void handleMessage(Message msg) {
    48             Bundle b = msg.getData();
    49             int age = b.getInt("age");
    50             String name = b.getString("name");
    51             System.out.println("age is"+age+",name"+name);
    52             System.out.println("Handler--->"+Thread.currentThread().getId());
    53             System.out.println("Handler--->"+Thread.currentThread().getName());
    54             System.out.println("handlermessage");
    55         }
    56         
    57     }
    58     
    59 }

    好了,就这么多了,具体的关于Handler、Looper、Message三者的关系,参考http://blog.csdn.net/lmj623565791/article/details/38377229个人感觉不错

  • 相关阅读:
    【Anagrams】 cpp
    【Count and Say】cpp
    【Roman To Integer】cpp
    【Integer To Roman】cpp
    【Valid Number】cpp
    重构之 实体与引用 逻辑实体 逻辑存在的形式 可引用逻辑实体 不可引用逻辑实体 散弹式修改
    Maven项目聚合 jar包锁定 依赖传递 私服
    Oracle学习2 视图 索引 sql编程 游标 存储过程 存储函数 触发器
    mysql案例~tcpdump的使用
    tidb架构~本地化安装
  • 原文地址:https://www.cnblogs.com/bingbingliang-xiaomonv/p/5462685.html
Copyright © 2011-2022 走看看