Android网络编程之使用HttpClient进行Get方式通信

在Android开发中,Android SDK附带了Apache的HttpClient,它是一个完善的客户端。它提供了对HTTP协议的全面支持,可以使用HttpClient的对象来执行HTTP GET和HTTP POST调用。

HTTP工作原理:
1.客户端(一般是指浏览器,这里是指自己写的程序)与服务器建立连接
2.建立连接后,客户端向服务器发送请求
3.服务器接收到请求后,向客户端发送响应信息
4.客户端与服务器断开连接

HttpClient的一般使用步骤:
1.使用DefaultHttpClient类实例化HttpClient对象
2.创建HttpGet或HttpPost对象,将要请求的URL通过构造方法传入HttpGet或HttpPost对象。
3.调用execute方法发送HTTP GET或HTTP POST请求,并返回HttpResponse对象。
4.通过HttpResponse接口的getEntity方法返回响应信息,并进行相应的处理。
最后记得要在AndroidManifest.xml文件添加网络权限
<uses-permission android:name="android.permission.INTERNET" />

下面以聚合数据空气质量城市空气PM2.5指数数据接口为例来演示使用HttpClient进行Get方式通信,通过HttpClient建立网络连接,使用HttpGet方法读取数据,并且通过HttpResponse获取Entity返回值。
聚合数据空气质量城市空气PM2.5指数数据接口API文档参见: http://www.juhe.cn/docs/api/id/33/aid/79
请求示例:http://web.juhe.cn:8080/environment/air/pm?city=城市名称&key=你申请的APPKEY值

实例:HttpClientGetDemo
运行效果:


代码清单:
布局文件:activity_main.xml
<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:orientation="vertical"
    tools:context=".MainActivity" >

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

		<TextView
		    android:layout_width="wrap_content"
		    android:layout_height="wrap_content"
		    android:layout_weight="1"
		    android:gravity="center"
		    android:text="城市:"
		    android:textSize="23sp" />

		<EditText 
            android:id="@+id/city"
            android:layout_width="wrap_content"
			android:layout_height="wrap_content"
			android:layout_weight="3"
            android:inputType="text" />"
    </LinearLayout>

    <Button
        android:id="@+id/query"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" 
        android:text="查询" 
        android:textSize="23sp" />
    
    <TextView
		android:id="@+id/result"
		android:layout_width="match_parent"
		android:layout_height="match_parent" />
</LinearLayout>

Java源代码文件:MainActivity.java

package com.rainsong.httpclientgetdemo;

