• Handler问题


    •使用Handler是异步的,它会建立新线程么?

    •Handler是在主线程内么?

    Handler的post和sentMessage方法,使用的是一个队列还是两个?

      是一个队列,post是线程队列,sentMessage是消息队列

    •子线程中建立一个handler,然后sendMessage会怎样?

    子线程建立handler,构造的时候传入主线程的,Looper

    •Handler是做什么的,既然是异步任务处理,他本身是多线程的么?

    Handler作用
    1)执行计划任务,你可以再预定的实现执行某些任务,可以模拟定时器
    2)线程间通信。在Android的应用启动时,会创建一个主线程,主线程会创建一个消息队列来处理各种消息。 当你创建子线程时,你可以在你的子线程中拿到父线程中创建的Handler对象,就可以通过向父线程的消息队列发送消息了。 由于Android要求在UI线程中更新界面,因此,可以通过该方法在其他线程中更新界面。

    一、角色描述

    2.Handle、 Looper 、Message Queue和线程之间的关系

    1).Looper(相当于隧道)一个线程可以产生一个Looper对象,由它来管理此线程里的Message Queue(车队、消息隧道).

      •当前线程中有一个Looper这样的循环在监听消息队列,但又不是额外的线程,这不是和我们的学习常理相勃吗?

    Looper没有新开一个线程,Looper又系统来控制的循环。

    2).Handler 你可以构造Handler对象来与Looper沟通,以便push新消息到Message Queue里;或者接收Looper(从Message Queue取出)所送来的消息.

    3).Message Queue(消息队列): 用来存放线程放入的消息。

     4).线程: UI thread 通常就是main thread, 而Android启动程序时会替它建立一个Message Queue.

    每一个线程里可含有一个Looper对象以及一个MessageQueue数据结构。在你的应用程序里,可以定义Handler的子类别来接收Looper所送出的消息。

    见下面两张图,你将明白Handler作用,.Message Queue,.Looper

    3.主线程里面定义两个不同的handler实例,其中一个handler发出的消息另外一个能接收到吗?

        不能,虽然主线程共享同一个消息队列,但是它们通过message的what变量来区分到底是由哪一个handler发出的消息。Handler实例与消息处理是关联的,发送和接收要匹配

    mainHandler2 = new Handler(){
    
    			@Override
    			public void handleMessage(Message msg) {
    				// TODO Auto-generated method stub
    				super.handleMessage(msg);//这里接收不到
    				Toast.makeText(HandlerConceptActivity.this, "[Main Thread]Handler2 Get the message: "+msg.getData().getString(HANDLER_KEY), 5000).show()  ;
    			}
    			
    		} ;
    		mainHandler1 = new Handler(){
    
    			@Override
    			public void handleMessage(Message msg) {
    				// TODO Auto-generated method stub
    				super.handleMessage(msg);//这里能接收到
    				Toast.makeText(HandlerConceptActivity.this, "[Main Thread]Handler1 Get the message: "+msg.getData().getString(HANDLER_KEY), 5000).show()  ;
    			}
    			
    		} ;
    
    		//Handler Lab1
    		findViewById(R.id.buttonHandlerLab1).setOnClickListener(new OnClickListener(){
    
    			@Override
    			public void onClick(View v) {
    				// TODO Auto-generated method stub
    				new Thread(new Runnable(){
    
    					@Override
    					public void run() {
    						// TODO Auto-generated method stub
    						
    						mainHandler1.sendMessage(defineNewMessage("Lab1")) ;
    						//try to use mainHanlder2 to send meesage and receive . 
    						//mainHandler2.sendMessage(defineNewMessage("Lab1")) ;
    						
    					}
    					
    				}).start() ;
    			}
    			
    		}) ;
    
    4.任何一个线程都有消息队列吗
         默认只有主线程才有消息队列,自己新建的普通线程是没有线程队列的。不过子线程中用HandlerThread,默认有消息队列
      1)//下面代码会抛出Can't create handler inside thread that has not called Looper.prepare()异常
                findViewById(R.id.buttonHandlerLab2).setOnClickListener(new OnClickListener(){
    
    			@Override
    			public void onClick(View v) {
    				// TODO Auto-generated method stub
    				new Thread(new Runnable(){
    
    					@Override
    					public void run() {
    						Handler lab2Handler = new Handler()  ;
    						lab2Handler.sendMessage(defineNewMessage("Lab2")) ;
                                                  
    					}
    					
    				}).start() ;
    			}
    		}) ;
    
    
    
    2)下面的代码是正确的
           class SubHandlerThread extends HandlerThread{
    
    		public SubHandlerThread(String name) {
    			super(name);
    			// TODO Auto-generated constructor stub
    		}
    
    		@Override
    		public void run() {
    			// TODO Auto-generated method stub
    			ProcessCaculate() ;
    			Looper lp = this.getLooper() ;
    
    			new Handler(lp){
    				
    				@Override
    				public void handleMessage(Message msg) {
    					// TODO Auto-generated method stub
    					super.handleMessage(msg);
    					Log.i(CommonConstants.LOGCAT_TAG_NAME, "Get the message by HandlerThread "+ msg.getData().getString(HANDLER_KEY))  ;
    				}
    	        	
    	        }.sendMessage(defineNewMessage("Lab2.2"))  ;
    		}
    		
    	}






    findViewById(R.id.buttonHandlerLab3).setOnClickListener(new OnClickListener(){@Overridepublic void onClick(View v) {// TODO Auto-generated method stub//using HandlerThread to make handler (message queue) ,send messageSubHandlerThread subHandlerThread = new SubHandlerThread("threadone"); subHandlerThread.start();}}) ;



    5.子线程的handler可以使用主线程的消息队列吗
    可以的。
    //Handler Lab3.1 child thread get main thread's looper and send message .
    		findViewById(R.id.buttonHandlerLab4).setOnClickListener(new OnClickListener(){
    
    			@Override
    			public void onClick(View v) {
    				// TODO Auto-generated method stub
    				new Thread(new Runnable(){
    					
    					@Override
    					public void run() {
    						// TODO Auto-generated method stub
    						Handler lab3Handler  ;
    						lab3Handler = new Handler(Looper.getMainLooper())
    						{
    
    							@Override
    							public void handleMessage(Message msg) {
    								// TODO Auto-generated method stub
    								super.handleMessage(msg);
    								Log.i(CommonConstants.LOGCAT_TAG_NAME, "Get the message: "+msg.getData().getString(HANDLER_KEY)+" by Child Thread Handler")  ;
    							}
    							
    						};
    						lab3Handler.sendMessage(defineNewMessage("Lab3")) ;
    						
    					}
    					
    				}).start() ;
    			}
    			
    		}) ;
    5.子线程的handler可以使用子线程的消息队列吗
    //Handler Lab3.2 using looper.prepare() and looper.loop()  .
    		findViewById(R.id.buttonHandlerLab5).setOnClickListener(new OnClickListener(){
    
    			@Override
    			public void onClick(View v) {
    				// TODO Auto-generated method stub
    				new Thread(new Runnable(){
    					
    					@Override
    					public void run() {
    						Looper.prepare();//实例化looper对象,生成消息队列
    						lab3Handler = new Handler(){
    
    							@Override
    							public void handleMessage(Message msg) {
    								// TODO Auto-generated method stub
    								super.handleMessage(msg);
    								Log.i(CommonConstants.LOGCAT_TAG_NAME, "Get the message from "+msg.getData().getString(HANDLER_KEY)+" by Child Thread Handler")  ;
    							}
    						} ;
    						
    						lab3Handler.sendMessage(defineNewMessage("Lab3")) ;
    						Looper.loop() ;//循环消息队列
    					}
    					
    				}).start() ;
    			}
    			
    		}) ;
     

    总结:
    1.Handler实例与消息处理是关联的,发送和接收要匹配。
    2.Handler操作队列,主要是在子线程操作主线程消息队列
    3.子线程默认是没有消息队列的
  • 相关阅读:
    iOS开发基础知识--碎片7
    python---ORM之SQLAlchemy(3)外键与relationship的关系
    python---ORM之SQLAlchemy(2)外键使用
    python---ORM之SQLAlchemy(1)
    python---自定义字段验证
    mysql -- 慢日志使用
    mysql -- 索引补充
    mysql -- 动态获取结果集(重点)
    mysql -- 逻辑语句
    mysql -- 事务
  • 原文地址:https://www.cnblogs.com/firecode/p/2460867.html
Copyright © 2020-2023  润新知