Android http网络请求框架搭建

本文主要介绍如何在Android上搭建一套基于HTTP的简单网络请求框架。内容包括参数传递、网络请求、多线程处理、数据格式转换和状态回调等关键步骤。示例中使用了HttpClient,但强调可以替换为其他如HttpURLConnection的方式。虽然这个框架已具备基本功能,但仍有网络加密、缓存、泛型参数和登录拦截等优化点待补充。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

android上网络请求大致分为使用socket和http,普通应用大多使用http或者https,今天主要介绍http,实现目标通过使用http搭建一套简单的Android网络请求框架。



网络请求部分:

Android的网络请求部分我们大致分为:

参数传递,网络请求,多线程处理,结果数据格式转换,状态回调赋值处理。这几快内容。


当然还有网络加密处理,缓存处理,泛型参数传递、登录前操作拦截等内容需要添加。


案例一:

请求参数定义:


/***
 * 定义基础请求参数类
 * @param <T>
 */
public abstract class BaseParser<T> {

   public abstract T parseJSON(String paramString) throws JSONException;

   /**
    *
    * @throws JSONException
    */
   public String checkResponse(String paramString) throws JSONException {
      if (paramString == null) {
         return null;
      } else {
         JSONObject jsonObject = new JSONObject(paramString);
         String result = jsonObject.getString("response");
         if (result != null && !result.equals("error")) {
            return result;
         } else {
            return null;
         }

      }
   }
}

请求参数举例:

/**
 * 列表请求参数-捎带数据Bean
 * @author
 */
public class ListPageParser extends BaseParser<List<ListpageItemBean>>{
   @Override
   public List<ListpageItemBean> parseJSON(String paramString) throws JSONException {
      if (!TextUtils.isEmpty(checkResponse(paramString))) {
         return (List<ListpageItemBean>)(GsonParseUtils.Gson2Object(paramString,null));
      }
      JDLog.e("ListPageParser-->","解析JSON出错");
      return new ArrayList<ListpageItemBean>();
   }
}
/**
 * 使用Gson解析相应Bean
 */
public class GsonParseUtils {
   private static Gson gson = new Gson();

   public static Object Gson2Object(String json, Type tp) {
      try {
         return gson.fromJson(json, tp);
      } catch (Exception e) {
         e.printStackTrace();
         LogUtil.e(GsonParseUtils.class, "ParseUtils 解析失败", 15);
         return null;
      }
   }

   public static String Object2Json(Object json) {
      try {
         return gson.toJson(json);
      } catch (Exception e) {
         e.printStackTrace();
         LogUtil.e(GsonParseUtils.class, "ParseUtils 转化失败", 27);
         return null;
      }
   }
}

/**
 * 定义网络请求参数
 */
public class RequestVo {
   public String requestUrl;
   public Context context;
   public HashMap<String, String> requestDataMap;
   public BaseParser<?> jsonParser;

   public RequestVo() {
   }

   public RequestVo(String requestUrl, Context context, HashMap<String, String> requestDataMap, BaseParser<?> jsonParser) {
      super();
      this.requestUrl = requestUrl;
      this.context = context;
      this.requestDataMap = requestDataMap;
      this.jsonParser = jsonParser;
   }
}
处理多线程请求
/**
 * 网络请求线程池
 */
public class ThreadPoolManager {
   private ExecutorService service;

   private ThreadPoolManager() {
      int num = Runtime.getRuntime().availableProcessors();//系统cpu核心数
      service = Executors.newFixedThreadPool(num * 6);
   }

   private static final ThreadPoolManager manager = new ThreadPoolManager();

   public static ThreadPoolManager getInstance() {
      return manager;
   }

   public void addTask(Runnable runnable) {
      service.execute(runnable);
   }
}

/**
 * 
 * 网络请求管理类
 * Created by zhangzhenzhong on 15/12/5.
 */
public class RequstManager {
    private  final String TAG = "REqust_TAG";
    private Context mContext;
    private List<BaseTask> record = new Vector<BaseTask>();
    /**
     * 网络请求状态回调
     * @param <T>
     */
    public abstract interface DataCallback<T> {
        public abstract void onSucess(T paramObject, boolean paramBoolean);
        public abstract void onStart(Context context);
        public abstract void onFinished(Context context);
        public abstract void onFaild(Context context);
    }
    private ThreadPoolManager threadPoolManager;

