核心技术篇:1.移动应用的根源---网络

前言

  有一次面试时候,一位面试官曾说过,所谓移动应用,重点就在于设备与网络的连接,通过网络实现用户界面和服务器的数据交互。与有线互联网一样,无线互联网也可以使用HTTP访问网络,在android中,实现HTTP通信有两种方法:一种是通过HttpURLConnextion实现,另一种是通过HttpClient实现。

HttpURLConnection类

  使用HttpURLConnection进行通信又分为两种方法:get()和post()

  默认发送的是get()请求,发送get请求时候可以在url后面通过“?参数名=参数值”的方式进行传递,多个参数之间使用逗号隔开,如:

String target="http://192.168.1.104:8080/blog/index.jsp?content="+base64(contentText.getText().toString().trim());

  使用get方法进行数据通信主要通过以下代码实现:

url=new URL(target);//创建一个URL对象
            //由于HttpURLConnection是一个抽象类,因此可以通过openConnection实例化一个对象
            //使用HttpURLConnection,默认发送的就是get请求
            HttpURLConnection urlConn=(HttpURLConnection) url.openConnection();
            //以上为向服务器发送内容
            //以下为从服务器读取内容
            if (urlConn.getResponseCode()==HttpURLConnection.HTTP_OK){
                InputStreamReader in=new InputStreamReader(urlConn.getInputStream());//从服务器读取内容
                BufferedReader buffer=new BufferedReader(in);//获得输入流对象并转换为文本
                //通过循环逐行读取输入流内容
                String inputline=null;
                while((inputline=buffer.readLine())!=null){
                    result+=inputline+"\n";
                }
                in.close();//关闭字符输入流对象
            }
            urlConn.disconnect();//断开连接

  需要说明的是,url.openConnection()只是建立了一个Http连接;直到urlConn.getInputStream()才真正把http请求发送出去。

  使用Post()方法主要通过以下代码实现:

url=new URL(target);//创建一个URL对象
            //由于HttpURLConnection是一个抽象类,因此可以通过openConnection实例化一个对象
            HttpURLConnection urlConn=(HttpURLConnection) url.openConnection();
            urlConn.setRequestMethod("POST");//指定使用POST方式进行请求
            urlConn.setDoInput(true);//允许向连接写入数据
            urlConn.setDoOutput(true);//允许从连接读取数据
            urlConn.setUseCaches(false);//禁止缓存,post请求不能使用缓存
            urlConn.setRequestProperty("Content-type", "application/x-www-form-urlencoded");//设置内容类型为URI
            DataOutputStream out=new DataOutputStream(urlConn.getOutputStream());//获取输出流
            String param="content"+URLEncoder.encode(contentText.getText().toString(),"utf-8");
            out.writeBytes(param);//往数据输出流写入数据
            out.flush();//刷新输出流,输出缓存
            out.close();//关闭输出流
            //以上为向服务器发送内容
            //以下为从服务器读取内容
            if (urlConn.getResponseCode()==HttpURLConnection.HTTP_OK){
                InputStreamReader in=new InputStreamReader(urlConn.getInputStream());//从服务器读取内容
                BufferedReader buffer=new BufferedReader(in);//获得输入流对象并转换为文本
                //通过循环逐行读取输入流内容
                String inputline=null;
                while((inputline=buffer.readLine())!=null){
                    result+=inputline+"\n";
                }
                in.close();//关闭字符输入流对象
            }
            urlConn.disconnect();//断开连接

  post方式中,http正文是通过outputstream方式写入的,outputstream实际上是个字符串流,往里面写入的数据并不会马上发送到网络,而是存储在内存缓冲区,待outputstream关闭后,根据输入的内容生成正文。参数传递方式的不同也正是get()方法和post()方法之间最大的区别。

  无论是采用get()方法或者post()方法,都需要开启一个新的子线程进行网络数据传输,并通过Handler进行消息的发送和处理:

//创建一个新线程,用于发送和读取信息
                new Thread(new Runnable(){
                    @Override
                    public void run() {
                        // TODO Auto-generated method stub
                        URLGetSend();//发送文本内容到服务器并从服务器读取结果
                        //利用obtainMessage从消息池中获取空消息对象
                        Message m=handler.obtainMessage();
                        handler.sendMessage(m);
                    }
                }).start();
handler=new Handler(){
            @Override
            public void handleMessage(Message msg){
                if(result!=null){
                    resultTV.setText(result);//更新UI线程中的界面
                    contentText.setText("");
                }
                super.handleMessage(msg);
            }
        };

  线程的创建与使用、Handler的使用、以及与Messagequeue之间的关系将会另开一篇文章进行介绍。

HttpClient类

  HttpURLConnection一般用于在某个简单页面提交请求并获取服务器的响应,对于更复杂的互联网操作,HttpClient能更好地实现。两种实现方法其实有很大联系,HttpClient对HttpURLConnection类中的输入输出流操作进行封装,封装为HttpGet、HttpPost和HttpRespense类,如此一来,减少了操作的繁琐性。其中,HttpGet类用于发送get请求,HttpPost类用于发送Post请求,HttPrespense类代表处理响应的对象。

  get()请求可以通过以下代码实现:

String target="http://192.168.1.104:8080/blog/index.jsp?content="+base64(contentText.getText().toString().trim());
        HttpClient httpclient=new DefaultHttpClient();//创建HttpClient对象
        HttpGet httpRequest=new HttpGet(target);//创建httpget连接对象
        HttpResponse httpResponse;
        try{
            httpResponse=httpclient.execute(httpRequest);//指定HttpClient请求
            if(httpResponse.getStatusLine().getStatusCode()==HttpStatus.SC_OK){
                result=EntityUtils.toString(httpResponse.getEntity());//对返回的数据进行转换
            }
            else{
                result="fail";
            }
        }

  相对HttpURLConnection类的get()方法操作方便很多。

  post()请求可以通过以下代码实现:

String target="http://192.168.1.104:8080/blog/index.jsp";
        HttpClient httpClient=new DefaultHttpClient();
        //直接使用HttpPost类实例化一个对象,不用指定请求方式
        HttpPost httpRequest=new HttpPost(target);//创建httppost连接对象
        HttpResponse httpResponse;
        //将要传递的参数保存到list集合中
        List<NameValuePair> params=new ArrayList<NameValuePair>();
        params.add(new BasicNameValuePair("content",contentText.getText().toString() ));
        try{
            httpRequest.setEntity(new UrlEncodedFormEntity(params,"utf-8"));//设置编码方式
            httpResponse=httpClient.execute(httpRequest);//执行HttpClient请求
            if(httpResponse.getStatusLine().getStatusCode()==HttpStatus.SC_OK){
                result=EntityUtils.toString(httpResponse.getEntity());//对返回的数据进行转换
            }
            else{
                result="fail";
            }
        }

  post()方法中,可以通过setParams()方法来添加请求参数,也可以调用setEntity()实现。

后续:

  有关http相关的知识还有很多,后期再做深入的学习。

posted on 2014-08-15 20:36  小太阳550  阅读(313)  评论(0编辑  收藏  举报

导航