import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import android.os.Bundle;
import android.os.StrictMode;
import android.app.Activity;
import android.view.Menu;
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 static final String JUHE_URL_ENVIRONMENT_AIR_PM = 
                                    "http://web.juhe.cn:8080/environment/air/pm";
    private static final String JUHE_APPKEY = "你申请的APPKEY值";
    EditText et_city;
    Button btn_query;
    TextView tv_result;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 强制直接在UI线程中进行网络操作
        StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
            .detectDiskReads().detectDiskWrites().detectNetwork()
            .penaltyLog().build());
        StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
            .detectLeakedSqlLiteObjects().detectLeakedClosableObjects()
            .penaltyLog().penaltyDeath().build());

        setContentView(R.layout.activity_main);
        et_city = (EditText)findViewById(R.id.city);
        tv_result = (TextView)findViewById(R.id.result);
        btn_query = (Button)findViewById(R.id.query);
        btn_query.setOnClickListener(new OnClickListener() {
            public void onClick(View view) {
                tv_result.setText("");
                String city;
                city = et_city.getText().toString();
                if (city.length() < 1) {
                    Toast.makeText(MainActivity.this, "请输入城市名",
                            Toast.LENGTH_LONG).show();
                    return;
                }
                ArrayList<NameValuePair> headerList = new ArrayList<NameValuePair>();
                headerList.add(new BasicNameValuePair("Content-Type",
                        "text/html; charset=utf-8"));
                String targetUrl = JUHE_URL_ENVIRONMENT_AIR_PM;
                ArrayList<NameValuePair> paramList = new ArrayList<NameValuePair>();
                paramList.add(new BasicNameValuePair("key", JUHE_APPKEY));
                paramList.add(new BasicNameValuePair("dtype", "json"));
                paramList.add(new BasicNameValuePair("city", city));
                
                for (int i = 0; i < paramList.size(); i++) {
                    NameValuePair nowPair = paramList.get(i);
                    String value = nowPair.getValue();
                    try {
                        value = URLEncoder.encode(value, "UTF-8");
                    } catch (Exception e) {
                        
                    }
                    if (i == 0) {
                        targetUrl += ("?" + nowPair.getName() + "=" + value);
                    } else {
                        targetUrl += ("&" + nowPair.getName() + "=" + value);
                    }
                }

                HttpGet httpRequest = new HttpGet(targetUrl);
                try {
                    for (int i = 0; i < headerList.size(); i++) {
                        httpRequest.addHeader(headerList.get(i).getName(),
                                                headerList.get(i).getValue());
                    }

                    HttpClient httpClient = new DefaultHttpClient();

                    HttpResponse httpResponse = httpClient.execute(httpRequest);
                    if (httpResponse.getStatusLine().getStatusCode() == 200) {
                        String strResult = EntityUtils.toString(httpResponse.getEntity());
                        tv_result.setText(strResult);
                    } else {
                        Toast.makeText(MainActivity.this, "查询失败",
                                Toast.LENGTH_LONG).show();
                        tv_result.setText("");
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

}

注:本来不应该直接在UI线程进行网络操作,会阻塞UI,影响用户体验。但为了不引入其他知识点,把焦点聚集在HttpClient网络通信上,在本例中强制直接在UI线程中进行网络操作。在下篇文章中会介绍如何避免直接在UI线程中进行网络操作。


API知识点
public interface
HttpClient

org.apache.http.client.HttpClient

Known Indirect Subclasses
AbstractHttpClient, AndroidHttpClient, DefaultHttpClient

Class Overview
Interface for an HTTP client. HTTP clients encapsulate a smorgasbord of objects required to execute HTTP requests while handling cookies, authentication, connection management, and other features. Thread safety of HTTP clients depends on the implementation and configuration of the specific client.

abstract HttpResponse execute(HttpUriRequest request)
Executes a request using the default context.

public class
DefaultHttpClient
extends AbstractHttpClient

org.apache.http.impl.client.DefaultHttpClient

Class Overview
Default implementation of an HTTP client.

Public Constructor
DefaultHttpClient()
Creates a new HTTP client.

public class
HttpGet
extends HttpRequestBase

Inherited Methods
 From class org.apache.http.client.methods.HttpRequestBase
 From class org.apache.http.message.AbstractHttpMessage
 From class java.lang.Object
 From interface org.apache.http.HttpMessage
 From interface org.apache.http.HttpRequest
 From interface org.apache.http.client.methods.AbortableHttpRequest
 From interface org.apache.http.client.methods.HttpUriRequest

Public Constructors
HttpGet()
HttpGet(URI uri)
HttpGet(String uri)

abstract void addHeader(String name, String value)
Adds a header to this message.

public interface
HttpResponse
implements HttpMessage

org.apache.http.HttpResponse

Class Overview
An HTTP response.

abstract HttpEntity getEntity()
Obtains the message entity of this response, if any.

abstract StatusLine getStatusLine()
Obtains the status line of this response.

public interface
NameValuePair

org.apache.http.NameValuePair

Known Indirect Subclasses
BasicNameValuePair

Class Overview
A simple class encapsulating an attribute/value pair.

Public Methods
abstract String getName()
abstract String getValue()

public class
BasicNameValuePair
extends Object
implements Cloneable NameValuePair

org.apache.http.message.BasicNameValuePair

Public Constructors
BasicNameValuePair(String name, String value)
Default Constructor taking a name and a value.



  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
您好!对于ESP8266进行网络编程使用Arduino编程语言可以很方便地实现。如果您在使用HttpClient库时遇到了"connection refused"的错误,可能是因为连接被服务器拒绝了。 这种错误通常有以下几个原因: 1. 服务器未启动或不可用:请确保您要访问的服务器已经启动,并且可以从您的设备所在的网络访问到该服务器。 2. 服务器地址或端口错误:请检查您在代码中设置的服务器地址和端口号是否正确。确保它们与服务器配置一致。 3. 防火墙或网络限制:某些网络环境可能会对某些端口或IP地址进行限制。请确保您的网络环境允许通过所需的端口进行通信。 以下是一个简单的示例代码,演示如何在ESP8266上使用HttpClient进行GET请求: ```cpp #include <ESP8266WiFi.h> #include <ESP8266HTTPClient.h> const char* ssid = "YourNetworkSSID"; const char* password = "YourNetworkPassword"; void setup() { Serial.begin(115200); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.println("Connecting to WiFi..."); } Serial.println("Connected to WiFi"); // 发起GET请求 HTTPClient http; // 设置服务器地址和端口 http.begin("http://example.com/api/data"); // 替换为您的服务器地址 // 发送GET请求 int httpCode = http.GET(); if (httpCode > 0) { // 获取响应内容 String response = http.getString(); Serial.println(response); } else { Serial.println("Error on HTTP request"); } // 关闭连接 http.end(); } void loop() { // 其他代码... } ``` 请根据您的网络环境和服务器配置,将上述代码中的网络参数进行相应的修改。希望这能够帮助您解决问题!如果仍然有疑问,请随时向我提问。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值