当前位置:网站首页>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
边栏推荐
- Oracle RAC数据库实例启动异常问题分析IPC Send timeout
- Dolphinscheduler调度sql任务建表时The query did not generate a result set异常解决
- oracle表的约束详解
- Abnormal record-17
- Kubernetes coredns FAQ reference
- Prometheus thanos Quick Guide
- Arranges the objects specified in the array in front of the array
- ACFS文件系统创建扩大缩小等配置步骤
- 中国各省会城市经纬度位置
- oracle 修改默认临时表空间
猜你喜欢
随机推荐
BPF program of type XDP
Memcached source code analysis
一个DG环境的ORA-16047: DGID mismatch between destination setting and target database问题排查及监听VNCR特性
Oracle索引状态查询与索引重建
JS 比较2个数组中不同的元素
利用队列实现栈
基於ECS搭建雲上博客(雲小寶碼上送祝福,免費抽iphone13任務詳解)
Abnormal record-16
RAC环境中openssh版本对SSH互信创建的影响
Using Prom label proxy to implement label based multi tenant reading of Prometheus thanos
useReducer基本用法
Dolphinscheduler调度spark任务踩坑记录
ACFS文件系统创建扩大缩小等配置步骤
基于ECS搭建云上博客(云小宝码上送祝福,免费抽iphone13任务详解)
统一任务分发调度执行框架
oracle数据库将多个列的查询结果集合并到一行中
[Exynos4412][iTOP4412][Android-K]添加产品选项
oracle用delete删除数据所需时间测试
Oracle redo log产生量大的查找思路与案例
iTOP4412 FramebufferNativeWindow(4.0.3_r1)