浅析android中handler与Message(二)+源码查看器

handler与message


关于handler,上节已经说明了它的由来.点击打开链接

这节主要说,它的用法,,以及配合message使用.

通常:handler要依附于某个线程,主线程或子线程,一般是在哪里创建,依附于哪里.

handler ,在创建它的时候,通常,要复写public void handleMessage(Message msg)方法,以此来处理由子线程传递过来的信息.

这样,我们就有必要先说Message了,

Message有几个属性字段:
arg0,arg1,what,object,replyTo,等
arg0 ,arg1 是整型数值,what通常是状态码,object是对象,replyTo是message依附于哪个handler.

具体见官方APIAPI




通常的Message需要自己创建,但是呢,在用到handler的时候,我们可以用:
public final Message obtainMessage ()
创建,当然,他还有其他的带参数的创建的方式.
public final Message obtainMessage (int what)
public final Message obtainMessage (int what, Object obj)
public final Message obtainMessage (int what, int arg1, int arg2, Object obj)



handler对象有几个方法,如下

public final boolean sendEmptyMessage (int what)

Sends a Message containing only the what value.

Returns
  • Returns true if the message was successfully placed in to the message queue. Returns false on failure, usually because the looper processing the message queue is exiting.
这个是发送信息.,带一个自定义的code(what)

public final boolean sendMessage (Message msg)
Added in  API level 1

Pushes a message onto the end of the message queue after all pending messages before the current time. It will be received in handleMessage(Message), in the thread attached to this handler.

Returns
  • Returns true if the message was successfully placed in to the message queue. Returns false on failure, usually because the looper processing the message queue is exiting.
推送了一个message到消息队列尾部,将会在handleMessage(Message msg )中接收.
消息成功推送到消息队列的时候 返回值为true.
public final boolean sendMessageAtFrontOfQueue (Message msg)
这个是放在队列头部的.

public final boolean post (Runnable r)
这个提交了一个Runable对象


关于handler的就这么多了


下面看Message 点击打开链接
主要的方法.
在这里,我主要用到了setData的方法与getData
他们通常是带有一个Bundle

当然还有pickData与上面的类似


Public Methods
void copyFrom( Message o)
Make this message like o.
int describeContents()
Describe the kinds of special objects contained in this Parcelable's marshalled representation.
Runnable getCallback()
Retrieve callback object that will execute when this message is handled.
Bundle getData()
Obtains a Bundle of arbitrary data associated with this event, lazily creating it if necessary.
Handler getTarget()
Retrieve the a  Handler implementation that will receive this message.
long getWhen()
Return the targeted delivery time of this message, in milliseconds.
static  Message obtain( Handler h, int what, int arg1, int arg2,  Object obj)
Same as  obtain(), but sets the values of the  targetwhatarg1arg2, and  obj members.
static  Message obtain( Handler h, int what,  Object obj)
Same as  obtain(), but sets the values of the  targetwhat, and  obj members.
static  Message obtain( Handler h, int what)
Same as  obtain(), but sets the values for both  target and  what members on the Message.
static  Message obtain( Handler h)
Same as  obtain(), but sets the value for the  target member on the Message returned.
static  Message obtain( Handler h,  Runnable callback)
Same as  obtain(Handler), but assigns a callback Runnable on the Message that is returned.
static  Message obtain()
Return a new Message instance from the global pool.
static  Message obtain( Handler h, int what, int arg1, int arg2)
Same as  obtain(), but sets the values of the  targetwhatarg1, and  arg2 members.
static  Message obtain( Message orig)
Same as  obtain(), but copies the values of an existing message (including its target) into the new one.
Bundle peekData()
Like getData(), but does not lazily create the Bundle.
void recycle()
Return a Message instance to the global pool.
void sendToTarget()
Sends this Message to the Handler specified by  getTarget().
void setData(Bundle data)
Sets a Bundle of arbitrary data values.
void setTarget( Handler target)
String toString()
Returns a string containing a concise, human-readable description of this object.
void writeToParcel( Parcel dest, int flags)
Flatten this object in to a Parcel.

"废话"了那么多,看下代码吧

