22
22
23
23
* [ 下载文件] ( #下载文件 )
24
24
25
- * [ 同步请求 ] ( #同步请求 )
25
+ * [ 分区存储适配 ] ( #分区存储适配 )
26
26
27
- * [ 请求缓存 ] ( #请求缓存 )
27
+ * [ 发起同步请求 ] ( #发起同步请求 )
28
28
29
- * [ 搭配协程使用 ] ( #搭配协程使用 )
29
+ * [ 设置请求缓存 ] ( #设置请求缓存 )
30
30
31
- * [ 分区存储适配 ] ( #分区存储适配 )
31
+ * [ 搭配协程使用 ] ( #搭配协程使用 )
32
32
33
33
* [ 疑难解答] ( #疑难解答 )
34
34
94
94
95
95
* [ 我想自定义一个 RequestBody 进行请求该怎么办] ( #我想自定义一个-requestbody-进行请求该怎么办 )
96
96
97
+ * [ 我想自定义请求头中的 ContentType 该怎么做] ( #我想自定义请求头中的-contenttype-该怎么做 )
98
+
99
+ * [ 我想自定义 Get 请求参数中的 key 和 value 该怎么做] ( #我想自定义-get-请求参数中的-key-和-value-该怎么做 )
100
+
97
101
* [ 搭配 RxJava] ( #搭配-rxjava )
98
102
99
103
* [ 准备工作] ( #准备工作 )
@@ -169,9 +173,9 @@ OkHttpClient okHttpClient = new OkHttpClient.Builder()
169
173
EasyConfig . with(okHttpClient)
170
174
// 是否打印日志
171
175
.setLogEnabled(BuildConfig . DEBUG )
172
- // 设置服务器配置
176
+ // 设置服务器配置(必须设置)
173
177
.setServer(server)
174
- // 设置请求处理策略
178
+ // 设置请求处理策略(必须设置)
175
179
.setHandler(new RequestHandler ())
176
180
// 设置请求重试次数
177
181
.setRetryCount(3 )
@@ -413,7 +417,38 @@ EasyHttp.download(this)
413
417
}). start();
414
418
```
415
419
416
- #### 同步请求
420
+ #### 分区存储适配
421
+
422
+ * 在 Android 10 之前,我们在读写外部存储的时候,可以直接使用 File 对象来上传或者下载文件,但是在 Android 10 之后,如果你的项目需要 Android 10 分区存储的特性,那么在读写外部存储文件的时候,就不能直接使用 File 对象,因为 ` ContentResolver.insert ` 返回是一个 ` Uri ` 对象,这个时候就需要使用到框架提供的 ` FileContentResolver ` 对象了(这个对象是 File 的子类),具体使用案例如下:
423
+
424
+ ``` java
425
+ File outputFile;
426
+ if (Build . VERSION. SDK_INT >= Build . VERSION_CODES. Q ) {
427
+ ContentValues values = new ContentValues ();
428
+ .........
429
+ // 生成一个新的 uri 路径
430
+ Uri outputUri = getContentResolver(). insert(MediaStore . Xxx . Media . EXTERNAL_CONTENT_URI , values);
431
+ // 适配 Android 10 分区存储特性
432
+ outputFile = new FileContentResolver (context, outputUri);
433
+ } else {
434
+ outputFile = new File (xxxx);
435
+ }
436
+
437
+ EasyHttp . post(this )
438
+ .api(new XxxApi ()
439
+ .setImage(outputFile))
440
+ .request(new HttpCallback<Xxx <Xxx> > (this ) {
441
+
442
+ @Override
443
+ public void onSucceed (Xxx<Xxx > data ) {
444
+
445
+ }
446
+ });
447
+ ```
448
+
449
+ * 这是上传的案例,下载也同理,这里不再赘述。
450
+
451
+ #### 发起同步请求
417
452
418
453
* 需要注意的是:同步请求是耗时操作,不能在主线程中执行,请务必保证此操作在子线程中执行
419
454
@@ -430,7 +465,7 @@ try {
430
465
}
431
466
```
432
467
433
- #### 请求缓存
468
+ #### 设置请求缓存
434
469
435
470
* 需要先实现读取和写入缓存的接口,如果已配置则可以跳过,这里以 MMKV 为例
436
471
@@ -615,37 +650,6 @@ lifecycleScope.launch(Dispatchers.IO) {
615
650
616
651
* 如果你对协程的使用不太熟悉,推荐你看一下[ 这篇文章] ( https://www.jianshu.com/p/2e0746c7d4f3 )
617
652
618
- #### 分区存储适配
619
-
620
- * 在 Android 10 之前,我们在读写外部存储的时候,可以直接使用 File 对象来上传或者下载文件,但是在 Android 10 之后,如果你的项目需要 Android 10 分区存储的特性,那么在读写外部存储文件的时候,就不能直接使用 File 对象,因为 ` ContentResolver.insert ` 返回是一个 ` Uri ` 对象,这个时候就需要使用到框架提供的 ` FileContentResolver ` 对象了(这个对象是 File 的子类),具体使用案例如下:
621
-
622
- ``` java
623
- File outputFile;
624
- if (Build . VERSION. SDK_INT >= Build . VERSION_CODES. Q ) {
625
- ContentValues values = new ContentValues ();
626
- .........
627
- // 生成一个新的 uri 路径
628
- Uri outputUri = getContentResolver(). insert(MediaStore . Xxx . Media . EXTERNAL_CONTENT_URI , values);
629
- // 适配 Android 10 分区存储特性
630
- outputFile = new FileContentResolver (context, outputUri);
631
- } else {
632
- outputFile = new File (xxxx);
633
- }
634
-
635
- EasyHttp . post(this )
636
- .api(new XxxApi ()
637
- .setImage(outputFile))
638
- .request(new HttpCallback<Xxx <Xxx> > (this ) {
639
-
640
- @Override
641
- public void onSucceed (Xxx<Xxx > data ) {
642
-
643
- }
644
- });
645
- ```
646
-
647
- * 这是上传的案例,下载也同理,这里不再赘述。
648
-
649
653
# 疑难解答
650
654
651
655
#### 如何设置 Cookie
@@ -1423,10 +1427,11 @@ parameter.put("key1", value1);
1423
1427
parameter. put(" key2" , value2);
1424
1428
1425
1429
String json = gson. toJson(parameter);
1430
+ JsonBody jsonBody = new JsonBody (json)
1426
1431
1427
1432
EasyHttp . post(this )
1428
1433
.api(new XxxApi ())
1429
- .body(new JsonBody (json) )
1434
+ .body(jsonBody )
1430
1435
.request(new HttpCallback<HttpData<Xxx > > (this ) {
1431
1436
1432
1437
@Override
@@ -1438,7 +1443,7 @@ EasyHttp.post(this)
1438
1443
1439
1444
#### 如何设置自定义的 UA 标识
1440
1445
1441
- * 首先 UA 是 User Agent 的简称,当我们没有设置自定义 UA 标识的时候,那么 OkHttp 会在 BridgeInterceptor 拦截器添加一个默认的 UA 标识,那么如何在 EasyHttp 设置自定义 UA 标识呢?其实很简单,UA 标识本质上其实就是一个请求头,在 EasyHttp 中添加一个请求头为 ` " User-Agent` 的参数即可,至于怎么添加请求头,前面的文档已经有介绍了,这里不再赘述。
1446
+ * 首先 UA 是 User Agent 的简称,当我们没有设置自定义 UA 标识的时候,那么 OkHttp 会在 BridgeInterceptor 拦截器添加一个默认的 UA 标识,那么如何在 EasyHttp 设置自定义 UA 标识呢?其实很简单,UA 标识本质上其实就是一个请求头,在 EasyHttp 中添加一个请求头为 ` User-Agent ` 的参数即可,至于怎么添加请求头,前面的文档已经有介绍了,这里不再赘述。
1442
1447
1443
1448
#### 我想修改请求回调所在的线程该怎么办
1444
1449
@@ -1475,6 +1480,103 @@ EasyHttp.post(this)
1475
1480
1476
1481
* 需要注意的是:由于 Post 请求是将参数放置到 ` RequestBody ` 上面,而一个请求只能设置一个 ` RequestBody ` ,如果你设置了自定义 ` body(RequestBody body) ` ,那么框架将不会去将 ` XxxApi ` 类中的字段解析成参数。另外除了 Post 请求,Put 请求和 Patch 请求也可以使用这种方式进行设置,这里不再赘述。
1477
1482
1483
+ #### 我想自定义请求头中的 ContentType 该怎么做
1484
+
1485
+ * 具体的写法示例如下:
1486
+
1487
+ ``` java
1488
+ public final class SearchBlogsApi implements IRequestApi {
1489
+
1490
+ @NonNull
1491
+ @Override
1492
+ public String getApi () {
1493
+ return " xxx/xxx" ;
1494
+ }
1495
+
1496
+ @HttpHeader
1497
+ @HttpRename (" Content-Type" )
1498
+ private String contentType = " application/x-www-form-urlencoded;charset=utf-8" ;
1499
+ }
1500
+ ```
1501
+
1502
+ * 需要注意的是:此功能仅是在框架 ** 11.5** 版本的时候加上的,之前的版本没有这一功能
1503
+
1504
+ #### 我想自定义 Get 请求参数中的 key 和 value 该怎么做
1505
+
1506
+ * 先自定义一个 Api 类,然后通过 ` getApi ` 方法将参数动态拼接上去
1507
+
1508
+ ``` java
1509
+ public final class CustomParameterApi implements IRequestApi {
1510
+
1511
+ @HttpIgnore
1512
+ @NonNull
1513
+ private final Map<String , String > parameters;
1514
+
1515
+ public CustomParameterApi () {
1516
+ this (new HashMap<> ());
1517
+ }
1518
+
1519
+ public CustomParameterApi (@NonNull Map<String , String > parameters ) {
1520
+ this . parameters = parameters;
1521
+ }
1522
+
1523
+ @NonNull
1524
+ @Override
1525
+ public String getApi () {
1526
+ Set<String > keys = parameters. keySet();
1527
+
1528
+ StringBuilder builder = new StringBuilder ();
1529
+ int index = 0 ;
1530
+ for (String key : keys) {
1531
+ String value = parameters. get(key);
1532
+
1533
+ if (index == 0 ) {
1534
+ builder. append(" ?" );
1535
+ }
1536
+ builder. append(key)
1537
+ .append(" =" )
1538
+ .append(value);
1539
+ if (index < keys. size() - 1 ) {
1540
+ builder. append(" &" );
1541
+ }
1542
+ index++ ;
1543
+ }
1544
+
1545
+ return " xxx/xxx" + builder;
1546
+ }
1547
+
1548
+ public CustomParameterApi putParameter (String key , String value ) {
1549
+ parameters. put(key, value);
1550
+ return this ;
1551
+ }
1552
+
1553
+ public CustomParameterApi removeParameter (String key ) {
1554
+ parameters. remove(key);
1555
+ return this ;
1556
+ }
1557
+ }
1558
+ ```
1559
+
1560
+ * 外层可以通过以下方式进行调用
1561
+
1562
+ ``` java
1563
+ CustomParameterApi api = new CustomParameterApi ();
1564
+ api. putParameter(" key1" , " value1" );
1565
+ api. putParameter(" key2" , " value2" );
1566
+
1567
+ EasyHttp . get(this )
1568
+ .api(api)
1569
+ .request(new HttpCallback<Xxx > (this ) {
1570
+
1571
+ @Override
1572
+ public void onSucceed (Xxx result ) {
1573
+
1574
+ }
1575
+ });
1576
+ ```
1577
+
1578
+ * 需要注意的是:这种实现方式仅适用于在框架设计无法满足需求的情况下,其他情况下作者并不提倡用这种方式,因为这样不方便管理请求参数的 key,还是推荐大家使用在类上面定义字段的方式来实现。
1579
+
1478
1580
# 搭配 RxJava
1479
1581
1480
1582
#### 准备工作
0 commit comments