Android 网络请求-AsyncHttpClient封装(超详细版)

前言

最近捣鼓android,但学习不多,索性完全把android当前端玩了,然后自己写了个后端服务,所以这个中间过程就需要网络请求,找了个三方库,即AsyncHttpClient,下面就是自己简单的封装了下getpost方法,这两个也够我目前业务开发了。

如果想看下代码的可以按照顺序慢慢看,如果有不喜欢看代码,就喜欢直接复制粘贴的,也可以直接点目录,倒数第二个大标题《完整代码》,添加文件,复制代码,然后目录最后一个《外部使用》简单看下实现效果模仿者来就好了。

1、为项目添加网络权限

打开项目清单文件,添加如下两行代码即可,有权限才能开网络请求嘛。

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

在这里插入图片描述

2、新建一个Axios.java文件,写入如下代码

文件名其实是由于之前搞前端习惯用axios库,也是个非常优秀的请求库;代码的相关注释我已写好,其中主要分为几个部分:

  • 基本配置(请求地址、超时时间,合法状态码)
  • get和post方法的实现
  • 加载提示(请求前、请求结束后)
  • 请求反馈(回调)

2.1先看基本配置吧

这个其实没什么太多说的,光看注释应该是看的懂的

private Context context; // 上下文,用来给弹框反馈提示用的
private AsyncHttpClient asyncHttpClient; // asyncHttpClient对象
private ProgressDialog waitingDialog = null; // 弹框对象
private String dialogTitle = "", dialogMsg = ""; // 弹框标题和内容
private static String baseURL = "http://xxxx:5000"; // 请求地址
private static int ConnectTimeOut = 5000; // 超时时间
private CallBackFun callBackFun; // 回调接口

2.2 get和post的实现

get:
注意:这里我是没有在方法中体现携带方法的,要携带参数一般是直接拼在url后面,或者你可以看看post的实现。
还有,你可能会看到两个失败的回调的实现,之所以是两个,是因为这个请求的错误有可能有很多情况,有可能400、有可能500,也有可能是网络没打开等等原因,但我业务又不是很复杂,所以没有深究,就把两种实现都写上去,提示下用户就好了。

public void get(String url) {

        String requsetUrl = baseURL + url; // 完整链接

        if (this.asyncHttpClient != null) {

            try {

                showLoading(); // 弹框加载

                this.asyncHttpClient.get(requsetUrl, new JsonHttpResponseHandler() { // 实现AsyncHttpClient的响应

                    @SuppressLint("DefaultLocale")
                    @Override
                    public void onSuccess(int statusCode, Header[] headers, org.json.JSONObject response) { // 实现成功的回调
                        super.onSuccess(statusCode, headers, response);
                        stopLoading(); // 停止加载
                        try {

                            if (!Axios.isValidCode(Integer.parseInt(response.getString("Tag")))) { // 校验一下后端的给的code是不是合法的,注意这不是http的code,而是业务自己设定的
                                Toast.makeText(context, response.getString("Message"), Toast.LENGTH_SHORT).show();
                            } else {
                                callBackFun.onAxiosSuccess(response); // 调用外部给的成功回调方法
                            }

                        } catch (JSONException e) {
                            e.printStackTrace();
                        }

                    }


                    @SuppressLint("DefaultLocale")
                    @Override
                    public void onFailure(int statusCode, Header[] headers, Throwable throwable, org.json.JSONObject errorResponse) { // 实现失败的回调
                        super.onFailure(statusCode, headers, throwable, errorResponse);
                        callBackFun.onAxiosFailure(errorResponse); // 调用外部失败的回调方法
                        stopLoading(); // 停止加载

                        if (errorResponse == null) {
                            Toast.makeText(context, R.string.fail + ":网络", Toast.LENGTH_SHORT).show();
                            return;
                        }

                        try {
                            Toast.makeText(context, errorResponse.getString("reason"), Toast.LENGTH_SHORT).show();
                        } catch (JSONException e) {

                            e.printStackTrace();

                        }


                    }


                    @Override

                    public void onFailure(int statusCode, Header[] headers, String responseString, Throwable throwable) { // 实现失败的回调
                        super.onFailure(statusCode, headers, responseString, throwable);
                        callBackFun.onAxiosFailure(responseString); // 调用外部失败的回调方法
                        stopLoading(); // 停止加载

                        Toast.makeText(context, R.string.fail + responseString, Toast.LENGTH_SHORT).show();
                    }
                });
            } catch (Exception e) {
                e.printStackTrace();
                stopLoading();
            }

        }

    }

