当前位置:网站首页>Encapsulate a set of project network request framework from 0
Encapsulate a set of project network request framework from 0
2022-04-23 07:08:00 【Drink dichlorvos alone】
Preface
Android Make a network request , Usually by Retrofit coordination RxJava To achieve . It should be noted that , In the project , It is impossible to directly use the framework naked in every request place , Instead, you must have encapsulated a layer of the framework in your own project , What is actually used is the layer of encapsulation .
This article will introduce a packaging scheme , You can use... In a project . There must be some shortcomings in this scheme , Please criticize and correct .
Knowledge used
Kotlin、Retrofit,RxJava,OkHttp
Introduction to the steps
1.api Introduce
Use the opening of Hongyang great God here api, Link here . Login only api that will do , Other api In the same way .
url:https://www.wanandroid.com/user/login
Method :POST
Parameters :username,password
Here is a good interface testing tool Apipost, Let me test the login interface
It returns response It's made up of three parts , Namely data,errorCode,errorMsg. I pasted the results
{
"data": {
"admin": false,
"chapterTops": [],
"coinCount": 10,
"collectIds": [],
"email": "",
"icon": "",
"id": 130077,
"nickname": "LJH111",
"password": "",
"publicName": "LJH111",
"token": "",
"type": 0,
"username": "LJH111"
},
"errorCode": 0,
"errorMsg": ""
}
2. Create project
Create a kotlin project , Complete the necessary preparations
① Dependency import
stay app Modular gradle Import in file retrofit and rxjava Dependence
// Import retrofit
implementation 'com.squareup.retrofit2:retrofit:2.3.0'
implementation 'com.squareup.retrofit2:converter-gson:2.3.0'//ConverterFactory Of Gson Dependency package
implementation 'com.squareup.retrofit2:converter-scalars:2.3.0'//ConverterFactory Of String Dependency package
implementation("com.squareup.okhttp3:okhttp:4.9.1")
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
// Import rxjava
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
compile "io.reactivex.rxjava2:rxjava:2.0.8"
② Turn on network permissions
(1) First, create a new one xml file , Pictured
The content is
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true" />
</network-security-config>
(2) And then find Menifest file
stay application Set such a property in the tag
(3) then , stay menifest Open network permissions in
The content is
<!-- network right -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
3. newly build response Template class
be-all response There's one thing in common , It consists of three parts , Namely data,errorCode,errorMsg. There is only data The type of is uncertain , But you can use generics to represent .
So you can use a common template class to receive all Response
/** * Created by didiwei on 2022/4/20 * desc: All requested template classes */
data class ResponseModel<T>(val data: T,
val errorCode: String?,
val errorMsg: String?)
data Just use generics
4. When the new login is successful , Back to data Template class
When the login is successful , Back to json as follows
{
"data": {
"admin": false,
"chapterTops": [],
"coinCount": 10,
"collectIds": [],
"email": "",
"icon": "",
"id": 130077,
"nickname": "LJH111",
"password": "",
"publicName": "LJH111",
"token": "",
"type": 0,
"username": "LJH111"
},
"errorCode": 0,
"errorMsg": ""
}
Because data Is different api, It may be different , So it's best to use a class to distinguish different data. Here, when the login is successful , Back to data I say so
/** * Created by didiwei on 2022/4/20 * desc: When the login is successful , Back to response Medium data Template class of */
data class LoginSuccessResData(val admin: Boolean,
val chapterTops: List<*>,
val coinCount: Int,
val collectIds: List<*>,
val email: String?,
val icon: String?,
val id: String?,
val nickname: String?,
val password: String?,
val publicName: String?,
val token: String?,
val type: Int,
val username: String?)
5. Customize RxJava The operator
The normal logic should be like this , When the request is successful , hold data Throw it to UI, When the request fails , hold errorMsg Throw it to UI. So we can customize RxJava The operator , When the data returns , Yes Response To accomplish such a function .
/** * Created by didiwei on 2022/4/20 * desc: RxJava Custom operators for , For stripping data and errorMsg */
abstract class RxJavaInterceptor<T> : Observer<ResponseModel<T>> {
abstract fun success(data: T?)
abstract fun failure(errorMsg: String?)
override fun onSubscribe(d: Disposable?) {
// You can get a load here dialog Of start, Don't forget to finish the request ( Success or failure ) Let this dialog disappear
}
override fun onNext(t: ResponseModel<T>?) {
if(t?.data != null){
// Request succeeded
success(t?.data)
}else{
// Failure
failure(t?.errorMsg)
}
}
override fun onError(e: Throwable?) {
failure(e?.message)
}
override fun onComplete() {
// You can add dialog The disappearance of
}
}
There's a caveat , First RxJavaInterceptor
Class is an abstract class , Inside success
and failure
Is an abstract method , When called, implement . Secondly, it is still a generic class , Applicable to all model
6. Interface for writing requests
/** * Created by didiwei on 2022/4/20 * desc: About user login Registered api */
interface UserService {
/** * desc Login interface * * url:https://www.wanandroid.com/user/login * Method :POST * Parameters :username,password */
@POST("/user/login")
@FormUrlEncoded
fun loginAction(@Field("username")username: String?,
@Field("password")password: String?)
:Observable<ResponseModel<LoginSuccessResData>>
}
Notice that its return value is Observable
type , As the observed , Flow to the observer (RxJava Knowledge )
7. Create instantiation service Class
/** * Created by didiwei on 2022/4/20 * desc: This class is a singleton class , Used to create Service Example */
class ApiClient {
private object Holder{
val instance = ApiClient()
}
companion object{
val INSTANCE = Holder.instance
}
fun <T> createRetrofit(retrofitInterface: Class<T>) : T{
// establish okhttp
val mOkHttpClient = OkHttpClient().newBuilder()
.readTimeout(10000, TimeUnit.SECONDS)// Read timeout
.connectTimeout(10000, TimeUnit.SECONDS)// Connection timeout
.writeTimeout(10000, TimeUnit.SECONDS)// Write the timeout
.build()
// establish retrofit
val retrofit: Retrofit = Retrofit.Builder()
.baseUrl("https://www.wanandroid.com")
.client(mOkHttpClient)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build()
// return
return retrofit.create(retrofitInterface)
}
}
8. So when we use it , That's how it works
For example, add a login button , Then register its click event
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val userLoginBtn: Button = findViewById<Button>(R.id.userLoginBtn)
userLoginBtn.setOnClickListener(onClickListener)
}
private val onClickListener = View.OnClickListener {
when(it.id){
R.id.userLoginBtn ->{
val userName = "LJH111"
val userPwd = "123456"
ApiClient.INSTANCE.createRetrofit(UserService::class.java)
.loginAction(userName,userPwd)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : RxJavaInterceptor<LoginSuccessResData>(){
override fun success(data: LoginSuccessResData?) {
Log.v("ljh"," The request is successful , Back to data by :${data}")
}
override fun failure(errorMsg: String?) {
Log.v("ljh"," request was aborted , The error message is :${errorMsg}")
}
})
}
}
}
}
effect
If you change it to the wrong user name or password , The effect is this
thus , We have completed the encapsulation of network request rules
版权声明
本文为[Drink dichlorvos alone]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204230606379929.html
边栏推荐
- Chaos takes you to the chaos project quickly
- 中国各省会城市经纬度位置
- oracle生成毫秒级时间戳
- oracle表空间表分区详解及oracle表分区查询使用方法
- Using Prom label proxy to implement label based multi tenant reading of Prometheus thanos
- 统一任务分发调度执行框架
- Oracle RAC数据库实例启动异常问题分析IPC Send timeout
- Oracle Job定时任务的使用详解
- Build a cloud blog based on ECS (polite experience)
- JS 比较2个数组中不同的元素
猜你喜欢
mysql和pgsql时间相关操作
10g数据库使用大内存主机时不能启动的问题
Practice using polardb and ECs to build portal websites
Redis FAQ
Static interface method calls are not supported at language level ‘5‘ 异常解决
Implementation of multi tenant read and write in Prometheus cortex
Typical application scenarios of alicloud log service SLS
Build a cloud blog based on ECS (polite experience)
iTOP4412 LCD背光驱动(PWM)
Prometheus cortex Architecture Overview (horizontally scalable, highly available, multi tenant, long-term storage)
随机推荐
Abnormal record-15
npm ERR code 500解决
Abnormal record-16
timestamp隐式转换问题导致索引列未使用问题分析
OSS云存储管理实践(体验有礼)
oracle用delete删除数据所需时间测试
Oracle索引状态查询与索引重建
Build a cloud blog based on ECS (send blessings on the cloud Xiaobao code and draw iphone13 for free)
【机器学习】笔记 4、KNN+交叉验证
OVS and OVS + dpdk architecture analysis
oracle数据库将多个列的查询结果集合并到一行中
BPF program of type XDP
Build a cloud blog based on ECS (polite experience)
Problems related to Prometheus cortex using block storage
error 403 In most cases, you or one of your dependencies are requesting解决
Prometheus monitoring method and index interpretation of influxdb
Relabel of Prometheus_ Configs and metric_ relabel_ Configs explanation and usage examples
JS format current time and date calculation
Oracle RAC数据库实例启动异常问题分析IPC Send timeout
iTOP4412 SurfaceFlinger(4.0.3_r1)