Okhttp3

    1. 簡(jiǎn)介
    1.支持http和https協(xié)議,api相同,易用; 
    2.http使用線(xiàn)程池,https使用多路復(fù)用;
    3.okhttp支持同步和異步調(diào)用; 
    4.支持普通form和文件上傳form; 
    5.操作請(qǐng)求和響應(yīng)(日志,請(qǐng)求頭,body等); 
    6.okhttp可以設(shè)置緩存;
    7.支持透明的gzip壓縮響應(yīng)體
    1. 配置
    implementation 'com.squareup.okhttp3:okhttp:3.10.0'//okhttp3
    <uses-permission android name = "android.permission.INTERNET"/>
    1. 請(qǐng)求思路
get請(qǐng)求思路
  1.獲取okHttpClient對(duì)象
  2.構(gòu)建Request對(duì)象
  3.構(gòu)建Call對(duì)象
  4.通過(guò)Call.enqueue(callback)方法來(lái)提交異步請(qǐng)求;execute()方法實(shí)現(xiàn)同步請(qǐng)求
post請(qǐng)求思路
  1.獲取okHttpClient對(duì)象
  2.創(chuàng)建RequestBody
  3.構(gòu)建Request對(duì)象
  4.構(gòu)建Call對(duì)象
  5.通過(guò)Call.enqueue(callback)方法來(lái)提交異步請(qǐng)求;execute()方法實(shí)現(xiàn)同步請(qǐng)求
    1. get,post 同步和異步請(qǐng)求

異步請(qǐng)求(get)

        String url = "http://";

        //第一步獲取okHttpClient對(duì)象
        OkHttpClient client = new OkHttpClient.Builder()
                .build();
        //第二步構(gòu)建Request對(duì)象
        Request request = new Request.Builder()
                .url(url)
                .get()
                .build();
        //第三步構(gòu)建Call對(duì)象
        Call call = client.newCall(request);
        //第四步:異步get請(qǐng)求
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.i("onFailure", e.getMessage());
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                    String result = response.body().string();
                    // 數(shù)據(jù)刷新必須在主線(xiàn)程中
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(MainActivity.this, result , Toast.LENGTH_SHORT).show();
                        }
                    });

                Log.i("result", result);
            }
        });

同步請(qǐng)求(get)

        String url = "http://";

        //第一步獲取okHttpClient對(duì)象
        OkHttpClient client = new OkHttpClient.Builder()
                .build();
        //第二步構(gòu)建Request對(duì)象
        Request request = new Request.Builder()
                .url(url)
                .get()
                .build();
        //第三步構(gòu)建Call對(duì)象
        final Call call = client.newCall(request);
        //第四步:同步get請(qǐng)求
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Response response = call.execute();//必須子線(xiàn)程執(zhí)行
                    String result = response.body().string();
                    Log.i("response", result);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();

異步請(qǐng)求(post)

        //接口參數(shù) String username,String password

        String url = "http://";
        //第一步創(chuàng)建OKHttpClient
        OkHttpClient client = new OkHttpClient.Builder()
                .build();
        //第二步創(chuàng)建RequestBody(Form表達(dá))
        RequestBody body = new FormBody.Builder()
                .add("username", "admin")
                .add("password", "123456")
                .build();
        //第三步創(chuàng)建Rquest
        Request request = new Request.Builder()
                .url(url)
                .post(body)
                .build();
        //第四步創(chuàng)建call回調(diào)對(duì)象
        final Call call = client.newCall(request);
        //第五步發(fā)起請(qǐng)求
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.i("onFailure", e.getMessage());
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                String result = response.body().string();
                Log.i("result", result);
            }
        });