post:
这里注意的地方到没什么,就是携带参数那里,我设置了用json格式发送的。

    public void post(String url, RequestParams requestParams) {
        requestParams.setUseJsonStreamer(true); // 代表是用json格式携带进body里面,即Mime-Type为application/json
        String requsetUrl = baseURL + url; //请求完整地址

        if (this.asyncHttpClient != null) {

            try {

                showLoading(); // 弹框加载
                this.asyncHttpClient.post(requsetUrl, requestParams, new JsonHttpResponseHandler() {

                    @SuppressLint("DefaultLocale")
                    @Override
                    public void onSuccess(int statusCode, Header[] headers, org.json.JSONObject response) {
                        super.onSuccess(statusCode, headers, response);
                        stopLoading();
                        try {
                            if (!Axios.isValidCode(Integer.parseInt(response.getString("Tag")))) { // 校验一下后端的给的code是不是合法的,注意这不是http的code,而是业务自己设定的
                                Toast.makeText(context, response.getString("Message"), Toast.LENGTH_SHORT).show();
                            } else {
                                callBackFun.onAxiosSuccess(response); // 调用外部的成功回调方法
                            }

                        } catch (JSONException e) {
                            e.printStackTrace();
                        }

                    }

                    @SuppressLint("DefaultLocale")
                    @Override
                    public void onFailure(int statusCode, Header[] headers, Throwable throwable, org.json.JSONObject errorResponse) {

                        super.onFailure(statusCode, headers, throwable, errorResponse);
                        callBackFun.onAxiosFailure(errorResponse); // 调用外部失败的回调方法
                        stopLoading();
                        if (errorResponse == null) {

                            Toast.makeText(context, R.string.fail, Toast.LENGTH_SHORT).show();

                            return;
                        }
                        try {

                            Toast.makeText(context, errorResponse.getString("reason"), Toast.LENGTH_SHORT).show();

                        } catch (JSONException e) {

                            e.printStackTrace();

                        }
                    }


                    @Override

                    public void onFailure(int statusCode, Header[] headers, String responseString, Throwable throwable) {

                        super.onFailure(statusCode, headers, responseString, throwable);
                        callBackFun.onAxiosFailure(responseString);
                        stopLoading();

                        Toast.makeText(context, R.string.fail, Toast.LENGTH_SHORT).show();

                    }

                });

            } catch (Exception e) {
                e.printStackTrace();
                stopLoading();
            }

        }

    }

2.3回调实现

这里代码其实很简单,其实就是自己多琢磨琢磨就好了,没啥技巧,因为回调不管是前端还是后端,应用场景大多都是异步操作,等异步操作完了再干嘛干嘛。

public interface CallBackFun { // 外部用的回调接口

        public void onAxiosSuccess(org.json.JSONObject obj);

        public void onAxiosFailure(Object obj);

    }


    public void setOnCallBack(CallBackFun callBackFun) { // 为该对象添加回调接口

        this.callBackFun = callBackFun;

    }

完整代码

package com.xlzn.hcpda.uhf.ui;

import android.annotation.SuppressLint;
import android.app.ProgressDialog;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.widget.Toast;

import com.alibaba.fastjson.JSONObject;
import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.JsonHttpResponseHandler;
import com.loopj.android.http.RequestParams;
import com.xlzn.hcpda.uhf.R;

import org.json.JSONException;

import cz.msebera.android.httpclient.Header;


public class Axios {

    private Context context; // 上下文,用来给弹框反馈提示用的
    private AsyncHttpClient asyncHttpClient; // asyncHttpClient对象
    private ProgressDialog waitingDialog = null; // 弹框对象
    private String dialogTitle = "", dialogMsg = ""; // 弹框标题和内容
    private static String baseURL = "http://xxxx:5000"; // 请求地址
    private static int ConnectTimeOut = 5000; // 超时时间
    private CallBackFun callBackFun; // 回调接口


    public Axios(Context context) { // 初始化
        this.context = context;
        this.dialogTitle = context.getString(R.string.dialog_title);
        this.dialogMsg = context.getString(R.string.dialog_loading_msg);
        AsyncHttpClient client = new AsyncHttpClient();
        client.setTimeout(Axios.ConnectTimeOut);
        this.asyncHttpClient = client;

    }


    public void setDialogTitle(String dialogTitle) { // 设置加载框的标题,用来给外部用的

        this.dialogTitle = dialogTitle;

    }


