Android之HttpURLConnection基于HTTP网络编程

基于HTTP网络编程

Android之基于HttpURLConnection下载文本与图片网络编程案例

一、HTTP通信
在开始前先简单介绍下HTTP协议中的两种不同的请求方式——GET和POST。GET方式在进行数据请求时,会把数据附加到URL后面传递给服务器,比如常见的:http://XXX.XXX.XXX/XX.jsp?id=1,POST方式则是将请求的数据放到HTTP请求头中,作为请求头的一部分传入服务器。所以,在进行HTTP编程前,首先要明确究竟使用的哪种方式进行数据请求的。

在Android中,可以有两种方式可以用来进行Http编程:
1、 HttpURLConnection
2、 HttpClient


二、HttpURLConnection
HttpURLConnection是继承自URLConnection的一个抽象类,在HTTP编程时,来自HttpURLConnection的类是所有操作的基础,获取该对象的代码如下:

 1     public HttpURLConnection urlconn= null;
 2     private void Init() throws IOException
 3     {
 4         if (urlStr=="")
 5         {
 6             urlStr="http://www.baidu.com";
 7         }
 8         URL url = new URL(urlStr);
 9         //打开一个URL所指向的Connection对象
10         urlconn = (HttpURLConnection)url.openConnection();
11     }

HttpURLConnection对网络资源的请求在默认情况下是使用GET方式的,所以当使用GET方式时,不需要我们做太多的工作; 当我们需要使用POST方式时,就需要使用setRequestMethod()来设置请求方式了。

二、HttpClient
这个类并不是来自Android的,而是来自org.apache.http。和HttpURLConnection相同,HttpClient也存在GET和POST两种方式。
1、HttpGet
在HttpClient中,我们可以非常轻松使用HttpGet对象来通过GET方式进行数据请求操作,当获得HttpGet对象后我们可以使用HttpClient的execute方法来向我们的服务器发送请求。在发送的GET请求被服务器相应后,会返回一个HttpResponse响应对象,利用这个响应的对象我们能够获得响应回来的状态码,如:200、400、401等等。

 1     public String HttpGetMethod()
 2     {
 3         String result = "";
 4         try
 5         {
 6         HttpGet httpRequest = new HttpGet(urlStr);
 7         HttpClient httpClient = new DefaultHttpClient();
 8         HttpResponse httpResponse = httpClient.execute(httpRequest);
 9         if(httpResponse.getStatusLine().getStatusCode()==HttpStatus.SC_OK)
10         {
11             result = EntityUtils.toString(httpResponse.getEntity());
12         }
13         else
14         {
15             result = "null";
16         }
17         return result;
18         }
19         catch(Exception e)
20         {
21             return null;
22         }
23     } 
 
2、HttpPost
当我们使用POST方式时,我们可以使用HttpPost类来进行操作。当获取了HttpPost对象后,我们就需要向这个请求体传入键值对,这个键值对我们可以使用NameValuePair对象来进行构造,然后再使用HttpRequest对象最终构造我们的请求体,最后使用HttpClient的execute方法来发送我们的请求,并在得到响应后返回一个HttpResponse对象。其他操作和我们在HttpGet对象中的操作一样。

 1 public String HttpPostMethod(String key,String value)
 2     {
 3         String result = "";
 4         try
 5         {
 6         // HttpPost连接对象
 7         HttpPost httpRequest = new HttpPost(urlStr);
 8         // 使用NameValuePair来保存要传递的Post参数
 9         List<NameValuePair> params = new ArrayList<NameValuePair>();
10         // 添加要传递的参数
11         params.add(new BasicNameValuePair(key, value));
12         // 设置字符集
13         HttpEntity httpentity = new UrlEncodedFormEntity(params, "Utf-8");
14         // 请求httpRequest
15         httpRequest.setEntity(httpentity);
16         // 取得默认的HttpClient
17         HttpClient httpclient = new DefaultHttpClient();
18         // 取得HttpResponse
19         HttpResponse httpResponse = httpclient.execute(httpRequest);
20         // HttpStatus.SC_OK表示连接成功
21         if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
22             // 取得返回的字符串
23             result = EntityUtils.toString(httpResponse.getEntity());
24             return result; 
25         } else {
26              return "null";
27         }
28         }
29         catch(Exception e)
30         {
31             return null;
32         }
33     }
 

三、上机任务

基于HTTP下载图像与文本文件




......


主界面类 MainActivity
1 IP 地址:安卓程序里用 localhost 127.0.0.1 表示是模拟器 IP 地址,而不是电脑的本机 IP 地址。在电脑上查看本机 IP 地址。

2 开子线程请求连接服务器(耗时的操作如果不开辟子线程,会导致主线程产生阻塞现象,影响用户体验)
3 )子线程里不能直接更新主线程 UI ,必须要通过消息处理器 Handler 对象来实现。

package net.lm.ied.download_text_image;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ProgressBar;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

/**
 * 基于HttpURLConnection下载文本和图片
 */
public class MainActivity extends Activity {

    private final String TAG = "download_text_image";
    /**
     * 服务器URL
     */
    private final String SERVER_URL = "http://192.168.183.2:8080/lzy_server";

    private ImageView ivImage;

    private EditText edtText;