同步請(qǐng)求(post)

        //接口參數(shù) String username,String password

        String url = "http://";
        //第一步創(chuàng)建OKHttpClient
        OkHttpClient client = new OkHttpClient.Builder()
                .build();
        //第二步創(chuàng)建RequestBody
        RequestBody body = new FormBody.Builder()
                .add("username", "admin")
                .add("password", "123456")
                .build();
        //第三步創(chuàng)建Rquest
        Request request = new Request.Builder()
                .url(url)
                .post(body)
                .build();
        //第四步創(chuàng)建call回調(diào)對(duì)象
        final Call call = client.newCall(request);
        //第五步發(fā)起請(qǐng)求
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Response response = call.execute();
                    String result = response.body().string();
                    Log.i("response", result);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start(); 
  • 5.請(qǐng)求頭處理(Header)以及超時(shí)和緩沖處理以及響應(yīng)處理
        //超時(shí)設(shè)置
        OkHttpClient client = new OkHttpClient.Builder()
                .connectTimeout(5,TimeUnit.SECONDS)
                .readTimeout(5,TimeUnit.SECONDS)
                .writeTimeout(5,TimeUnit.SECONDS)
                .cache(new Cache(cacheDirectory,10*1024*1024))
                .build();

        //表單提交
        RequestBody requestBody = new FormBody.Builder()
                .add("pno", "1")
                .add("ps","50")
                .add("dtype","son")
                .add("key","4a7cf244fd7efbd17ecbf0cb8e4d1c85")
                .build();

        //請(qǐng)求頭設(shè)置
        Request request = new Request.Builder()
                .url(url)
                .addHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8")
                .header("User-Agent", "OkHttp Example")
                .post(body)
                .build();
      
        //響應(yīng)處理
        @Override
        public void onResponse(Call call, Response response) throws IOException {
            //響應(yīng)行
            Log.d("ok", response.protocol() + " " +response.code() + " " + response.message());
            //響應(yīng)頭
            Headers headers = response.headers();
            for (int i = 0; i < headers.size(); i++) {
                Log.d("ok", headers.name(i) + ":" + headers.value(i));
            }
            //響應(yīng)體
            final String string = response.body().string();

            Log.d("ok", "onResponse: " + string);
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    tx.setText(string);
                }
            });
        }

  • 6.請(qǐng)求體處理(Form表單,String字符串,流,文件)
        //1.POST方式提交String/JSON    application/json;json串
        MediaType mediaType1 = MediaType.parse("application/x-www-form-urlencoded;charset=utf-8");
        String requestBody = "pno=1&ps=50&dtype=son&key=4a7cf244fd7efbd17ecbf0cb8e4d1c85";
        RequestBody requestBody1 = RequestBody.create(mediaType1, requestBody);

        //POST方式提交JSON:傳遞JSON同時(shí)設(shè)置son類(lèi)型頭
        RequestBody requestBodyJson = RequestBody.create(MediaType.parse("application/json;charset=utf-8"), "{}");
        request.addHeader("Content-Type", "application/json")//必須加json類(lèi)型頭
            
        //POST方式提交無(wú)參
        RequestBody requestBody1 = RequestBody.create(MediaType.parse("application/x-www-form-urlencoded;charset=utf-8"), "");


        //2.POST方式提交流
        RequestBody requestBody2 = new RequestBody() {
            @Nullable
            @Override
            public MediaType contentType() {
                return MediaType.parse("application/x-www-form-urlencoded;charset=utf-8");
            }

            @Override
            public void writeTo(BufferedSink sink) throws IOException {
                sink.writeUtf8("pno=1&ps=50&dtype=son&key=4a7cf244fd7efbd17ecbf0cb8e4d1c85");
            }
        };

       //3.POST方式提交表單
        RequestBody requestBody4 = new FormBody.Builder()
                .add("pno", "1")
                .add("ps","50")
                .add("dtype","son")
                .add("key","4a7cf244fd7efbd17ecbf0cb8e4d1c85")
                .build();

        //4.POST提交文件
        MediaType mediaType3 = MediaType.parse("text/x-markdown; charset=utf-8");
        File file = new File("test.txt");
        RequestBody requestBody3 = RequestBody.create(mediaType3, file);

        //5.POST方式提交分塊請(qǐng)求
        MultipartBody body = new MultipartBody.Builder("AaB03x")
                .setType(MultipartBody.FORM)
                .addPart(
                        Headers.of("Content-Disposition", "form-data; name=\"title\""),
                        RequestBody.create(null, "Square Logo"))
                .addPart(
                        Headers.of("Content-Disposition", "form-data; name=\"image\""),
                        RequestBody.create(MediaType.parse("image/png"), new File("website/static/logo-square.png")))
                .build();
  • 7.攔截器(interator)
RetryAndFollowUp Intercaptors
Bridge interceptors
Cache interceptors
Connect interceptors
Callserver Intercaptors

