Looper.loop()引发的惨案

本文详细分析了一位开发者在Android应用中遇到的问题:账号被挤下线后重新登录,请求执行但无回调。经过排查,发现问题是由于Looper.loop()导致的线程池串行执行,使得新任务无法执行。文章介绍了Looper.loop()的工作原理,并提出了避免此类问题的解决方案和对RxJava线程池设计的思考。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、案件描述

在一个安静的下午,一妹子在`技术交流群里反馈(群号:977438066),自己开发的app,账号被挤下线时,重新登录到首页后,发现有一个请求,代码执行了,却没有任何回调,看得出,妹子很着急。

what ??? 还有这种事?原本安静的群,一下活跃了起来,男同胞们一顿狂猜,我总结了下,如下:

  • 会不会请求代码没执行,妹子自己搞错了吧?

  • 发请求前,出现异常,代码被中断运行?

  • 请求过程伴随着页面跳转,导致页面销毁时,请求被自动关闭?

  • 请求过程出现异常,被RxJava全局异常捕获了,并吃掉了,所以收不到失败回调?

这里解释下,妹子采用RxHttp+RxJava结合的方式发请求

经过第一轮询问后,以上猜想轻而易举的被推翻了,我也大概知道了案件的细节,为此,我用代码来还原一下,为简化案件,还原时,我会适当的做出修改,但意思还是那个意思。

2、案件还原

妹子在首页MainActivityOnCreate方法,会并行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() {                           
在Java中,特别是在Android开发中,`Looper`类用于处理线程的消息队列。`Looper.myLooper()`方法用于获取当前线程的`Looper`对象,而`Looper.loop()`方法则用于启动消息循环。以下是详细解释: 1. **Looper.myLooper()**: - 这个方法返回与当前线程关联的`Looper`对象。如果当前线程没有关联的`Looper`,则返回`null`。 - `Looper`对象包含一个消息队列(MessageQueue),用于存储待处理的消息。 2. **Looper.loop()**: - 这个方法用于启动消息循环。它会不断地从消息队列中取出消息,并将其分派给相应的处理程序(Handler)。 - 消息循环会一直运行,直到调用`Looper.quit()`或`Looper.quitSafely()`方法。 以下是一个简单的示例,展示了如何使用`Looper.myLooper()`和`Looper.loop()`: ```java class LooperThread extends Thread { public Handler mHandler; public void run() { // 初始化Looper Looper.prepare(); // 创建Handler并关联到当前线程的Looper mHandler = new Handler() { public void handleMessage(Message msg) { // 处理消息 System.out.println("Received message: " + msg.what); } }; // 获取当前线程的Looper对象 Looper myLooper = Looper.myLooper(); // 启动消息循环 Looper.loop(); } } public class Main { public static void main(String[] args) { LooperThread looperThread = new LooperThread(); looperThread.start(); // 等待线程启动 try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } // 发送消息到Looper线程 looperThread.mHandler.sendEmptyMessage(1); } } ``` 在这个示例中: 1. `LooperThread`类继承自`Thread`,在`run`方法中初始化`Looper`并启动消息循环。 2. `Handler`对象用于处理消息。 3. `Looper.myLooper()`获取当前线程的`Looper`对象。 4. `Looper.loop()`启动消息循环。 5. 在`Main`类的`main`方法中,启动`LooperThread`线程并发送消息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值