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

来源:互联网 发布:剑网3更新网络中断 编辑:程序博客网 时间:2024/06/03 18:41

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 MethodsvoidcopyFrom(Message o)
Make this message like o.
intdescribeContents()
Describe the kinds of special objects contained in this Parcelable's marshalled representation.
RunnablegetCallback()
Retrieve callback object that will execute when this message is handled.
BundlegetData()
Obtains a Bundle of arbitrary data associated with this event, lazily creating it if necessary.
HandlergetTarget()
Retrieve the a Handler implementation that will receive this message.
longgetWhen()
Return the targeted delivery time of this message, in milliseconds.
static Messageobtain(Handler h, int what, int arg1, int arg2, Object obj)
Same as obtain(), but sets the values of the targetwhatarg1arg2, and obj members.
static Messageobtain(Handler h, int what, Object obj)
Same as obtain(), but sets the values of the targetwhat, and obj members.
static Messageobtain(Handler h, int what)
Same as obtain(), but sets the values for both target and what members on the Message.
static Messageobtain(Handler h)
Same as obtain(), but sets the value for the target member on the Message returned.
static Messageobtain(Handler h, Runnable callback)
Same as obtain(Handler), but assigns a callback Runnable on the Message that is returned.
static Messageobtain()
Return a new Message instance from the global pool.
static Messageobtain(Handler h, int what, int arg1, int arg2)
Same as obtain(), but sets the values of the targetwhatarg1, and arg2 members.
static Messageobtain(Message orig)
Same as obtain(), but copies the values of an existing message (including its target) into the new one.
BundlepeekData()
Like getData(), but does not lazily create the Bundle.
voidrecycle()
Return a Message instance to the global pool.
voidsendToTarget()
Sends this Message to the Handler specified by getTarget().
voidsetData(Bundle data)
Sets a Bundle of arbitrary data values.
voidsetTarget(Handler target)StringtoString()
Returns a string containing a concise, human-readable description of this object.
voidwriteToParcel(Parcel dest, int flags)
Flatten this object in to a Parcel.

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

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

线程类:java
   class MyThread implements Runnable{    String s = null;@Overridepublic void run() {// TODO Auto-generated method stubtry {s = MainActivity.getSourceCodeString(url);<span style="white-space:pre"></span>////这个是获取网页源码的.} catch (MalformedURLException e) {// TODO Auto-generated catch blocke.printStackTrace();}Message message = new Message();//可以用obtainMessage获得Bundle bundle = new Bundle();if(s!=null){message.what = 0x111;bundle.putString("html", s);//添加数据到Bundlemessage.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 blockLog.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 blockLog.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>//事件监听@Overridepublic void onClick(View v) {// TODO Auto-generated method stubtry {url = new URL(mEditText.getText().toString());} catch (MalformedURLException e) {// TODO Auto-generated catch blocke.printStackTrace();}mythread mth = new mythread();new Thread(mth).start();<span style="white-space:pre"></span>mHandler = new Handler(){@Overridepublic void handleMessage(Message msg) {// TODO Auto-generated method stubif (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