一個(gè)完整的異步請(qǐng)求,主要有以下幾點(diǎn):new okhttpclient new Request(),通過(guò)client.newCall,傳入request請(qǐng)求對(duì)象且返回一個(gè)Call對(duì)象,執(zhí)行call.enqueue()來(lái)實(shí)現(xiàn)一個(gè)完整的請(qǐng)求邏輯。主要涉及幾點(diǎn):
1.構(gòu)建okhttpclient對(duì)象的時(shí)候,會(huì)new Dispatcher()對(duì)象,Dispatcher主要用于維護(hù)同步和異步請(qǐng)求的狀態(tài)。并維護(hù)一個(gè)線(xiàn)程池,有三個(gè)集合,一個(gè)異步等待集合,一個(gè)異步運(yùn)行集合,一個(gè)是同步運(yùn)行集合。
2.RealCall 對(duì)call接口的實(shí)現(xiàn)類(lèi),封裝了請(qǐng)求服務(wù)器的數(shù)據(jù)和配置項(xiàng)目,同時(shí)處理執(zhí)行具體同步和異步的操作。
3.interceptors 攔截器,一個(gè)完整的請(qǐng)求會(huì)依次執(zhí)行以下幾個(gè)攔截器,最終返回結(jié)果。
RetryAndFollowUpIntercaptors 重試和重定向攔截器
Bridgeinterceptors 橋接攔截器
Cacheinterceptors 緩存攔截器
Connectinterceptors 鏈接攔截器
CallserverIntercaptors 請(qǐng)求服務(wù)攔截器

4.其它攔截器

Application interceptors 應(yīng)用攔截器
Network Interceptors 網(wǎng)絡(luò)攔截器
Logging Interceptor 日志攔截器
一、Application Intercetor和NetworkInterceptor的區(qū)別

1,Application interceptors 應(yīng)用攔截器

builder.addInterceptor(new LoggingInterceptor())

Application Interceptor 是第一個(gè) Interceptor 因此它會(huì)被第一個(gè)執(zhí)行,因此這里的 request 還是最原始的。而對(duì)于 response 而言呢,因?yàn)檎麄€(gè)過(guò)程是遞歸的調(diào)用過(guò)程,因此它會(huì)在 CallServerInterceptor 執(zhí)行完畢之后才會(huì)將 Response 進(jìn)行返回,因此在 Application Interceptor 這里得到的 response 就是最終的響應(yīng),雖然中間有重定向,但是這里只關(guān)心最終的 response

1,不需要去關(guān)心中發(fā)生的重定向和重試操作。因?yàn)樗幱诘谝粋€(gè)攔截器,會(huì)獲取到最終的響應(yīng) 
2,只會(huì)被調(diào)用一次,即使這個(gè)響應(yīng)是從緩存中獲取的。
3,只關(guān)注最原始的請(qǐng)求,不去關(guān)系請(qǐng)求的資源是否發(fā)生了改變,我只關(guān)注最后的 response 結(jié)果而已。
4,因?yàn)槭堑谝粋€(gè)被執(zhí)行的攔截器,因此它有權(quán)決定了是否要調(diào)用其他攔截,也就是 Chain.proceed() 方法是否要被執(zhí)行。
5,因?yàn)槭堑谝粋€(gè)被執(zhí)行的攔截器,因此它有可以多次調(diào)用 Chain.proceed() 方法,其實(shí)也就是相當(dāng)與重新請(qǐng)求的作用了。

2,Network Interceptors 網(wǎng)絡(luò)攔截器

builder.addNetworkInterceptor(new LoggingInterceptor())

NetwrokInterceptor 處于第 6 個(gè)攔截器中,它會(huì)經(jīng)過(guò) RetryAndFollowIntercptor 進(jìn)行重定向并且也會(huì)通過(guò) BridgeInterceptor 進(jìn)行 request 請(qǐng)求頭和 響應(yīng) resposne 的處理,因此這里可以得到的是更多的信息。在打印結(jié)果可以看到它內(nèi)部是發(fā)生了一次重定向操作,在上圖可以看出,為什么 NetworkInterceptor 可以比 Application Interceptor 得到更多的信息了

