V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  hongch  ›  全部回复第 46 页 / 共 46 页
回复总数  915
1 ... 37  38  39  40  41  42  43  44  45  46  
2018-09-12 09:31:17 +08:00
回复了 littleBeats 创建的主题 酷工作 蚂蚁金服(支付宝)杭州 招聘客户端开发
android 招吗
2018-09-11 16:22:26 +08:00
回复了 ophunter 创建的主题 iOS IOS 入门
ios 搭个 rn 容器 用 rn 搞定
2018-09-11 11:37:46 +08:00
回复了 Lee97 创建的主题 兰州 缺个程序猿系列,手动狗头
那么问题来了 薪资呢?
2018-09-11 10:07:02 +08:00
回复了 jabez 创建的主题 MacBook Pro 想入一个 mbp 13 寸的 15 17 款都 ok 有没有大佬出的
@wavever 同 android 开发,准备出 17 款 15 寸 MBP 灰色 带 BAR 256 电池循环 22 次 99 新
2018-09-11 10:06:16 +08:00
回复了 ZXay1er 创建的主题 MacBook Pro 16 款 MBP15 低配现在能出多少?
@wangxinghua 17 款 15 寸 MBP 灰色 带 BAR 256 电池循环 22 次 99 新 考虑妈
2018-09-11 10:05:06 +08:00
回复了 junceo 创建的主题 MacBook Pro 有没有大佬出 15 款 MBP ? MF839
17 款 15 寸 MBP 灰色 带 BAR 256 电池循环 22 次 99 新 准备出了
@ioth 打扰了👋
@whileFalse - - 好吧 那我对仅拆封或通电不超过一天的定位是 几乎全新
@Hilong 想出 14 左右
2018-09-03 08:35:00 +08:00
回复了 hongch 创建的主题 Android Android 新人写的网络框架 有大神提点意见吗?
- -
2018-08-31 18:03:40 +08:00
回复了 storypanda 创建的主题 Android Android 入门,求推荐书籍
建议放弃 夕阳产业
---------------------刚毕业 2 个月的 android 开发者
2018-08-23 14:58:56 +08:00
回复了 hongch 创建的主题 Android Android 新人写的网络框架 有大神提点意见吗?
# 历时 2 天,完成了用 kotlin 写网络框架
## 1.错误统一处理</br>
## 2.和服务端约定 response 格式,剥离出 data</br>
## 3.MVVM</br>
## 4.DTO-VO 转换</br>
## 5.Activity 层几乎没有代码,极度简洁</br>

---
#先上效果图 </br>

1 )首先新建一个 VM 类,用于网络请求</br>
```
class MainVM {
fun getData(callback: DesCallBack<HCVO>) {
return ApiClient
.instance
.getApiService()
.test()
.compose(RxStreamHelper().io_Main())
.map {
it.transform()
}
.subscribe(Destiny(callback))
}
}
```
</br>

2 )利用 map 操作符将 DTO 转为业务所需的 VO </br>
```
.map {
it.transform()
}
```
3 )然后通过 callback 的方式将 data 暴露给 activity,具体业务场景不同,有时候可能需要 Observer 的 complete</br>


4 )最后调用 VM 的方法可以看到 View 层只有几行代码,极大程度降低了业务与逻辑的冗余度,</br>
```
fun request() {
val mainVM = MainVM()
mainVM.getData(object : DesCallBack<HCVO> {
override fun success(any: HCVO) {
Log.i("success", any.name)
}
override fun failed(e: Throwable) {
}
})
}
```
</br>
如果用上 databinding Activity 只需要请求网络就可以了 是不是很方便?
---

# 具体实现</br>
## 一、Retrofit 的封装</br>
kotloin 对于 coder 来说,简化了大量代码,双重检查单例只需要一行代码</br>
```
val instance: ApiClientby lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED){
ApiClient()
}
```
</br>
这样就保证了全局只有一个 retrofit 对象
</br>

接口层没什么变化,不过是 kotlin 的语法不一样

这样就完成了 retrofit 的封装

---
## 二、服务端返回的数据处理</br>
### 1 )首先定义一个基础类型,这里是服务端返回的格式,分别为 code,msg,和 data,在后期我们要将 data 单独剥离出来给具体的业务使用,code 和 msg 与业务无关
```
open class BaseModel<T> {
var code: Int? = null
var msg: String? = null
var data: T? = null
}
```
### 2 )错误处理,错误分为服务端错误和本地错误</br>

1.本地错误:在 onErrorResumeNext()的时候返回自定义的 exception,通过 Observable.error()发射出去</br>


具体的 CustomException 如图所示,判断 throwable 类型,自定义的 exception</br>

```
class CustomException {
companion object {

fun handleException(e: Throwable): ApiException {
if (e is HttpException) {
var ex = ApiException(e.code(), e.message(), e)
when (ex.code) {
UNAUTHORIZED -> ex.msg("未授权的请求")
FORBIDDEN -> ex.msg("禁止访问")
NOT_FOUND -> ex.msg("服务器地址未找到")
REQUEST_TIMEOUT -> ex.msg("请求超时")
GATEWAY_TIMEOUT -> ex.msg("网关响应超时")
INTERNAL_SERVER_ERROR -> {
ex.msg("服务器出错")
ex.msg("无效的请求")
}
BAD_GATEWAY -> ex.msg("无效的请求")
SERVICE_UNAVAILABLE -> ex.msg("服务器不可用")
ACCESS_DENIED -> ex.msg("网络错误")
HANDEL_ERROR -> ex.msg("接口处理失败")

else -> {
if (TextUtils.isEmpty(ex.msg)) {
ex.msg(e.message!!)
}

if (TextUtils.isEmpty(ex.msg) && e.getLocalizedMessage() != null) {
ex.msg(e.getLocalizedMessage())
}
if (TextUtils.isEmpty(ex.msg)) {
ex.msg("未知错误")
}
}
}
return ex
} else if (e is JSONException || e is ParseException) {
var ex = ApiException(PARSE_ERROR, e.message, e)
ex.msg("解析错误")
return ex
} else if (e is ConnectException) {
var ex = ApiException(NETWORK_ERROR, e.message, e)
ex.msg("连接失败")
return ex
} else if (e is javax.net.ssl.SSLHandshakeException) {
var ex = ApiException(SSL_ERROR, e.message, e)
ex.msg("证书验证失败")
return ex
} else if (e is java.security.cert.CertPathValidatorException) {
var ex = ApiException(SSL_NOT_FOUND, e.message, e)
ex.msg("证书路径没找到")

return ex
} else if (e is SSLPeerUnverifiedException) {
var ex = ApiException(SSL_NOT_FOUND, e.message, e)
ex.msg("无有效的 SSL 证书")
return ex

} else if (e is ConnectTimeoutException) {
var ex = ApiException(TIMEOUT_ERROR, e.message, e)
ex.msg("连接超时")
return ex
} else if (e is java.net.SocketTimeoutException) {
var ex = ApiException(TIMEOUT_ERROR, e.message, e)
ex.msg("连接超时")
return ex
} else if (e is java.lang.ClassCastException) {
var ex = ApiException(FORMAT_ERROR, e.message, e)
ex.msg("类型转换出错")
return ex
} else if (e is NullPointerException) {
var ex = ApiException(NULL, e.message, e)
ex.msg("数据有空")
return ex
} else if (e is FormatException) {

var ex = ApiException(-200, e.message, e)
ex.msg("服务端返回数据格式异常")
return ex
} else if (e is UnknownHostException) {
var ex = ApiException(NOT_FOUND, e.message, e)
ex.msg("服务器地址未找到,请检查网络或 Url")
return ex
} else {
var ex = ApiException(UNKNOWN, e.message, e)
ex.msg("未知异常")
return ex
}
}

}
}
```
### 3 )数据剥离,用到了 flatMap,此处解析服务端有关的错误,如果 code 等于 200,则代表接口请求成功,否则通过 Observable.error()抛出</br>
```
.flatMap { tBaseModel ->
if (tBaseModel.code == 200) {
Observable.just(tBaseModel.data!!)
} else Observable.error(ApiException(tBaseModel.code!!, tBaseModel.msg!!))
}
```
### 4 )线程调度,在子线程请求,在主线程处理</br>
```
upstream
. subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
```
通过 4 个操作符之后我们完成了以上任务,最后通过 compose 操作将这个操作集合合并为一个简化代码

github 地址: https://github.com/honglvt/NetWorkUtil
2018-08-23 14:15:28 +08:00
回复了 hongch 创建的主题 Android Android 新人写的网络框架 有大神提点意见吗?
谢谢各位大佬的 star
2018-08-23 10:45:56 +08:00
回复了 ophunter 创建的主题 Android 请假下 Jenkins 问题
不要用默认的 gradle 脚本脚本
在打包最后写一个 shell
1.npminstall

2.react-native bundle --platform android --dev false --entry-file index.android.js --bundle-output app/src/main/assets/index.android.bundle --assets-dest app/src/main/res/

3../gradlew $build_action
1 ... 37  38  39  40  41  42  43  44  45  46  
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1269 人在线   最高记录 6543   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 43ms · UTC 17:44 · PVG 01:44 · LAX 10:44 · JFK 13:44
Developed with CodeLauncher
♥ Do have faith in what you're doing.