    public void setDialogMsg(String dialogMsg) { // 设置加载框的内容,用来给外部用的

        this.dialogMsg = dialogMsg;

    }


    /*
     * 没太大用,把对象实例返回出去而已,
     * 之前想着是用来外部判断网络连接没有,
     * 但是后面发现,其实如果没有网路连接的话,
     * 其实会进入 AsyncHttpClient 里面失败的回调,
     * 相当于是别人内部以及做了处理了
     * */
    public AsyncHttpClient getAsyncHttpClient() {

        if (!this.isNetConnection()) {

            Toast.makeText(context, R.string.net_error, Toast.LENGTH_SHORT).show();

            return null;

        }

        return asyncHttpClient;

    }


    private boolean isNetConnection() { // 判断是否有网络连接 包括wifi和数据流量

        if (this.context != null) {

            ConnectivityManager connectivityManager = (ConnectivityManager) this.context.getSystemService(Context.CONNECTIVITY_SERVICE);

            NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();

            if (networkInfo != null && networkInfo.isConnected()) {

                return networkInfo.getState() == NetworkInfo.State.CONNECTED;

            }

        }

        return false;

    }


    private void showLoading() {

        if (this.waitingDialog == null) {
            this.waitingDialog = new ProgressDialog(this.context);
            this.waitingDialog.setTitle(dialogTitle);
            this.waitingDialog.setMessage(dialogMsg);
            this.waitingDialog.setIndeterminate(true);
            this.waitingDialog.setCancelable(false);
        }

        this.waitingDialog.show();
    }


    private void stopLoading() {

        if (this.waitingDialog != null) this.waitingDialog.cancel();

    }


    public static boolean isValidCode(int code) {
        return code == 1;
    }


    public void get(String url) {

        String requsetUrl = baseURL + url; // 完整链接

        if (this.asyncHttpClient != null) {

            try {

                showLoading(); // 弹框加载

                this.asyncHttpClient.get(requsetUrl, new JsonHttpResponseHandler() { // 实现AsyncHttpClient的响应

                    @SuppressLint("DefaultLocale")
                    @Override
                    public void onSuccess(int statusCode, Header[] headers, org.json.JSONObject response) { // 实现成功的回调
                        super.onSuccess(statusCode, headers, response);
                        stopLoading(); // 停止加载
                        try {

                            if (!Axios.isValidCode(Integer.parseInt(response.getString("Tag")))) { // 校验一下后端的给的code是不是合法的,注意这不是http的code,而是业务自己设定的
                                Toast.makeText(context, response.getString("Message"), Toast.LENGTH_SHORT).show();
                            } else {
                                callBackFun.onAxiosSuccess(response); // 调用外部给的成功回调方法
                            }

                        } catch (JSONException e) {
                            e.printStackTrace();
                        }

                    }


                    @SuppressLint("DefaultLocale")
                    @Override
                    public void onFailure(int statusCode, Header[] headers, Throwable throwable, org.json.JSONObject errorResponse) { // 实现失败的回调
                        super.onFailure(statusCode, headers, throwable, errorResponse);
                        callBackFun.onAxiosFailure(errorResponse); // 调用外部失败的回调方法
                        stopLoading(); // 停止加载

                        if (errorResponse == null) {
                            Toast.makeText(context, R.string.fail + ":网络", Toast.LENGTH_SHORT).show();
                            return;
                        }

                        try {
                            Toast.makeText(context, errorResponse.getString("reason"), Toast.LENGTH_SHORT).show();
                        } catch (JSONException e) {

                            e.printStackTrace();

                        }


                    }


                    @Override

                    public void onFailure(int statusCode, Header[] headers, String responseString, Throwable throwable) { // 实现失败的回调
                        super.onFailure(statusCode, headers, responseString, throwable);
                        callBackFun.onAxiosFailure(responseString); // 调用外部失败的回调方法
                        stopLoading(); // 停止加载

                        Toast.makeText(context, R.string.fail + responseString, Toast.LENGTH_SHORT).show();

                    }

                });

            } catch (Exception e) {

                e.printStackTrace();

                stopLoading();

            }

        }

    }


