04_消息机制的写法

handle直接翻译叫处理。Handler叫做处理者/助手。

A Handler allows you to send and process Message and Runnable objects associated with a thread's MessageQueue. Each Handler instance is associated with a single thread and that thread's message queue. When you create a new Handler, it is bound to the thread / message queue of the thread that is creating it -- from that point on, it will deliver messages and runnables to that message queue and execute them as they come out of the message queue. 

Handler允许你去发送并且处理消息或者说是一个Runnable对象。Handler是跟一个Thread线程对应起来。线程有一个MessageQueue(消息队列)。每一个Handler的实例都和一个单独的线程是一一对应的。在哪一个线程创建的Handler,这个Handler就和这个线程是对应起来的。如果Handler是在主线程里面创建的,那么它实际上就对应着这个主线程。当你创建一个Handler对象,它就跟这个线程绑定在一起了。反复提到了有一个消息队列。可以通过Handler来发一条消息,实际上是想在子线程里面获取数据。然后得在主线程拿到这个数据之后,更新界面。这就涉及到它们俩之间得进行沟通。子线程拿到数据之后得想办法通知一下主线程,在通知的过程当中可以把数据给它携带过去。这就涉及到子线程要发一个消息发给主线程。

在哪个线程创建的Handler,这个Handler就跟当前的线程建立的一一对应的关系。所以可以在主线程创建这么一个Handler。Handler可以发送一个消息并且还可以处理消息。

handler既可以去发送消息/数据还可以处理消息,那就可以通过Handler在子线程发消息,在主线程处理消息。



There are two main uses for a Handler: (1) to schedule messages and runnables to be executed as some point in the future; and (2) to enqueue an action to be performed on a different thread than your own.

 有两个最主要的用处:在未来的某一时刻来运行这么一个消息或者说是一个runnable对象。这一个用法咱们以后再说。最主要的对于咱们的就是这个东西:可以在你所拥用的不同线程之间来进行消息的传递。基本的思路:在子线程里面通过handler发消息,在主线程中创建一个Handler对象。


安卓源码路径是:

H:\heimaandroidadt\adt-bundle-windows-x86_64_20140101\adt-bundle-windows-x86_64_20140101\sdk\sources\android-18

    /**
     * Subclasses must implement this to receive messages.
     */
    public void handleMessage(Message msg) {
    }

实际上它是啥也没有,等着你去实现。你想去接收到消息的话必须得实现这个方法。

整个handler的用法套路还是挺简单的,一共就分三步:①在主线程创建一个handler②子线程发消息③主线程处理消息 一共就这么几步,但是这里面这个原理稍微有一点复杂。


 

package com.itheima.servlet;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class HelloServlet
 */
//@WebServlet("/HelloServlet")
public class HelloServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    /**
     * Default constructor. 
     */
    public HelloServlet() {
        // TODO Auto-generated constructor stub
    }

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        //response.getWriter().append("Served at: ").append(request.getContextPath());
        try {
            Thread.sleep(10000);//接收请求之后设置服务端睡眠10秒
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        response.getWriter().append("Served at: ").append(request.getContextPath());//让服务端睡眠10秒之后才产生响应
    }
    //http://localhost:8080/day07_01_servlethello/hello
    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        doGet(request, response);
    }

}
package com.itheima.htmlcodeviewer;

