Http网络连接处理

    |     2015年8月5日   |   网络通讯   |     0 条评论   |    1716

Android 联网先拿回数据再解析。HTTP 协议可参考 深入理解HTTP协议。动手前在 manifest 加权限,检查网络是否可用,并把请求放到 UI 线程之外(常用 AsyncTask)。客户端多用 HttpURLConnection,也可用 Apache HttpClient。


一、权限与网络是否可用

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
if (isGpsConnection() || isWiFiConnection()) {
    //网络连接可用
} else {
    //网络连接不可用!
}
public boolean isGpsConnection(){
    ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
    if (networkInfo != null && networkInfo.isConnected()) {
        return true;
    } else {
        return false;
    }
}

public boolean isWiFiConnection(Context inContext) {
    Context context = inContext.getApplicationContext();
    ConnectivityManager connectivity = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);

    if (connectivity != null) {
        NetworkInfo[] info = connectivity.getAllNetworkInfo();
        if (info != null) {
            for (int i = 0; i < info.length; i++) {
                if (info[i].getTypeName().equals("WIFI") && info[i].isConnected()) {
                    return true;
                }
            }
        }
    }
    return false;
}

二、AsyncTask 避开 UI 线程延迟

网络会有不可预期延迟,必须在 UI Thread 外执行。doInBackground 调 downloadUrl()(URL 从 execute() 传入,params[0] 是 url),处理完把 String 交给 onPostExecute 更新 UI。

private class DownloadWebpageText extends AsyncTask<String, Void, String> {
    @Override
    protected String doInBackground(String... urls) {
        // 参数从 execute() 传入, params[0] 表示 url
    }

    @Override
    protected void onPostExecute(String result) {
    }
}

三、完整实例:HttpURLConnection GET

布局 activity_httpconnection_layout.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <EditText
        android:id="@+id/http_url_edit"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="请输入URL地址" />

    <TextView
        android:id="@+id/http_content_txt"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <Button android:id="@+id/http_get_content_btn"
        android:layout_width="match_parent"
        android:onClick="onConnectionClickHandler"
        android:layout_height="wrap_content" />

</LinearLayout>

HttpExampleActivity.java:点按钮先查网络,再异步 GET。注意 getResponseCode() 返回状态码,200 表示成功。

public class HttpExampleActivity extends Activity {
    private static final String DEBUG_TAG = "HttpExample";
    private EditText mUrlText;
    private TextView mShowMessageTxt;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_httpconnection_layout);
        mUrlText = (EditText) findViewById(R.id.http_url_edit);
        mShowMessageTxt = (TextView) findViewById(R.id.http_content_txt);
    }

    public void onConnectionClickHandler(View view) {
        String stringUrl = mUrlText.getText().toString();
        ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
        if (networkInfo != null && networkInfo.isConnected()) {
            new DownloadWebpageText().execute(stringUrl);
        } else {
            mShowMessageTxt.setText("网络连接不可用!");
        }
    }

    private class DownloadWebpageText extends AsyncTask<String, Void, String> {
        @Override
        protected String doInBackground(String... urls) {
            try {
                return downloadUrl(urls[0]);
            } catch (IOException e) {
                return "Unable to retrieve web page. URL may be invalid.";
            }
        }

        @Override
        protected void onPostExecute(String result) {
            mShowMessageTxt.setText(result);
        }
    }

    private String downloadUrl(String myurl) throws IOException {
        InputStream is = null;
        try {
            URL url = new URL(myurl);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setReadTimeout(10000);
            conn.setConnectTimeout(15000);
            conn.setRequestMethod("GET");
            conn.setDoInput(true);

            conn.connect();
            int response = conn.getResponseCode();
            Log.d(DEBUG_TAG, "The response is: " + response);
            is = conn.getInputStream();
            return readIt(is);
        } finally {
            if (is != null) {
                is.close();
            }
        }
    }

    public String readIt(InputStream stream) throws IOException, UnsupportedEncodingException {
        Reader reader = new InputStreamReader(stream, "UTF-8");
        BufferedReader br = new BufferedReader(reader);
        String line = null;
        StringBuffer sb = new StringBuffer();
        while ((line = br.readLine()) != null) {
            sb.append(line);
        }
        return sb.toString();
    }
}

InputStream 是可读的 byte 源,通常要 decode 成目标类型。下图数据可直接:

InputStream is = null;
...
Bitmap bitmap = BitmapFactory.decodeStream(is);
ImageView imageView = (ImageView) findViewById(R.id.image_view);
imageView.setImageBitmap(bitmap);

四、Apache HttpClient 写法

HttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(httpUrl);
HttpResponse response = httpClient.execute(httpGet);

int statusCode = response.getStatusLine().getStatusCode();
Logs.v("statusCode >>> :" + statusCode);

if (statusCode == HttpURLConnection.HTTP_OK) {
    InputStream ins = response.getEntity().getContent();
    BufferedReader br = new BufferedReader(new InputStreamReader(ins, "utf-8"));
    StringBuilder sb = new StringBuilder();
    String line = null;
    while ((line = br.readLine()) != null) {
        sb.append(line);
    }
}
步骤 要点
权限 INTERNET + ACCESS_NETWORK_STATE
可用性 ConnectivityManager + NetworkInfo.isConnected
线程 AsyncTask:后台 download,onPostExecute 更新 UI
客户端 HttpURLConnection(推荐)或 Apache HttpClient
成功码 getResponseCode() == 200

一句话总结:联网 = 权限 + 检查 NetworkInfo + 后台 HttpURLConnection GET,把 InputStream 转成 String 或 Bitmap,状态码 200 再当成功。

转载请注明来源:Http网络连接处理
本文链接地址:https://ai.zhousir.top/?p=925
回复 取消