    public void post(String url, RequestParams requestParams) {
        requestParams.setUseJsonStreamer(true); // 代表是用json格式携带进body里面,即Mime-Type为application/json
        String requsetUrl = baseURL + url; //请求完整地址

        if (this.asyncHttpClient != null) {

            try {

                showLoading(); // 弹框加载
                this.asyncHttpClient.post(requsetUrl, requestParams, new JsonHttpResponseHandler() {

                    @SuppressLint("DefaultLocale")
                    @Override
                    public void onSuccess(int statusCode, Header[] headers, org.json.JSONObject response) {
                        super.onSuccess(statusCode, headers, response);
                        stopLoading();
                        try {
                            if (!Axios.isValidCode(Integer.parseInt(response.getString("Tag")))) { // 校验一下后端的给的code是不是合法的,注意这不是http的code,而是业务自己设定的
                                Toast.makeText(context, response.getString("Message"), Toast.LENGTH_SHORT).show();
                            } else {
                                callBackFun.onAxiosSuccess(response); // 调用外部的成功回调方法
                            }

                        } catch (JSONException e) {
                            e.printStackTrace();
                        }

                    }


                    @SuppressLint("DefaultLocale")
                    @Override
                    public void onFailure(int statusCode, Header[] headers, Throwable throwable, org.json.JSONObject errorResponse) {

                        super.onFailure(statusCode, headers, throwable, errorResponse);
                        callBackFun.onAxiosFailure(errorResponse); // 调用外部失败的回调方法
                        stopLoading();

                        if (errorResponse == null) {

                            Toast.makeText(context, R.string.fail, Toast.LENGTH_SHORT).show();

                            return;

                        }
                        try {

                            Toast.makeText(context, errorResponse.getString("reason"), Toast.LENGTH_SHORT).show();

                        } catch (JSONException e) {

                            e.printStackTrace();

                        }


                    }


                    @Override

                    public void onFailure(int statusCode, Header[] headers, String responseString, Throwable throwable) {

                        super.onFailure(statusCode, headers, responseString, throwable);
                        callBackFun.onAxiosFailure(responseString);
                        stopLoading();

                        Toast.makeText(context, R.string.fail, Toast.LENGTH_SHORT).show();

                    }

                });

            } catch (Exception e) {

                e.printStackTrace();

                stopLoading();

            }

        }

    }


    public interface CallBackFun { // 外部用的回调接口

        public void onAxiosSuccess(org.json.JSONObject obj);

        public void onAxiosFailure(Object obj);

    }


    public void setOnCallBack(CallBackFun callBackFun) { // 为该对象添加回调接口

        this.callBackFun = callBackFun;

    }

}

外部使用

Axios axios = new Axios(mainActivity);

axios.setOnCallBack(new Axios.CallBackFun() {
    @Override
     public void onAxiosSuccess(org.json.JSONObject obj) {
         Toast.makeText(mainActivity, "请求成功", Toast.LENGTH_SHORT).show();
     }

     @Override
     public void onAxiosFailure(Object obj) {
         Toast.makeText(mainActivity,"请求失败", Toast.LENGTH_SHORT).show();
     }
 });

RequestParams requestParams = new RequestParams();
requestParams.put("name", "张三");
requestParams.put("age", 18);

axios.post("/xxx/yyy",requestParams); // post携带参数

axios.get("/aaa/bbb?id=1"); // get携带参数

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android网络请求封装可以通过以下步骤实现: 1. 在AndroidManifest.xml文件中添加网络权限,以确保应用程序可以进行网络请求。可以在<manifest>标签内添加以下代码: <uses-permission android:name="android.permission.INTERNET"/> \[1\] 2. 定义一个网络请求回调接口,用于处理请求成功和失败的回调方法。可以创建一个接口,并在接口中定义onSuccess和onFailure方法,如下所示: public interface CallBackLis<T> { void onSuccess(String method, T content); void onFailure(String method, String error); } \[2\] 3. 在Activity或Fragment中调用网络请求方法。可以使用HttpRequest类中的静态方法来发送网络请求,并传入回调接口的实例作为参数。例如: HttpRequest.login(activity, new CallBackLis<具体data类型>() { @Override public void onSuccess(String method, 具体data类型 content) { // 在这里处理请求成功后的逻辑,content为我们需要的数据 } @Override public void onFailure(String method, String error) { // 在这里处理请求失败后的逻辑,error为错误信息 toast(error); } }); \[3\] 通过以上步骤,可以实现Android网络请求封装,使得网络请求的调用更加简洁和方便。 #### 引用[.reference_title] - *1* [初学Android网络封装](https://blog.csdn.net/weixin_43993331/article/details/122151795)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [Android 网络请求封装(Retrofit+OkHttp+RxJava+AutoDispose),解决网络请求引起的内存泄漏](https://blog.csdn.net/u013624014/article/details/122000289)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值