1,因?yàn)?NetworkInterceptor 是排在第 6 個(gè)攔截器中,因此可以操作經(jīng)過(guò) RetryAndFollowup 進(jìn)行失敗重試或者重定向之后得到的resposne。
2,對(duì)于從緩存獲取的 response 則不會(huì)去觸發(fā) NetworkInterceptor 。因?yàn)轫憫?yīng)直接從 CacheInterceptor 返回了。
3,觀(guān)察數(shù)據(jù)在網(wǎng)絡(luò)中的傳輸。
4,可以獲得裝載請(qǐng)求的連接。
二、攔截器的應(yīng)用

1.日志攔截器

在 LoggingInterceptor 中主要做了 3 件事:
1,請(qǐng)求前-打印請(qǐng)求信息;
2,網(wǎng)絡(luò)請(qǐng)求-遞歸去調(diào)用其他攔截器發(fā)生網(wǎng)絡(luò)請(qǐng)求;
3,網(wǎng)絡(luò)響應(yīng)后-打印響應(yīng)信息

OkHttpClient client = builder
            .addInterceptor(new LoggingInterceptor())//應(yīng)用攔截器
            .addNetworkInterceptor(new LoggingInterceptor())//網(wǎng)絡(luò)攔截器
            .readTimeout(5, TimeUnit.SECONDS)
            .connectTimeout(5, TimeUnit.SECONDS)
            .writeTimeout(5, TimeUnit.SECONDS)
            .build();

class LoggingInterceptor implements Interceptor {

    private static final String TAG = "LoggingInterceptor";

    @Override
    public Response intercept(Chain chain) throws IOException {

        Request request = chain.request();

        //1.請(qǐng)求前--打印請(qǐng)求信息
        long startTime = System.nanoTime();
        Log.d(TAG, String.format("Sending request %s on %s%n%s",
                request.url(), chain.connection(), request.headers()));

        //2.網(wǎng)絡(luò)請(qǐng)求
        Response response =  chain.proceed(request);

        //3.網(wǎng)絡(luò)響應(yīng)后--打印響應(yīng)信息
        long endTime = System.nanoTime();
        Log.d(TAG, String.format("Received response for %s in %.1fms%n%s",
                response.request().url(), (endTime - startTime) / 1e6d, response.headers()));

        return response;
    }
}

2.緩存攔截器

在 MyCacheinterceptor 中主要做了(post方式無(wú)法緩存)
1,設(shè)置緩存位置
2,無(wú)網(wǎng)時(shí):設(shè)置緩存協(xié)議
3,有網(wǎng):加載網(wǎng)絡(luò)數(shù)據(jù);無(wú)網(wǎng):加載緩存數(shù)據(jù)

OkHttpClient okHttpClient = new OkHttpClient.Builder()
            .addInterceptor(myCacheinterceptor)//應(yīng)用攔截器
            .addNetworkInterceptor(myCacheinterceptor)//網(wǎng)絡(luò)攔截器
            .connectTimeout(5, TimeUnit.SECONDS)
            .cache(new Cache(new File(getCacheDir(), "Cache"), 1024 * 1024 * 10))
            .build();

class MyCacheinterceptor implements Interceptor {
    @Override
    public Response intercept(Chain chain) throws IOException {

        Request request = chain.request();

        if (!isNetworkAvailable(MainActivity.this)) {
            request = request.newBuilder().cacheControl(CacheControl.FORCE_CACHE).build();

        }

        Response originalResponse = chain.proceed(request);

        if (isNetworkAvailable(MainActivity.this)) {
            int maxAge = 0;
            return originalResponse.newBuilder()
                    .removeHeader("Pragma")
                    .header("Cache-Control", "public ,max-age=" + maxAge)
                    .build();
        } else {
            int maxStale = 15*60;
            return originalResponse.newBuilder()
                    .removeHeader("Pragma")
                    .header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
                    .build();
        }

    }
}

/**
    檢測(cè)是否有網(wǎng)
 */
public static boolean isNetworkAvailable(Context context) {
    if (context != null) {
        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo info = cm.getActiveNetworkInfo();
        if (info != null) {
            return info.isAvailable();
        }
    }
    return false;
}
  • 8 .注意事項(xiàng)
