Handler记录

package com.example.handler;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MainActivity extends Activity {
	
	private mHandler Handler1;
	private Button btn1;
	private Button btn2;
	private mHandler1 myHandler;
	private looperHandler loopHandler1;
	Thread t;
	
	//private Handler myHandler = new Handler();
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		btn1 = (Button)findViewById(R.id.btn1);
		btn2 = (Button)findViewById(R.id.btn2);
		
		//一个线程只有一个Looper,但是可以有多个handler对象,每个handler对象只对应一个线程
		//这里在一个线程里面创建了2个handler,handler将消息都放入了该线程的Looper中。
		//Looper提供的是一个消息循环机制,而handler的作用是对消息进行处理,包括发送消息、处理
		//handler发送的对象有2个:1.runnable对象,2.message对象,同时对应了runnable线程队列和消息队列
		//handler的使用方法答题分3步:
		//1.创建handler对象
		//2.创建runnable和message
		//3.调用post或者sendmessage方法将对象添加到Looper队列中
		Handler1 = new mHandler();
		myHandler = new mHandler1();
		//通过创建一个HandlerThread线程可以实现向这个线程的消息队列发送消息
		//1.创建一个 handlerthread
		//2.启动这个线程
		//3.用线程的getlooper参数去实例handler对象
		HandlerThread looper = new HandlerThread("handler_thread");
		looper.start();
		//这里创建的handler对象是绑定在新线程里面的,这里设置looper对象要使用线程的looper,
		//如果使用getmainloop获取的主线程的looper,那这个handler处理的是主线程looper里面的
		//消息
		loopHandler1 = new looperHandler(looper.getLooper());
	
		//按键将一个runnable对象放入队列中,当runnable发送到队列后,会立即返回,
		//不会管是否被执行、成功等。而具体执行是等到队列排到这个runnable对象后,
		//由系统拿来执行。
		btn1.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				//这里直接将runnable对象放入线程队列中,但是并没有创建新的线程,仍然是在创建
				//runnable对象的线程中。
				//myHandler.post(mrunnable);
				//标准的新线程启动方法,可以看到打印的线程ID已经改变
				t = new Thread(mrunnable);
				t.start();			
				sendmsg();
				System.out.println("start---->");
			}

			
		});
		btn2.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				myHandler.removeCallbacks(mrunnable);
				try {
					t.stop();
				} catch (Exception e) {
					// TODO: handle exception
				}
				
				System.out.println("stop---->");
			}
		});
		System.out.println("MainActivity threadid------->"+Thread.currentThread().getId());

	}
	
	private void sendmsg() {
		// TODO Auto-generated method stub
		Message msg = new Message();
		Bundle b = new Bundle();
		b.putString("sendMsg", "test send msg to child thread!!");
		msg.setData(b);
		loopHandler1.sendMessage(msg);
	}
	
	//这个类用来实例handler对象
	static class looperHandler extends Handler{
		URL url;
		URLConnection conn = null;
		InputStream is = null;
		InputStreamReader isr = null;
		BufferedReader br = null;
		
		@Override
		public void handleMessage(Message msg) {
			// TODO Auto-generated method stub
			super.handleMessage(msg);
			Bundle b= msg.getData();
			String str = b.getString("sendMsg");
			System.out.println("looperHandler get from mainthread---->"+str);
			//打印可以看出,这里是个新线程,可以直接在这里处理一些耗时操作
			System.out.println("looperHandler threadid---->"+Thread.currentThread().getId());
			//使用网络操作测试是否是在新线程里
			try {
				url = new URL("http://iframe.ip138.com/ic.asp");
				conn = url.openConnection();
				is = conn.getInputStream();
				isr = new InputStreamReader(is,"gb2312");
				br = new BufferedReader(isr);
				String input = "";
				while ((input = br.readLine()) != null) {
					str += input;
				}

			} catch (Exception e) {
				e.printStackTrace();
			}
			
		}
		

		public looperHandler() {
            super();
        }
        
        /* 这个构造方法必须有 ,通过实例handler对象中的getlooper参数去获取
         * 新的线程的Looper
         */
        public looperHandler(Looper looper) {
            super(looper);
        }
        
        
	}
	
	static class mHandler1 extends Handler{
		@Override
		public void handleMessage(Message msg) {
			// TODO Auto-generated method stub 
			super.handleMessage(msg);
			//Message.obtain();
			Bundle b= msg.getData();
			String str = b.getString("runnable1");
			String str2 = b.getString("sendMsg");
			System.out.println("Handler1 get from runnable---->"+str);
			System.out.println("Handler1 get from sendMsg---->"+str2);
		}
	}
	
	static class mHandler extends Handler
	{

		public mHandler(){} 
		public mHandler(Looper looper){ 
			super(looper); 
		}
		@Override
		public void handleMessage(Message msg) {
			// TODO Auto-generated method stub
			super.handleMessage(msg);
			Message.obtain();
			Bundle b = msg.getData();
			String string = b.getString("sendMsg");
			String string2 = b.getString("runnable1");
			System.out.println("mHandler threadid---->"+Thread.currentThread().getId());
			System.out.println("handleMessage get from sendMsg---->"+string);
			System.out.println("handleMessage get from runnable---->"+string2);
			
		}
		
	}
	

	private void sendMessage() {
		// TODO Auto-generated method stub
		Message msg = new Message();
		Bundle b = new Bundle();
		b.putString("sendMsg", "sendMsg");
		msg.setData(b);
		Handler1.sendMessage(msg);
	}
	
	private Runnable mrunnable = new Runnable() {
	
		@Override
		public void run() {
			// TODO Auto-generated method stub
			//每个handler在发送消息时都需要自己单独的message对象
			//这里如果共用一个,回导致应用无法响应。
			/*
			Message msg = new Message();
			Message msg1 = new Message();
			Bundle b = new Bundle();
			Bundle b1 = new Bundle();
			b.putString("runnable1", "runnable1");
			b1.putString("runnable1", "runnable1");
			b.putString("sendMsg", "sendMsg");
			b1.putString("sendMsg", "sendMsg");
			msg.setData(b);
			msg1.setData(b1);
			myHandler.sendMessage(msg);
			Handler1.sendMessage(msg1);
			*/
			//sendMessage();
			//当runnable对象排队到它时,会执行run方法,执行完毕后消息会废弃,
			//如果需要重复发送,必须重新将runnable对象放入队列中
			//可以看到,如果去掉下面一行代码,那么runnable对象只会执行一次。
			//myHandler.postDelayed(mrunnable, 3000);
			System.out.println("runnable1 threadid------->"+Thread.currentThread().getId());
			
				try {
					//这里是从线程发出消息,如果要实现循环,需要使用外套while,然后使线程定时睡眠
					//这样它是运行在新线程当中
					Thread.currentThread();
					Thread.sleep(3000);
					Message msg = new Message();
					Message msg1 = new Message();
					Bundle b = new Bundle();
					Bundle b1 = new Bundle();
					b.putString("runnable1", "runnable1");
					b1.putString("runnable1", "runnable1");
					b.putString("sendMsg", "sendMsg");
					b1.putString("sendMsg", "sendMsg");
					msg.setData(b);
					msg1.setData(b1);
					myHandler.sendMessage(msg);
					Handler1.sendMessage(msg1);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				//这里如果使用post,会将这个runnable对象放入到主线程的looper中
				//通过每次定时放入来实现循环发出消息,他是运行在主线程里面
				myHandler.postDelayed(mrunnable, 3000);
		}

		
	};

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {

		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// Handle action bar item clicks here. The action bar will
		// automatically handle clicks on the Home/Up button, so long
		// as you specify a parent activity in AndroidManifest.xml.
		int id = item.getItemId();
		if (id == R.id.action_settings) {
			return true;
		}
		return super.onOptionsItemSelected(item);
	}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值