    private Bitmap bitmap;

    private String text;

    private ProgressBar pbDownloadProgress;

    private Handler handler;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //通过布局资源文件设置用户界面
        setContentView(R.layout.activity_main);

        //通过资源标识获取控件实例
        ivImage = (ImageView) findViewById(R.id.iv_image);
        edtText = (EditText) findViewById(R.id.edt_text);
        pbDownloadProgress = (ProgressBar) findViewById(R.id.pb_download);

        //实例化消息处理器
       handler = new Handler(new Handler.Callback(){
           @Override
           public boolean handleMessage(Message message) {
               //利用子线程获取的数据更新主界面元素
               ivImage.setImageBitmap(bitmap);
               edtText.setText(text);
               //让进度条消失
               pbDownloadProgress.setVisibility(View.GONE);
               //事件往后传播
               return false;
           }
       });
    }
    public void doDownloadImage(View view){
        //让下载进度条出现
        pbDownloadProgress.setVisibility(View.VISIBLE);
        //创建子线程,连接服务器,下载图像资源
        new Thread(new Runnable() {
            @Override
            public void run() {
                //创建连接对象
                HttpURLConnection conn = null;

                try {
                    //定义图像资源URL
                    URL url = new URL(SERVER_URL+"/test.jpg");
                    //创建连接对象
                    conn= (HttpURLConnection) url.openConnection();
                    //获取响应码
                    int responseCode = conn.getResponseCode();
                    //根据响应码不同执行相应的操作
                    if(responseCode == HttpURLConnection.HTTP_OK){
                        //获取字节输入流
                        InputStream in = conn.getInputStream();
                        //利用位图工厂构建位图对象
                        bitmap = BitmapFactory.decodeStream(in);
                        //通过消息Message类获取消息处理器,往主线程发送消息
                        Message.obtain(handler).sendToTarget();
                    }else{
                        Log.d(TAG,"没有获取响应数据!");
                        //Toast.makeText(MainActivity.this,"没有获取响应数据",Toast.LENGTH_SHORT).show();
                    }
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }finally {
                    if(conn != null){
                        //断开网络连接,释放资源
                        conn.disconnect();
                    }
                }
            }
        }).start();
    }

    /**
     * 下载文本文件
     * @param view
     */
    public void doDownloadText(View view) {

        //创建子线程,连接服务器,下载文本资源
        new Thread(new Runnable() {
            @Override
            public void run() {
                //创建连接对象
                HttpURLConnection conn = null;

                try {
                    //定义文本资源URL
                    URL url = new URL(SERVER_URL+"/test.txt");
                    //创建连接对象
                    conn= (HttpURLConnection) url.openConnection();
                    //获取响应码
                    int responseCode = conn.getResponseCode();
                    //根据响应码不同执行相应的操作
                    if(responseCode == HttpURLConnection.HTTP_OK){
                        //获取字节输入流
                        InputStream in = conn.getInputStream();
                        //封转成缓冲字符输入流
                        BufferedReader br = new BufferedReader(new InputStreamReader(in,"UTF-8"));
                        //定义字符串生成器
                        StringBuilder builder = new StringBuilder();
                        //读取文本文件内容
                        String nextLine = "";
                        while ((nextLine = br.readLine())!= null){
                            builder.append(nextLine +"\n");
                        }
                        //将文件内容保存到文本变量
                        text = builder.toString();
                        //通过消息Message类获取消息处理器,往主线程发送消息
                        Message.obtain(handler).sendToTarget();
                    }else{
                        Log.d(TAG,"没有获取响应数据!");
                        //Toast.makeText(MainActivity.this,"没有获取响应数据",Toast.LENGTH_SHORT).show();
                        //java.net.SocketException: socket failed: EACCES (Permission denied)   没有权限访问
                    }
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }finally {
                    if(conn != null){
                        //断开网络连接,释放资源
                        conn.disconnect();
                    }
                }
            }
        }).start();
    }

    // TODO  download 将两个文件放在download目录中

}

受限访问在AndroidManifest.xml中添加:

<uses-permission android:name="android.permission.INTERNET"></uses-permission>


(四)、代码

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="15dp"
    android:orientation="vertical"
    tools:context="net.lm.ied.download_text_image.MainActivity">


    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:gravity="center"
        android:layout_height="wrap_content">


        <Button
            android:id="@+id/btn_download_text"
            android:layout_width="150dp"
            android:layout_height="wrap_content"
            android:onClick="doDownloadText"
            android:text="@string/download_text"/>

        <Button
            android:id="@+id/btn_download_image"
            android:layout_width="150dp"
            android:layout_height="wrap_content"
            android:onClick="doDownloadImage"
            android:text="@string/download_image"/>

    </LinearLayout>

    <ProgressBar
        android:id="@+id/pb_download"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:visibility="gone"/>

    <ImageView
        android:id="@+id/iv_image"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:scaleType="fitXY"/>

    <EditText
        android:id="@+id/edt_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:lines="8"
        android:editable="false"
        android:scrollbars="vertical"/>


</LinearLayout>


<resources>
    <string name="app_name">基于HttpURLConnection下载文本和图片</string>
    <string name="download_text">下载文本</string>
    <string name="download_image">下载图片</string>
</resources>






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

liumce

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值