1,推薦讓 OkHttpClient 保持單例,用同一個(gè) OkHttpClient 實(shí)例來(lái)執(zhí)行你的所有請(qǐng)求,因?yàn)槊恳粋€(gè) OkHttpClient 實(shí)例都擁有自己的連接池和線(xiàn)程池,重用這些資源可以減少延時(shí)和節(jié)省資源,如果為每個(gè)請(qǐng)求創(chuàng)建一個(gè) OkHttpClient 實(shí)例,顯然就是一種資源的浪費(fèi)。

2,response.body().string()只調(diào)用一次

3,每一個(gè)Call(其實(shí)現(xiàn)是RealCall)只能執(zhí)行一次,否則會(huì)報(bào)異常

4,子線(xiàn)程加載數(shù)據(jù)后,主線(xiàn)程刷新數(shù)據(jù)
  • 9 .HttpUrlCollection 及 Okhttp3 的對(duì)比分析
1,HttpUrlConnection,google官方提供的用來(lái)訪(fǎng)問(wèn)網(wǎng)絡(luò),但是實(shí)現(xiàn)的比較簡(jiǎn)單,只支持1.0/1.1
2,并沒(méi)有多路復(fù)用,如果碰到app大量網(wǎng)絡(luò)請(qǐng)求的時(shí)候,性能比較差,
3,HttpUrlConnection底層也是用Socket來(lái)實(shí)現(xiàn)的
4,OkHttp像HttpUrlConnection一樣,實(shí)現(xiàn)了一個(gè)網(wǎng)絡(luò)連接的過(guò)程。
5,OkHttp和HttpUrlConnection是一級(jí)的,用socket實(shí)現(xiàn)了網(wǎng)絡(luò)連接,OkHttp更強(qiáng)大,
6,HttpUrlConnection在IO方面用到的是InputStream和OutputStream,但OkHttp用的是sink和source,這兩個(gè)是在Okio這個(gè)開(kāi)源庫(kù)里的,    feredSink(支持緩沖)、GzipSink(支持Gzip壓縮)、ForwardingSink和InflaterSink(后面這兩者服務(wù)于GzipSink)
7,多個(gè)相同host和port的stream可以共同使用一個(gè)socket,而RealConnection就是處理連接的,那也就是說(shuō)一個(gè)RealConnection上可能有很多個(gè)Stream
8,OkHttp代碼比HttpURLConnection精簡(jiǎn)的多
  • 10.OkHttp源碼分析(設(shè)計(jì)模式,線(xiàn)程池的使用)
單利、多線(xiàn)程安全問(wèn)題
/**
  餓漢式
 */
public class Person {

    //1.構(gòu)造函數(shù)私有化
    private Person(){}

    //2.創(chuàng)建單個(gè)私有對(duì)象對(duì)象
    private static  Person person = new Person();

    //3.提供對(duì)外公開(kāi)訪(fǎng)問(wèn)方法
    public static Person getPerson() {
        return person;
    }
}

/**
 * 懶漢式
 *
 * 多線(xiàn)程安全問(wèn)題:
 *      1.多個(gè)線(xiàn)程同時(shí)操作
 *      2.共用同一個(gè)資源
 *      3.分步執(zhí)行操作同一個(gè)資源
 *
 * 多線(xiàn)程安全解決方式:
 *      1.同步方法
 *      2.同步代碼塊
 *      3.鎖機(jī)制
 */
public class Student {

    //1.構(gòu)造函數(shù)私有化
    private Student(){}

    //2.創(chuàng)建單個(gè)私有對(duì)象對(duì)象
    private static  Student student;

    //3.提供對(duì)外公開(kāi)訪(fǎng)問(wèn)方法
    public static Student getInstance(){

        //解決線(xiàn)程安全問(wèn)題
        if (student == null){
            synchronized (Student.class){
                if (student == null) {
                    student = new Student();
                }
            }
        }

        return student;
    }
}
  • 10.OkHttpUtils工具類(lèi)抽取
public class OkHttpUtils {

    private static OkHttpUtils okHttpUtils;
    private static OkHttpClient okHttpClient;
    private static Handler mHandler;