    public RequstManager(){
        threadPoolManager = ThreadPoolManager.getInstance();
    }
    public  void getDataFromServer(Context context,RequestVo reqVo, DataCallback callBack) {
        this.mContext=context;
        if (!NetUtils.isNetworkAvailable(mContext)){
            JDToast.showText(mContext,"当前网络不可用,设置网络后重试");
            return ;
        }
        BaseHandler handler = new BaseHandler(callBack, reqVo);
        BaseTask taskThread = new BaseTask(reqVo, handler);
        record.add(taskThread);
        this.threadPoolManager.addTask(taskThread);
    }
    /**
     * @author Mathew
     */
    @SuppressWarnings("unchecked")
    public class BaseHandler extends Handler {
        private DataCallback callBack;
        private RequestVo reqVo;
        public BaseHandler(DataCallback callBack, RequestVo reqVo) {
            this.callBack = callBack;
            callBack.onStart(mContext);
            this.reqVo = reqVo;
        }
        public void handleMessage(Message msg) {
            if (msg.what == Constant.SUCCESS) {
                if (msg.obj == null) {
                    CommonUtil.showInfoDialog(mContext, mContext.getString(R.string.error_network));
                    callBack.onFaild(mContext);
                    callBack.onFinished(mContext);
                } else {
                    callBack.onSucess(msg.obj, true);
                }
            } else if (msg.what == Constant.NET_FAILED) {
                callBack.onFaild(mContext);
                callBack.onFinished(mContext);
                CommonUtil.showInfoDialog(mContext, mContext.getString(R.string.error_network));
            }
            callBack.onFinished(mContext);
//            Logger.d(TAG, "recordSize:" + record.size());
        }
    }
   public class BaseTask implements Runnable {
        private RequestVo reqVo;
        private Handler handler;
        public BaseTask(RequestVo reqVo, Handler handler) {
            this.reqVo = reqVo;
            this.handler = handler;
        }
        @Override
        public void run() {
            Object obj = null;
            Message msg = Message.obtain();
            try {
                if (NetUtil.hasNetwork(mContext)) {
                    /**
                     * post请求
                     */
                    obj = NetUtil.post(reqVo);
                    if (obj instanceof AsyncTask.Status) {
//                        Intent intent = new Intent(BaseWapperActivity.this, LoginActivity.class);
//                        intent.putExtra("notlogin", "notlogin");
//                        startActivityForResult(intent, NOT_LOGIN);
                    } else {
                        msg.what = Constant.SUCCESS;
                        msg.obj = obj;
                        handler.sendMessage(msg);
                        record.remove(this);
                    }
                } else {
                    msg.what = Constant.NET_FAILED;
                    msg.obj = obj;
                    handler.sendMessage(msg);
                    record.remove(this);
                }
            } catch (Exception e) {
                record.remove(this);
                throw new RuntimeException(e);
            }
        }
    }
}


/**
 * 网络请求调用
 * @param freshList
 */

  private void getList(final boolean freshList) {
        String type = YSListPageType.YS_JINGDU;
        RequestVo vo = new RequestVo();
        vo.requestUrl = Url.LISTPAGE_URL;
        vo.jsonParser = new ListPageParser();
        vo.context = mContext;
        HashMap map = new HashMap();
        map.put("currentPage", currPageIndex+"");
        map.put("type", type);
        vo.requestDataMap = map;
        RequstManager mRequstManager = new RequstManager();
        mRequstManager.getDataFromServer(mContext, vo, new RequstManager.DataCallback<List<ListpageItemBean>>() {
            @Override
            public void onSucess(List<ListpageItemBean> paramObject, boolean paramBoolean) {
                if (paramObject != null&&paramObject.size()!=0) {
                }
            }
            @Override
            public void onStart(Context context) {

            }
            @Override
            public void onFinished(Context context) {

            }
            @Override
            public void onFaild(Context context) {

            }
        });
    }

由于现在网络链接有多种方式如:HttpClient 和HttpUrlConnection等,这种处理是可以替换的这里以HttpClient为例,读者也可以换成自己的HttpURLConnection。只需要在

RequstManager 中替换即可。

/**
 * 网络连接基础类
 * @author Mathew
 */
public class NetUtil {
   private static final String NOT_LOGIN = "notlogin";
   private static final String TAG = "NetUtil";
   private static Header[] headers = new BasicHeader[11];
   static {
      UUID uuid=UUID.randomUUID();
      headers[0] = new BasicHeader("Appkey", "");
      headers[1] = new BasicHeader("Udid", uuid.toString());
      headers[2] = new BasicHeader("Os", "");
      headers[3] = new BasicHeader("Osversion", "");
      headers[4] = new BasicHeader("Appversion", "");
      headers[5] = new BasicHeader("Sourceid", "");
      headers[6] = new BasicHeader("Ver", "");
      headers[7] = new BasicHeader("Userid", "");
      headers[8] = new BasicHeader("Usersession", "");
      headers[9] = new BasicHeader("Unique", "");
      headers[10] = new BasicHeader("Cookie", "");

   }
   