import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {

    private EditText et_url;
    private Button btn_show;
    private TextView tv_code;
//①在主线程创建一个handler 这个handler的消息就会发送到主线程的消息队列中
    private Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {//这就是套路,创建一个handler对象并且重写它的handleMessage()方法.
            // TODO Auto-generated method stub
            //super.handleMessage(msg);
            //可以通过handler在主线程中处理消息  在handleMessage方法中处理消息            
        String temp = (String) msg.obj;//obj携带了相关的数据,实际上它是一个text,是一个String类型的文本
        //刚才咱们丢进来的就是String类型的
        tv_code.setText(temp);//由于这个Handler是在主线程创建的,所以直接在这儿去修改这个数据.我现在是在主线程操作.
        //实现了把消息丢给主线程来处理.
        };
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        et_url = (EditText) findViewById(R.id.et_url);
        btn_show = (Button) findViewById(R.id.btn_show);
        tv_code = (TextView) findViewById(R.id.tv_code);
        //et_url.setText("http://10.0.2.2:8080");
        //et_url.setText("http://10.0.2.2:8080/day07_01_servlethello/hello");
        et_url.setText("http://localhost:8080/day07_01_servlethello/hello");
        btn_show.setOnClickListener(new MyOnClickListenr());
        String name = Thread.currentThread().getName();
        Toast.makeText(this, name, Toast.LENGTH_SHORT).show();
    }

    private class MyOnClickListenr implements OnClickListener{

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            new Thread(){
                public void run() {
                    //获取url
                    String path = et_url.getText().toString().trim();
                        try {
                            URL url = new URL(path);
                            //拿着url联网
                            //URLConnection openConnection = url.openConnection();
                            HttpURLConnection openConnection = (HttpURLConnection) url.openConnection();
                        //} catch (MalformedURLException e) {
                            //设置请求的方法  方法要大写   默认采用的是GET方式请求 
                            openConnection.setRequestMethod("GET");
                            //如果联网之后网络信号不是太好,那就涉及到一直在等,一直在等
                            //有的时候可能会等的时间很长,等的时间很长的话那就有问题了,我究竟等到什么时候算是个结束
                            //设置超时的时间,一旦超过这个时间默认就是连接失败,让它停止下来
                            openConnection.setConnectTimeout(10000);//设置一个连接超时的时间
                            //获取响应码
                            int responseCode = openConnection.getResponseCode();
                            //判断响应码  如果是200 获取流
                            if(responseCode==200){
                                //联网后获得响应内容  响应是通过流的方式去返回回来的
                                //通过textview 展示对应的内容    
                                InputStream inputStream = openConnection.getInputStream();//InputStream其实放的就是跟咱们HTML代码相关的内容
                                String stringFromStream = Utils.getStringFromStream(inputStream);
                                //不能直接修改界面 而是要通知主线程  获取到了数据  并且把数据丢给主线程  在主线程中显示
                                //②通过handler发送消息Message,把要更新界面用到的数据 通过Message 携带数据
                                //不能直接修改界面 而是要通知主线程  获取到了数据  并且把数据丢给主线程  在主线程中显示 所以现在就用到了一个API:Handler
                                //通过handler发送消息Message 把要更新界面用到的数据  通过Message进行携带  Message是一个对象 一个对象里面可以搞一些属性  通过这些属性
                                //就把这些内容给它携带过去  携带数据 
                                Message msg = new Message();
                                msg.obj = stringFromStream;//通过obj就可以携带数据  因为它是Object类型  什么对象都可以丢给它
                                handler.sendMessage(msg);
                                //修改textview内容展示数据
                                //tv_code.setText(stringFromStream);
                            }
                        } catch (Exception e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                };
            }.start();    
        }        
    }
}
package com.itheima.htmlcodeviewer;

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

public class Utils {
//从这个流里面把它内容读出来,读出来之后把它转化成一个String类型的数据
    public static String getStringFromStream(InputStream inputStream) {
        // TODO Auto-generated method stub
        //把流转化为字符串
        ByteArrayOutputStream baso = new ByteArrayOutputStream();
        int len = -1;
        byte[] buffer = new byte[1024];
        try {
            while((len=inputStream.read(buffer))!=-1){
                baso.write(buffer, 0, len);
            }
            inputStream.close();
            byte[] byteArray  =  baso.toByteArray();
            return new String(byteArray);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return null;
        }
    }

}

 

posted on 2017-06-20 06:59  绿茵好莱坞  阅读(132)  评论(0编辑  收藏  举报

导航