    /**
     * 構(gòu)造初始化
     */
    private OkHttpUtils(){
        /**
         * 構(gòu)建OkHttpClient
         */
        okHttpClient = new OkHttpClient.Builder()
        /**
         * 請(qǐng)求的超時(shí)時(shí)間
         */
        .readTimeout(5000, TimeUnit.MILLISECONDS)
        /**
         * 設(shè)置響應(yīng)的超時(shí)時(shí)間
         */
        .writeTimeout(5000, TimeUnit.MILLISECONDS)
        /**
         * 設(shè)置連接的超時(shí)時(shí)間
         */
        .connectTimeout(5000, TimeUnit.MILLISECONDS)
        /**
         * 構(gòu)建
         */
        .build();


        /**
         * 獲取主線(xiàn)程的handler
         */
        mHandler = new Handler(Looper.getMainLooper());
    }

    /**
     * 通過(guò)單例模式構(gòu)造對(duì)象
     * @return
     */
    public static OkHttpUtils getInstance(){
        if (OkHttpUtils == null){
            synchronized (OkHttpUtils.class){
                if (okHttpUtils == null){
                    okHttpUtils = new OkHttpUtils();
                }
            }
        }
        return okHttpUtils;
    }

    /**
     * 構(gòu)造Get請(qǐng)求,封裝對(duì)用的Request請(qǐng)求,實(shí)現(xiàn)方法
     * @param url  訪(fǎng)問(wèn)路徑
     * @param realCallback  接口回調(diào)
     */
    private void getRequest(String url, final RealCallback realCallback){

        Request request = new Request.Builder().url(url).get().build();
        deliveryResult(realCallback, okHttpClient.newCall(request));
    }

    /**
     * 構(gòu)造post 請(qǐng)求,封裝對(duì)用的Request請(qǐng)求,實(shí)現(xiàn)方法
     * @param url 請(qǐng)求的url
     * @param requestBody 請(qǐng)求參數(shù)
     * @param realCallback 結(jié)果回調(diào)的方法
     */
    private void postRequest(String url, RequestBody requestBody, final RealCallback realCallback){

        Request request = new Request.Builder().url(url).post(requestBody).build();
        deliveryResult(realCallback, okHttpClient.newCall(request));
    }

    /**
     * 處理請(qǐng)求結(jié)果的回調(diào):主線(xiàn)程切換
     * @param realCallback
     * @param call
     */
    private void deliveryResult(final RealCallback realCallback, Call call) {
        call.enqueue(new Callback() {
            @Override
            public void onFailure(final Call call, final IOException e) {
                sendFailureThread(call, e, realCallback);
            }

            @Override
            public void onResponse(final Call call, final Response response) throws IOException {
                sendSuccessThread(call, response, realCallback);
            }
        });
    }

    /**
     * 發(fā)送成功的回調(diào)
     * @param call
     * @param response
     * @param realCallback
     */
    private void sendSuccessThread(final Call call, final Response response, final RealCallback
            realCallback) {
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                realCallback.onResponse(call,response);
            }
        });
    }

    /**
     * 發(fā)送失敗的回調(diào)
     * @param call
     * @param e
     * @param realCallback
     */
    private void sendFailureThread(final Call call, final IOException e, final RealCallback realCallback) {
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                realCallback.onFailure(call,e);
            }
        });
    }

    //-----------對(duì)外公共訪(fǎng)問(wèn)的get/post方法-----------
    /**
     * get請(qǐng)求
     * @param url  請(qǐng)求url
     * @param realCallback  請(qǐng)求回調(diào)
     */
    public void get(String url, final RealCallback realCallback){
        getRequest(url,realCallback);
    }

    /**
     * post請(qǐng)求
     * @param url       請(qǐng)求url
     * @param realCallback  請(qǐng)求回調(diào)
     * @param requestBody    請(qǐng)求參數(shù)
     */
    public void post(String url, RequestBody requestBody, final RealCallback realCallback){
        postRequest(url,requestBody,realCallback);
    }

    /**
     * http請(qǐng)求回調(diào)類(lèi),回調(diào)方法在UI線(xiàn)程中執(zhí)行
     */
    public static abstract class RealCallback {
        /**
         * 請(qǐng)求成功回調(diào)
         * @param response
         */
        public abstract void onResponse(Call call,Response response);
        /**
         * 請(qǐng)求失敗回調(diào)
         * @param e
         */
        public abstract void onFailure(Call call,IOException e);
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容