登录流程
这也是我自己在写这个过程的出现的问题以及解决问题的一些领悟。 大部分的网络请求相关的都不太难,难点主要是在于操作cookie。 cookie是什么?自行了解
我对这个cookie的感受:在我们获取验证码的时候,服务器就会把cookie放在响应中发过来,然后这里是保存了一定信息的。而我们登录时需要上传的验证码信息就在里面。 而在进行图片加载时,我选用Glide来加载图片。那么出现的问题就是如何在使用Glide的时候保存服务器响应中的cookie。
Glide保存cookie
这也是从断点哪里学到的,使用自定义的GlideModule来完成这操作。
import android.content.Context
import android.util.Log
import com.bumptech.glide.Glide
import com.bumptech.glide.Registry
import com.bumptech.glide.annotation.GlideModule
import com.bumptech.glide.integration.okhttp3.OkHttpUrlLoader
import com.bumptech.glide.load.model.GlideUrl
import com.bumptech.glide.module.AppGlideModule
import java.io.InputStream
@GlideModule
class HttpGlideModule :AppGlideModule() {
override fun registerComponents(context: Context, glide: Glide, registry: Registry) {
Log.d("HttpGlideModule", "registerComponents: ")
registry.replace(
GlideUrl::class.java,
InputStream::class.java,
OkHttpUrlLoader.Factory(RetrofitClient.okHttpClient)
)
}
}
从方法名来理解这里是注册了一个组件,在这个registry.replace()方法中,第三个参数就是我们自己写的OkHttpClient。 我自己的理解:Glide加载图片也是使用了okhttp的网络请求相关的东西,而这里可以把我们自己配置好的OkHttpClient传入进去。 这里主要是注意需要导入哪些包:
//okHttp3 : https://github.com/square/okhttp
implementation 'com.squareup.okhttp3:okhttp:4.9.0'
//okHttp3LoggingInterceptor
implementation 'com.squareup.okhttp3:logging-interceptor:4.9.0'
implementation 'com.github.bumptech.glide:glide:4.11.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
implementation"com.github.bumptech.glide:okhttp3-integration:4.9.0"
annotationProcessor'androidx.annotation:annotation:1.1.0'
kapt 'com.github.bumptech.glide:compiler:4.11.0'
因为我是用Kotlin写的,所以需要引入kapt注解器插件。
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-kapt'
}
这样我们Module就可以了。 其实这里我们并没有提及到cookie的保存和使用,那它在什么地方呢?
OkhttpClient 配置 cookie管理
管理cookie 就是在刚刚传入的OkHttpClient中。
object RetrofitClient {
const val BASE_URL="https://api.sunofbeach.net"
val okHttpClient = OkHttpClient.Builder()
.cookieJar(CookiesManager())
.readTimeout(60, TimeUnit.SECONDS) //设置读取超时时间
.writeTimeout(60, TimeUnit.SECONDS) //设置写的超时时间
.connectTimeout(60, TimeUnit.SECONDS)
.build()
val retrofit = Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(okHttpClient)
.build()
}
重点是在创建okHttpClient时,我们传入了一个cookieJar,这就是我们管理cookie的地方。 而这里的需要传入的参数是一个CookJar的接口实现类,那我们可以自己实现一个CookJar,这里就取名为:CookiesManager。 网上也有很多其他人写的,这里面要重写两个方法就是用于对cookie的保存和使用。
class CookiesManager : CookieJar {
private val cookieStore by lazy {
ConcurrentHashMap<String, MutableList<Cookie>>()
}
override fun loadForRequest(url: HttpUrl): List<Cookie> {
val list = ArrayList<Cookie>()
Log.d("CookiesManager", "loadForRequest: httpUrl:${url.host} ")
val sob = cookieStore[RetrofitClient.BASE_URL]
Log.d("CookiesManager", "返回sob的cookie ${sob.toString()}")
sob?.apply {
return this
}
return list
}
override fun saveFromResponse(url: HttpUrl, cookies: List<Cookie>) {
Log.d("CookiesManager", "saveFromResponse: httpUrl:$url ")
if (RetrofitClient.BASE_URL.contains(url.host)) {
Log.d("CookiesManager", "保存sob的数据")
cookieStore[RetrofitClient.BASE_URL] = cookies as MutableList<Cookie>
}
}
}
其实从方法名就可以清楚他们的意思,具体的实现各有不同,这里也是参考的断点和安~默的代码写的,勉强能够。
获取验证码注意点
现在基本解决了重点:cookie的操作。 还有一个地方就是使用Glide加载验证码时需要对缓存策略进行修改。即不允许任何缓存。因为这个我们是用一个链接来获取图片的,当有了缓存就不能进行刷新验证码的操作了。
Glide.with(this)
.load(RetrofitClient.BASE_URL+"/uc/ut/captcha")
//不需要把图片进行缓存了
.skipMemoryCache(true)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.into(binding.ivCaptcha)
其他基本不是什么难点了,大锯哥很多东西都有讲过。
有什么不对的地方希望大家指出一下,很多东西不太清楚原理,就只能尝试去理解。