当前位置: 移动技术网 > IT编程>移动开发>Android > Android使用http协议与服务器通信的实例

Android使用http协议与服务器通信的实例

2019年07月24日  | 移动技术网IT编程  | 我要评论

奇异博士下载,游侠补丁网,兵马俑的资料

网上介绍android上http通信的文章很多,不过大部分只给出了实现代码的片段,一些注意事项和如何设计一个合理的类用来处理所有的http请求以及返回结果,一般都不会提及。因此,自己对此做了些总结,给出了我的一个解决方案。

首先,需要明确一下http通信流程,android目前提供两种http通信方式,httpurlconnection和httpclient,httpurlconnection多用于发送或接收流式数据,因此比较适合上传/下载文件,httpclient相对来讲更大更全能,但是速度相对也要慢一点。在此只介绍httpclient的通信流程:

1.创建httpclient对象,改对象可以用来多次发送不同的http请求

2.创建httppost或httpget对象,设置参数,每发送一次http请求,都需要这样一个对象

3.利用httpclient的execute方法发送请求并等待结果,该方法会一直阻塞当前线程,直到返回结果或抛出异常。

4.针对结果和异常做相应处理 

根据上述流程,发现在设计类的时候,有几点需要考虑到:

1.httpclient对象可以重复使用,因此可以作为类的静态变量

2.httppost/httpget对象一般无法重复使用(如果你每次请求的参数都差不多,也可以重复使用),因此可以创建一个方法用来初始化,同时设置一些需要上传到服务器的资源

3.目前android不再支持在ui线程中发起http请求,实际上也不该这么做,因为这样会阻塞ui线程。因此还需要一个子线程,用来发起http请求,即执行execute方法

4.不同的请求对应不同的返回结果,对于如何处理返回结果(一般来说都是解析json&更新ui),需要有一定的自由度。

5.最简单的方法是,每次需要发送http请求时,开一个子线程用于发送请求,子线程中接收到结果或抛出异常时,根据情况给ui线程发送message,最后在ui线程的handler的handlemessage方法中做结果解析和ui更新。这么写虽然简单,但是ui线程和http请求的耦合度很高,而且代码比较散乱、丑陋。

基于上述几点原因,我设计了一个postrequest类,用于满足我的http通信需求。我只用到了post请求,如果你需要get请求,也可以改写成getrequest

package com.handspeaker.network;

import java.io.ioexception;
import java.io.unsupportedencodingexception;
import java.net.uri;
import java.net.urisyntaxexception;
import java.util.concurrent.executorservice;
import java.util.concurrent.executors;

import org.apache.http.httpresponse;
import org.apache.http.client.clientprotocolexception;
import org.apache.http.client.httpclient;
import org.apache.http.client.methods.httppost;
import org.apache.http.entity.stringentity;
import org.apache.http.impl.client.defaulthttpclient;
import org.apache.http.params.httpconnectionparams;
import org.apache.http.params.httpparams;
import org.apache.http.protocol.http;
import org.apache.http.util.entityutils;
import org.json.jsonobject;

import android.app.activity;
import android.content.context;
import android.net.connectivitymanager;
import android.os.handler;
import android.util.log;

/**
 * 
 * 用于封装&简化http通信
 * 
 */
public class postrequest implements runnable {
  
  private static final int no_server_error=1000;
  //服务器地址
  public static final string url = "fill your own url";
  //一些请求类型
  public final static string add = "/add";
  public final static string update = "/update";
  public final static string ping = "/ping";
  //一些参数
  private static int connectiontimeout = 60000;
  private static int sockettimeout = 60000;
  //类静态变量
  private static httpclient httpclient=new defaulthttpclient();
  private static executorservice executorservice=executors.newcachedthreadpool();
  private static handler handler = new handler();
  //变量
  private string strresult;
  private httppost httppost;
  private httpresponse httpresponse;
  private onreceivedatalistener onreceivedatalistener;
  private int statuscode;

  /**
   * 构造函数,初始化一些可以重复使用的变量
   */
  public postrequest() {
    strresult = null;
    httpresponse = null;
    httppost = new httppost();
  }
  
  /**
   * 注册接收数据监听器
   * @param listener
   */
  public void setonreceivedatalistener(onreceivedatalistener listener) {
    onreceivedatalistener = listener;
  }

  /**
   * 根据不同的请求类型来初始化httppost
   * 
   * @param requesttype
   *      请求类型
   * @param namevaluepairs
   *      需要传递的参数
   */
  public void inirequest(string requesttype, jsonobject jsonobject) {
    httppost.addheader("content-type", "text/json");
    httppost.addheader("charset", "utf-8");

    httppost.addheader("cache-control", "no-cache");
    httpparams httpparameters = httppost.getparams();
    httpconnectionparams.setconnectiontimeout(httpparameters,
        connectiontimeout);
    httpconnectionparams.setsotimeout(httpparameters, sockettimeout);
    httppost.setparams(httpparameters);
    try {
      httppost.seturi(new uri(url + requesttype));
      httppost.setentity(new stringentity(jsonobject.tostring(),
          http.utf_8));
    } catch (urisyntaxexception e1) {
      e1.printstacktrace();
    } catch (unsupportedencodingexception e) {
      e.printstacktrace();
    }
  }

  /**
   * 新开一个线程发送http请求
   */
  public void execute() {
    executorservice.execute(this);
  }

  /**
   * 检测网络状况
   * 
   * @return true is available else false
   */
  public static boolean checknetstate(activity activity) {
    connectivitymanager connmanager = (connectivitymanager) activity
        .getsystemservice(context.connectivity_service);
    if (connmanager.getactivenetworkinfo() != null) {
      return connmanager.getactivenetworkinfo().isavailable();
    }
    return false;
  }

  /**
   * 发送http请求的具体执行代码
   */
  @override
  public void run() {
    httpresponse = null;
    try {
      httpresponse = httpclient.execute(httppost);
      strresult = entityutils.tostring(httpresponse.getentity());
    } catch (clientprotocolexception e1) {
      strresult = null;
      e1.printstacktrace();
    } catch (ioexception e1) {
      strresult = null;
      e1.printstacktrace();
    } finally {
      if (httpresponse != null) {
        statuscode = httpresponse.getstatusline().getstatuscode();
      }
      else
      {
        statuscode=no_server_error;
      }
      if(onreceivedatalistener!=null)
      {
        //将注册的监听器的onreceivedata方法加入到消息队列中去执行
        handler.post(new runnable() {
          @override
          public void run() {
            onreceivedatalistener.onreceivedata(strresult, statuscode);
          }
        });
      }
    }
  }

  /**
   * 用于接收并处理http请求结果的监听器
   *
   */
  public interface onreceivedatalistener {
    /**
     * the callback function for receiving the result data
     * from post request, and further processing will be done here
     * @param strresult the result in string style.
     * @param statuscode the status of the post
     */
    public abstract void onreceivedata(string strresult,int statuscode);
  }

}

代码使用了观察者模式,任何需要接收http请求结果的类,都要实现onreceivedatalistener接口的抽象方法,同时postrequest实例调用setonreceivedatalistener方法,注册该监听器。完整调用步骤如下:

1.创建postrequest对象,实现onreceivedata接口,编写自己的onreceivedata方法

2.注册监听器

3.调用postrequest的inirequest方法,初始化本次request

4.调用postrequest的execute方法

 可能的改进:

1.如果需要多个观察者,可以把只能注册单个监听器改为可以注册多个监听器,维护一个监听器list。

2.如果需求比较简单,并希望调用流程更简洁,inirequest和execute可以合并

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网