数据存储&网络通信|青训营笔记

155 阅读4分钟

这是我参与「第四届青训营 」笔记创作活动的第4天

本节课的主要内容:数据存储与网络通信

1,网络通信

大型App内容的获取,都是通过网络请求,作为App的基础能力。

1.1 Retrofit

主要介绍Retrofit
Retrofit是目前Android平台上,可以说是最热门的网络请求封装,是对OkHttp的一个封装。
Retrofit的使用说明

  • 添加Retrofit库的依赖

    • 在需要用到Retrofit接口的module中,新增依赖(最新的版本可看[GitHub]
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
    //...其他依赖
}
  • 创建 用于描述网络请求 的接口
interface IUserInfoService {

    @GET("users/{uid}/name")
    fun getUserName(@Path("uid") uid: Int): Call<ResponseBody>

    //@GET("users/{name}/uid")
    //fun getRequest(@Path("name" name:String)) Call<User>
    
    //后续可以增加其他的接口,一个接口对应一个api请求
}

//函数名:可自定义,需要能识别出该接口的作用,该interface里可以增加多个不同的函数
//@GET 注解:用于指定该接口的相对路径,并采用Get方法发起请求
//@Path 注解:需要外部调用时,传入一个uid,该uid会替换@GET注解里相对路径的{uid}
//返回值Call<ResponseBody>,这里用ResponseBody,我们可以直接拿到请求的String内容
//如果要自动转为Model类,例如User,这里直接替换为User就好。
  • 发起网络请求
    //创建Retrofit实例
    val retrofit = Retrofit.Builder()
        .baseUrl("https://www.bytedance.com/")
        .build()
    //创建iUserInfoService实例
    val iUserInfoService = retrofit.create(IUserInfoService::class.java)
    //创建网络请求Call对象
    val call = iUserInfoService.getUserName(1123)
    //发起异步请求
    call.enqueue(object : Callback<ResponseBody> {

        override fun onResponse(call: Call<ResponseBody>,
                                response: Response<ResponseBody>) {
            //请求成功时回调
            request_result_tv.text = "请求成功:" + response.body()!!.string()
        }

        override fun onFailure(call: Call<ResponseBody>, e: Throwable) {
            //请求失败时候的回调
            request_result_tv.text = "请求失败:" + e.message
        }
    })
}

Retrofit的使用需要学习许多注解,通过注解的组合,以此实现更加丰富的功能。
Retrofit只支持OkHttp网络库的解答:
通过代理对象对方法接口进行调用时,会在InvocationHandler#invoke方法回调里为serviceMethod.callAdapter.adapt()设置okHttpCall对象,进而发起请求时,委托OkHttpCall对象发起网络请求。而OkHttpCall#enqueue 调用okHttp网络库发起请求。
所以serviceMethod.callAdapter.adapt()设置死了为okHttpCall对象。Retrofit发起请求只能对OkHttp网络库进行支持了。

1.2 TTNet

TTNet是字节跳动通用的网络请求封装框架,用来向服务端发起请求。

目前Android端上的头条,抖音,番茄小说都在使用该库作为网络请求封装框架,作为字节内部的基础库,提供了一整套Android客户端网络请求解决方案。

它有哪些突出的优点:
- 基于Retrofit改造,具备了Retrofit所具有的优点
- 支持多个Http网络库的动态切换(okhttp和cronet)
- 支持网络拦截配置:添加公共参数,动态切换协议及Host,动态选路等
- 支持流解析,json序列化
- ......
TTNetTTNet的实现原理
基于Retrofit的进行二次开发,核心主要是替换Retrofit其中的2点

  • 替换底层用到的OKHttpClient

  • 替换底层用到的OKHttpCall

image.png

TTNet主流程

image.png

1.3 网络请求总结

image.png

2, 数据存储

2.1 存储方式对比

持久性的本地数据存储是Android中常见的能力,可以在应用被杀死的情况下,而保持数据不会被清除。我们可以根据不同场景的诉求,可以选用不同的存储方式,常见的数据存储主要有以下4种。

image.png

2.2 数据库开源框架对比

数据库 相对来说,其使用会比较复杂些,单独进行探索,下面是几个主流的数据库框架对比

image.png

2.3 Room介绍

Room是Google Jetpack家族里的一员,Room在SQLite上提供了一个抽象层,以便在充分利用SQLite的强大功能的同时,能够流畅地访问数据库

image.png

主要的三个组件

  • 数据库类(Database),用于保存数据库并作为应用持久性数据底层连接的主要访问点。
  • 数据实体(Entity),用于表示应用的数据库中的表。
  • 数据访问对象(DAO),提供您的应用可用于查询、更新、插入和删除数据库中的数据的方法。

Room接入
Gradle目录的build.gradle文件里添加如下:

image.png

Room原理 其原理主要为编译期,通过kapt处理@``Dao@Database注解,动态生成对应的实现类,然后底层使用Android提供的SupportSQLiteOpenHelper实现数据库的增删改查等操作

kapt注解处理 oom在编译期,通过kapt处理@Dao和@Database注解,生成DAO和Database的实现类 AppDatabase --> AppDatabase_Impl UserDao-->UserDao_Impl

image.png

kapt生成的代码在build/generated/source/kapt/

image.png

2.4 数据库总结

image.png

3,总结:

本次课程收获颇丰,通过本次学习我知道了Retrofit的用法以及原理,了解了字节跳动使用的TTnet的用法与原理。在数据存储方面也对Room数据库有了一定的了解。课后还需要不断加深学习以来巩固今日所学!

参考资料