   /*
    * 
    */
   public static Object post(RequestVo vo) {
      DefaultHttpClient client = new DefaultHttpClient();
      String url = vo.requestUrl;
      JDLog.d(TAG, "Post " + url);
      HttpPost post = new HttpPost(url);
      post.setHeaders(headers);
      Object obj = null;
      try {
         if (vo.requestDataMap != null) {
            HashMap<String, String> map = vo.requestDataMap;
            ArrayList<BasicNameValuePair> pairList = new ArrayList<BasicNameValuePair>();
            for (Map.Entry<String, String> entry : map.entrySet()) {
               BasicNameValuePair pair = new BasicNameValuePair(entry.getKey(), entry.getValue());
               pairList.add(pair);
            }
            HttpEntity entity = new UrlEncodedFormEntity(pairList, "UTF-8");
            post.setEntity(entity);
         }
         HttpResponse response = client.execute(post);
         if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
            setCookie(response);
            String result = EntityUtils.toString(response.getEntity(), "UTF-8");
            JDLog.d("JSONDATA",result);
            try {
               if (invilidateLogin(result)) {
                  return Status.Login;
               }
               obj = vo.jsonParser.parseJSON(result);
               JDLog.d("JSONParserObj",obj.toString());
            } catch (JSONException e) {
               JDLog.e(TAG, e.getLocalizedMessage(), e);
            }
            return obj;
         }
      } catch (ClientProtocolException e) {
         JDLog.e(TAG, e.getLocalizedMessage(), e);
      } catch (IOException e) {
         JDLog.e(TAG, e.getLocalizedMessage(), e);
      }
      return null;
   }

   /**
    * 添加Cookie
    * @param response
    */
   private static void setCookie(HttpResponse response) {
      if (response.getHeaders("Set-Cookie").length > 0) {
         JDLog.d(TAG, response.getHeaders("Set-Cookie")[0].getValue()) ;
         headers[10] = new BasicHeader("Cookie", response.getHeaders("Set-Cookie")[0].getValue());
      }
   }
   /**
    * 验证是否需要登录
    * @param result
    * @return
    * @throws JSONException
    */
   private static boolean invilidateLogin(String result) throws JSONException {
      JSONObject jsonObject = new JSONObject(result);
      String responseCode = jsonObject.getString("response");
      if (NOT_LOGIN.equals(responseCode)) {
         return true;
      }
      return false;
   }
   
   /**
    * 
    * @param vo
    * @return
    */
   public static Object get(RequestVo vo) {
      DefaultHttpClient client = new DefaultHttpClient();
      String url = vo.requestUrl;
      JDLog.d(TAG, "Get " + url);
      HttpGet get = new HttpGet(url);
      get.setHeaders(headers);
      Object obj = null;
      try {

         HttpResponse response = client.execute(get);
         if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
            setCookie(response);
            String result = EntityUtils.toString(response.getEntity(), "UTF-8");
            JDLog.d(TAG, result);
            try {
               if (invilidateLogin(result)) {
                  return Status.Login;
               }
               JDLog.w("JSONresult",result);
               obj = vo.jsonParser.parseJSON(result);
            } catch (JSONException e) {
               JDLog.e(TAG, e.getLocalizedMessage(), e);
            }
            return obj;
         }
      } catch (ClientProtocolException e) {
         e.printStackTrace();
      } catch (IOException e) {
         e.printStackTrace();
      }
      return null;
   }

   /**
    * 获得网络连接是否可用
    * 
    * @param context
    * @return
    */
   public static boolean hasNetwork(Context context) {
      ConnectivityManager con = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
      NetworkInfo workinfo = con.getActiveNetworkInfo();
      if (workinfo == null || !workinfo.isAvailable()) {
         Toast.makeText(context, R.string.error_network, Toast.LENGTH_SHORT).show();
         return false;
      }
      return true;
   }
   
   public enum Status {
      Login,Logout,singin;
   }
}

以上已经是一个比较完整的简单的网络请求流程了,当然正如开始时说的,还有很多优化点要加。满足基本核心的网络请求是已经够了。



待续。。。



简介: 本框架是在Netroid的基础之上进行了封装,节省了其中配置的过程和一些不必要的操作 主要进行文本请求和图片请求,图片请求都进行了缓存(内存缓存和sd卡缓存)的封装,sd卡缓存时间可自行更改. 文本请求可传入解析的泛型clazz,即可返回解析后的clazz对象进行数据 操作,如果不需要进行数据解析,可通过另一种方式获取原生的string; 单图请求,单图请求可执行对本地asset文件夹,sd卡,http三种请求模式.只需传入相应的路径即可; 多图请求,多图请求主要是针对listview这种图文混排模式而生,能快速加载图片并实现缓存,不需要考虑 图片错位问题.只需传入相应的url即可完成全部功能. 使用说明: 1:在新创建的Manifest.xml中application中申明: <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" android:name="com.aqs.application.UApplication" > 并初始化Const.init();此处的初始化主要是对内存缓存,SD卡缓存大小,缓存时间等进行设置,如果不初始化,则按使用默认配置; 2:依赖HttpAqs-library或者jar包 3:通过公有方法进行网络请求,示例如下: >文本请求: >解析后的文本请求: HttpRequest.reqquest(int,String,Parse,Class){....}; >原生string文本请求: HttpRequest.getString(String,AqsString){...} >单张图片请求: HttpRequest.setImage(ImageView,String,int,int){...} >多张图片请求: 可使用AQSImageView控件来加载图片;特别是针对listview图文混排 实现方法: >在布局中添加 >在代码中 av.setImageUrl(url);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值