data class LoginRegisterResponse(

val admin: Boolean,

val chapterTops: List<*>,

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?

)

定义一个接口 代码如下:WanAndroidAPI

interface WanAndroidAPI {

// TODO 下面是传统方式API

/** https://www.wanandroid.com/blog/show/2

登录API username=Derry-vip&password=123456

*/

@POST(“/user/login”)

@FormUrlEncoded

fun loginAction(

@Field(“username”) username: String,

@Field(“password”) password: String

)

Call // 返回值

}

接口的实现 代码如下:APIClient

class APIClient {

/**

单例

*/

private object Holder {

val INSTANCE = APIClient()

}

companion object { // 派生

val instance = Holder.INSTANCE

}

fun instanceRetrofit(apiInstance: Class): T {

// OkHttpClient 请求服务器

val mOkHttpClient = OkHttpClient().newBuilder().apply {

readTimeout(10000, TimeUnit.SECONDS) //添加超时时间

connectTimeout(10000, TimeUnit.SECONDS) //添加连接超时时间

writeTimeout(10000, TimeUnit.SECONDS) // 添加写入超时时间

}.build()

val retrofit = Retrofit.Builder()

.baseUrl(“https://www.wanandroid.com”)

// 请求方 ←

.client(mOkHttpClient)

// 响应方 →

// Response的事情 回来

.addCallAdapterFactory(RxJava2CallAdapterFactory.create()) // RxJava来处理

.addConverterFactory(GsonConverterFactory.create()) // Gson 来解析 — JavaBean

.build()

return retrofit.create(apiInstance)

}

}

XML 代码如下

xmlns:app=“http://schemas.android.com/apk/res-auto”

xmlns:tools=“http://schemas.android.com/tools”

android:layout_width=“match_parent”

android:layout_height=“match_parent”

tools:context=“.ui.MainActivity”>

android:id=“@+id/textview”

android:text=“启动线程”

android:layout_width=“match_parent”

android:layout_height=“wrap_content”

tools:ignore=“MissingConstraints” />

android:id=“@+id/button”

android:onClick=“startRequest”

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:text=“网络请求”

app:layout_constraintBottom_toBottomOf=“parent”

app:layout_constraintLeft_toLeftOf=“parent”

app:layout_constraintRight_toRightOf=“parent”

app:layout_constraintTop_toTopOf=“parent”

tools:ignore=“OnClick” />

具体功能实现,直接看代码吧,注释比较多

代码如下: MainActivity

class MainActivity : AppCompatActivity() {

private var mProgressDialog: ProgressDialog? = null

override fun onCreate(savedInstanceState: Bundle?) {

super.onCreate(savedInstanceState)

setContentView(R.layout.activity_main)

}

fun startRequest(view: View){

mProgressDialog = ProgressDialog(this)

mProgressDialog?.setTitle(“请求服务器中…”)

mProgressDialog?.show()

// TODO 第一步:异步线程开启,请求服务器

object: Thread(){

override fun run() {

super.run()

Thread.sleep(2000) // 模拟一个两秒的加载时间

val loginResult = APIClient.instance.instanceRetrofit(WanAndroidAPI::class.java)

.loginAction(“Derry-vip”, “123456”)

val result: LoginRegisterResponseWrapper? = loginResult.execute().body()

// 切换到主线程, 更新UI 把最终的javaBean 发送给Handler

val msg = mHandler.obtainMessage()

msg.obj = result

mHandler.sendMessage(msg)

}

}.start()

}

// TODO 第二步:主线程更新UI

val mHandler = Handler(Looper.getMainLooper()){

// as 类型转换

val result = it.obj as LoginRegisterResponseWrapper

textview.text = result.data.toString() // 更新控件 UI

mProgressDialog?.hide()

false

}

}

上面的代码实现,是传统完成的异步加载操作。需要先开启一个异步线程,然后再把登录成功的数据,再交给主线线程去做UI的更新操作。

2.2:协程方式完成异步任务网络加载

再来实现一个协程的

修改 WanAndroidAPI 里面的接口,添加 suspend 关键字,代码如下:

@POST(“/user/login”)

@FormUrlEncoded

suspend fun loginActionCoroutine(

@Field(“username”) username: String,

@Field(“password”) password: String

)

LoginRegisterResponseWrapper // 返回值

修改 MainActivity 中的代码,代码如下:

class MainActivity1 : AppCompatActivity() {

private var mProgressDialog: ProgressDialog? = null

private val main = MainScope()

override fun onCreate(savedInstanceState: Bundle?) {

super.onCreate(savedInstanceState)

setContentView(R.layout.activity_main)

}

fun startRequest(view: View) {

mProgressDialog = ProgressDialog(this)

mProgressDialog?.setTitle(“请求服务器中…”)

mProgressDialog?.show()

// launch 在Android 中使用的时候,它默认的是 IO 线程,所以需要修改成Main 线程 (Dispatchers.Main )

main.launch(Dispatchers.Main) {

// 1.挂起出去执行异步线程 2. 操作完成之后,恢复主线程

val result = APIClient.instance.instanceRetrofit(WanAndroidAPI::class.java)

.loginActionCoroutine(“Derry-vip”, “123456”)

// 更新UI

textview.text = result.data.toString()

mProgressDialog?.hide()

}

}

override fun onDestroy() {

super.onDestroy()

main.cancel()

}

}

是不是简单了很多呢?不再需要创建异步线程,然后再交给主线程去修改UI,而是直接使用 launch 挂起出去执行异步操作,操作完成后直接恢复到主线程

这只是一个简单的一层回调的例子,可以想象一些,如果老板让我们实现一个三层回调,30层回调的时候,我们使用传统的处理方式会有多疼苦,接下来我们来实现一下。

2.3:传统方式完成三层回调

先写个回调接口 代码如下 ResponseCallback

/**

模拟请求服务器后,相应结果信息

*/

interface ResponseCallback {

/**

请求服务器 加载成功

*/

fun responseSuccess(serverResponseInfo: String)

/**

请求服务器 加载失败

*/

fun responseError(serverResponseErrorMsg: String)

}

再写三个模拟数据请求的异步线程 代码如下:

/**

第一层 请求加载 [用户数据] responseCallback [回调给外界的接口]

*/

private fun requestLoadUser(responseCallback: ResponseCallback) {

val isLoadSuccess = true // 加载成功 或 失败的标记

object : Thread() {

override fun run() {

super.run()

try {

sleep(3000L) // 模拟请求 所造成的耗时

if (isLoadSuccess) {

responseCallback.responseSuccess(“加载到[用户数据]信息集”)

} else {

responseCallback.responseSuccess(“加载[用户数据],加载失败,服务器宕机了”)

}

} catch (e: InstantiationException) {

e.printStackTrace()

}

}

}.start()

}

/**

第二层 请求加载 [用户资产数据] responseCallback [回调给外界的接口]

*/

private fun requestLoadUserAssets(responseCallback: ResponseCallback) {

val isLoadSuccess = true // 加载成功 或 失败的标记

object : Thread() {

override fun run() {

super.run()

try {

sleep(3000L)

if (isLoadSuccess) {

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)

最后

都说三年是程序员的一个坎,能否晋升或者提高自己的核心竞争力,这几年就十分关键。

技术发展的这么快,从哪些方面开始学习,才能达到高级工程师水平,最后进阶到Android架构师/技术专家?我总结了这 5大块;

我搜集整理过这几年阿里,以及腾讯,字节跳动,华为,小米等公司的面试题,把面试的要求和技术点梳理成一份大而全的“ Android架构师”面试 Xmind(实际上比预期多花了不少精力),包含知识脉络 + 分支细节。

网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。

2021年虽然路途坎坷,都在说Android要没落,但是,不要慌,做自己的计划,学自己的习,竞争无处不在,每个行业都是如此。相信自己,没有做不到的,只有想不到的。祝大家2021年万事大吉。

本文已被CODING开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》收录

一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!

AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算

vVu1-1712085353224)]

[外链图片转存中…(img-GocpXERz-1712085353225)]

网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。

2021年虽然路途坎坷,都在说Android要没落,但是,不要慌,做自己的计划,学自己的习,竞争无处不在,每个行业都是如此。相信自己,没有做不到的,只有想不到的。祝大家2021年万事大吉。

本文已被CODING开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》收录

一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!

AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算

好文链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: