会不会请求代码没执行,妹子自己搞错了吧?
发请求前,出现异常,代码被中断运行?
请求过程伴随着页面跳转,导致页面销毁时,请求被自动关闭?
请求过程出现异常,被RxJava
全局异常捕获了,并吃掉了,所以收不到失败回调?
这里解释下,妹子采用RxHttp+RxJava结合的方式发请求
经过第一轮询问后,以上猜想轻而易举的被推翻了,我也大概知道了案件的细节,为此,我用代码来还原一下,为简化案件,还原时,我会适当的做出修改,但意思还是那个意思。
2、案件还原
妹子在首页MainActivity的OnCreate方法,会并行3个请求,如下:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
request1();
request2();
request3();
}
public void request1() {
RxHttp.get("/service/…")
.asString()
.to(RxLife.toMain(this)) //页面销毁,自动关闭请求,并在UI线程回调
.subscribe(s -> {
//成功回调
}, throwable -> {
//异常回调
});
}
public void request2() {
//省略请求代码,请求代码类似request1()方法
}
public void request3() {
//省略请求代码,请求代码类似request1()方法
}
这段代码看起来并没有任何问题,正常登录进来后,都是正常的。
但是当账号被挤下线后(挤到登录页),重新登录到首页后,发现request1()
、request2()
、request3()
三个请求方法都执行了,可request2()
方法却迟迟收不到回调,不管成功/失败都收不到。
3、开始办案
以上猜想全部被推翻,接下来怎么办?很明显,我们要明确一点:
请求到底有没有发出去?服务端有没有收到这个请求?
随后,妹子用Adnroid Studio
自带的Profiler
工具,监控了下,发现请求并未发出来,接着,又找后台人员确认了下,后台也并未收到这个请求。
那就更奇怪了,请求代码执行了,请求却没有发出去?作为程序员的我第一反应,这怎么可能呢?妹子你用的手机有问题吧?要不换个手机试试?显然换了手机,问题一样存在,这就尴尬了。
接下来,跟妹子不断的调试,一而再,再而三的确认了,请求代码没有任何问题,然而,我却陷入了沉思之中,很绝望,很无助,甚至怀疑这是OkHttp
的问题。
作为一名老鸟,最后我还是冷静了下来,重新整理了线索,发现又一条线索被遗漏了,那就是账号被挤,自动跳转到登录页面,为什么只有在账号被挤时,才会出现问题?于是乎,我调整了调查方向
账号是如何被挤?又是如何跳转到登录页面的?
终于,凶手露出了水面,凶手就是Looper
,原来妹子是通过OkHttp
的拦截器来监听账号被挤,并通过Looper
来弹出一个Toast提示,并且执行页面跳转逻辑,如下:
public class TokenInterceptor implements Interceptor {
private Context context;
//省略部分代码
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Response originalResponse = chain.proceed(request);
String code = originalResponse.header(“code”);
if ("-1".equals(code)) { //账号被挤
Looper.prepare();
Toast.makeText(context, “你的账号在其它设备上登录”, Toast.LENGTH_LONG).show();
context.startActivity(new Intent(context, LoginActivity.class));
Looper.loop();
}
return originalResponse;
}
}
也许你会问,这确定有问题?通过Looper
在子线程弹出一个Toast
,这不是很正常的一件事?经常这么干,从来没出现任何问题,为啥到你这就出问题?
我让妹子把Looper
及Toast
代码注释掉,if语句里面只保留一行startActivity
,妹子试后开心的跟我说,好了,没问题了,这怎么解释?
4、开始破案
Looper
一脸委屈的说道:你说我是凶手,我就是凶手了,证据呢?
ok,我们就来寻找证据,我们知道,Looper.loop()
方法内部,会开启一个死循环,如下:
public static void loop() {
//省略部分代码
for (; {
Message msg = queue.next(); // might block
if (msg == null) {
// No message indicates that the message queue is quitting.
return;
}
//省略部分代码
}
//省略部分代码
}
作者2013年java转到Android开发,在小厂待过,也去过华为,OPPO等大厂待过,18年四月份进了阿里一直到现在。
被人面试过,也面试过很多人。深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长,而且极易碰到天花板技术停滞不前!
我们整理了一份阿里P7级别的Android架构师全套学习资料,特别适合有3-5年以上经验的小伙伴深入学习提升。
主要包括腾讯,以及字节跳动,阿里,华为,小米,等一线互联网公司主流架构技术。
![腾讯T3架构师学习专题资料](https://upload-images.jianshu.io/upload_images/24099992-a92eaf12abc534b6.gif?imageMogr2/auto-orient/str
ip)
如果你觉得自己学习效率低,缺乏正确的指导,可以一起学习交流!
我们致力打造一个平等,高质量的Android交流圈子,不一定能短期就让每个人的技术突飞猛进,但从长远来说,眼光,格局,长远发展的方向才是最重要的。
35岁中年危机大多是因为被短期的利益牵着走,过早压榨掉了价值,如果能一开始就树立一个正确的长远的职业规划。35岁后的你只会比周围的人更值钱。
orient/str
[外链图片转存中…(img-IDx8GYrG-1647772164354)]
ip)
如果你觉得自己学习效率低,缺乏正确的指导,可以一起学习交流!
我们致力打造一个平等,高质量的Android交流圈子,不一定能短期就让每个人的技术突飞猛进,但从长远来说,眼光,格局,长远发展的方向才是最重要的。
35岁中年危机大多是因为被短期的利益牵着走,过早压榨掉了价值,如果能一开始就树立一个正确的长远的职业规划。35岁后的你只会比周围的人更值钱。