因为在android中,主线程不安全,所以要再开启一个线程.
这里,我是写了一个实现Runable接口的线程类.,你也可以直接new Thread(),复写run方法.

线程类:java
   	class MyThread implements Runnable{
    		String s = null;
			@Override
			public void run() {
				// TODO Auto-generated method stub
				try {
					s = MainActivity.getSourceCodeString(url);<span style="white-space:pre">	</span>这个是获取网页源码的.
				} catch (MalformedURLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				Message message = new Message();	//可以用obtainMessage获得
				Bundle bundle = new Bundle();
				if(s!=null)
				{
					message.what = 0x111;
					bundle.putString("html", s);	//添加数据到Bundle
					message.setData(bundle);		//设置数据包
				}
				else {
					message.what = 0x110;	//设置状态码
					return;
				}
				MainActivity.this.mHandler.sendMessage(message);
			}
    	}

获取源码方法:

    public static String getSourceCodeString(URL url) throws MalformedURLException{
    	
    	String s =null;
    	try {
			HttpURLConnection connection = (HttpURLConnection) url.openConnection();
			//获得连接
			connection.setConnectTimeout(5000);		//设置超时
			connection.setRequestMethod("GET");	//此处需要大写
//			connection.setDoOutput(true);
			connection.setRequestProperty("Charset", "UTF8");
			if(connection.getResponseCode()==200)
			{
				InputStream inputStream = connection.getInputStream();
				//通过连接获取输入流.
				byte[] data = Transcation.readByte(inputStream);
				//将输入流通过转换为输出流,进而,通过输出流,将数据转换为字节数组.
				s = new String(data,"GBK");
				//构造字符串.
				return s ;
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			Log.i("TAG", "连接异常-----------");
			e.printStackTrace();
		}
    	return s;
    }

流转换类:
Transcation.readByte(inputStream)


package cn.hpu.tools;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

import android.util.Log;

public class Transcation {
	
	public static byte[] readByte(InputStream inputStream) throws IOException
	{
		ByteArrayOutputStream outputStream = new ByteArrayOutputStream();//字节数组输出流
		
		byte[] buffer = new byte[2048];//缓存数组
		
		int len=-1;
		try {
			while((len=inputStream.read(buffer))!=-1)
			{
				outputStream.write(buffer, 0, len);
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			Log.i("TAG", "流读取或写入异常");
			e.printStackTrace();
		}
		inputStream.close();	//关闭流
		
		return outputStream.toByteArray();
	}
}

MainActivity.java

public class MainActivity extends Activity {
	
	EditText mEditText;
	Button mButton;
	static URL url=null;
	Handler mHandler;
	TextView mTextView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_main);
        
        mButton = (Button)findViewById(R.id.get_button);
        mEditText =(EditText)findViewById(R.id.path_text);
        mTextView = (TextView)findViewById(R.id.text);<span style="white-space:pre">			</span>//获取各个控件
        mTextView.setMovementMethod(ScrollingMovementMethod.getInstance());//设置滑动
        
        mButton.setOnClickListener(new OnClickListener() {<span style="white-space:pre">		</span>//事件监听
			
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
		
				try {
					url = new URL(mEditText.getText().toString());
				} catch (MalformedURLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				mythread mth = new mythread();
				new Thread(mth).start();<span style="white-space:pre">			</span>

				mHandler = new Handler(){

						@Override
						public void handleMessage(Message msg) {
							// TODO Auto-generated method stub
							
							if (msg.what==0x111) {
								Bundle bundle=msg.getData();
								String text = bundle.getString("html");
								mTextView.setText(text);
								
							}
							else {
								Toast.makeText(getApplicationContext(), "失败", Toast.LENGTH_SHORT);
							}
							super.handleMessage(msg);
						}
						
						
					};
					
			}	
		});
        
        
    }


附上另外的一种开启线程的方法.

Thread th=new Thread(){

@Override
public void run() {
try {
t=getHtml(url);
Message m=new Message();
if(t!=null){
m.what=0x111;
mHandler.sendMessage(m);//发送消息
}else{
m.what=0x110;
mHandler.sendMessage(m);//发送消息
return;
}
} catch (Exception e) {
e.printStackTrace();
}
}

};

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值