多次调用 Looper 会导致“向死线程上的处理程序发送消息”

2023-12-06

我使用 Executor [固定线程池] 和我自己的 ThreadFactory 添加了 Looper:

Handler HANDLER = new Handler();
Executor    THREADS = Executors.newFixedThreadPool(THREAD_POOL_SIZE, new ThreadFactory() {
    @Override public Thread newThread(Runnable runnable) {
        return new MyThread(new Runnable() {
            @Override public void run() {
                Looper.prepare();
                runnable.run();
            }
        });
    }
});

private static class MyHandler extends Handler {
    public boolean fail;
        public void handleMessage(Message msg) {
        switch(msg.what) {
            case 1:
                this.fail = msg.arg1 == 1;
                Looper.myLooper().quit();
                break;
            }
        }
    }
}

我正在运行一个发出网络请求的线程,但如果网络失败,我希望向用户显示一条对话框消息。这个过程相当复杂,因为它需要在 UI 线程中发出并显示请求。我可以通过简单地向网络线程添加一个循环并等待从 UI 线程发送消息来等待用户对对话框的响应。这允许我将网络请求封装在 while(tryAgain) 线程中。一切正常,除非第二次调用 Looper.loop() 方法(显示第二个网络错误对话框后)并且对话框(在 UI 线程中)向网络线程的处理程序发送一条消息:

THREADS.execute(new Runnable() {
    private MyHandler   myHandler   = new MyHandler();
    @Override public void run() {
        boolean tryAgain    = true;
        while(tryAgain) {
            try {
                switch(request) {
                    [Handle network requests]
                }
                tryAgain    = false;

            } catch(IOException e) {
                // The network is unavailable.  Ask the user if we should try again.
                e.printStackTrace();

            } finally {
                if(tryAgain) {
                    HANDLER.post(new Runnable() {   // The UI thread
                        @Override public void run() {
                            theAlertDialog.show();
                        }
                    });

                    // Wait for the results from the dialog which lives in the UI thread.
                    Looper.loop();

                    // At this point the dialog has informed us of our answer.
                    tryAgain = !myHandler.fail;
                }
            }
        }
    }
});

在AlertDialog实例中是一个OnClickListener:

DialogInterface.OnClickListener myOnclickListener = new DialogInterface.OnClickListener() {
    public void onClick(DialogInterface dialog, int id) {
        Message msg = myHandler.obtainMessage(1);
        msg.setTarget(this.handler);
        msg.sendToTarget();
    }
}

我已经检查过该线程仍然处于活动状态handler.getLooper().getThread().isAlive()它总是返回 true,但它仍然给我“向死线程上的处理程序发送消息”。消息/处理程序如何确定线程已死亡?它不应该依赖 .isAlive() 方法吗?最后,我试图避免将线程管理构建复制到 Android 操作系统中:-)


如果您检查 android/os/MessageQueue.java 中的源代码,您可以看到类似以下内容

  if (mQuiting) {
                RuntimeException e = new RuntimeException(
                    msg.target + " sending message to a Handler on a dead thread");
                Log.w("MessageQueue", e.getMessage(), e);
                return false;
            } else if (msg.target == null) {
                mQuiting = true;
            }
   }

所以在第一次调用 Looper.quit() 后,消息队列基本上无法使用,因为它入队的 Message 目标为空,这是消息队列停止入队并出现“死亡”的神奇标识符。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

多次调用 Looper 会导致“向死线程上的处理程序发送消息” 的相关文章

  • 如何创建在 React-Native 中检测自动位置的地图

    我已经在react native中创建了地图 参考https github com lelandrichardson react native maps https github com lelandrichardson react nat
  • 模拟器中 Google Wear 上的语音识别器没有语音输入

    我试图使用 Google Wear 网站上的自由形式语音输入 在 hello world 示例中 我刚刚添加了对 textView 的单击 它确实从语音意图中调出 立即发言 活动 但模拟器无法检测到我的麦克风发出的任何声音 我使用的是 Ma
  • Android EditText 和 addTextChangedListener

    我目前正在将数据库管理器移植到 Android 由于性能原因 我喜欢 仅更新已修改的属性 我尝试使用 addTextChangedListener 执行此操作 以便将修改后的条目添加到列表中 但我的程序从未输入其任何方法 EditText
  • 用于 Kotlin 中单元测试的 BuildConfigField 模拟

    我正在尝试尽可能多地涵盖Kotlin Android 库我遇到了有关自定义 BuildConfig 变量的问题 更广为人知的是buildConfigField 我想模拟这个变量来测试两者true and false values 从 Gra
  • Android:如何暂停和恢复可运行线程?

    我正在使用 postDelayed 可运行线程 当我按下按钮时 我需要暂停并恢复该线程 请任何人帮助我 这是我的主题 protected void animation music6 music4 postDelayed new Runnab
  • 为什么不能在 Fragment 中使用 ViewPager?它实际上是

    有信息无法使用ViewPager在一个Fragment在许多来源中 例如 Android 开发者繁忙编码指南 http commonsware com 作者 Mark Murphy 或者类似的帖子this https stackoverfl
  • relativelayout导致动画不起作用?

    我有一个活动 其布局仅包含一个 VideoView 这是 XML
  • CoordinatorLayout 和 ImageView 在滚动时调整宽度的问题

    我正在尝试放置一个ImageView in a CollapsingToolbarLayout它在加载时占据整个屏幕 并且当您滚动内容时 16x9 分辨率图像宽度会调整大小 直到图像占据屏幕的整个宽度 那时 我希望图像具有视差app lay
  • Play 商店中的应用描述更新

    我想更新应用程序的描述以及 Play 商店上的屏幕截图 但应用程序保持相同 即相同的版本号 我不想发布新应用程序 因为应用程序中没有任何更改 这可能吗 谷歌也会要求更新应用程序吗 您可以更新描述 也可以更改屏幕截图 您的应用程序将保持不变
  • 自动删除 Firebase 通知

    我有一个问题 我都读过让通知在 5 分钟后消失 https stackoverflow com questions 15648699 make notification disappear after 5 minutes and 几秒钟后清
  • 如何绘制部分位图圆弧?类似于圆形进度轮,但具有显示得越来越多的位图。

    我正在寻找的是一种以顺时针圆形方式显示图像的视图 当进度为 25 时 应显示前 90 度 当进度为 100 时 应绘制完整的 360 度 它与使用 canvas drawArc 非常接近 但此方法仅适用于 Paint 对象 不适用于位图 其
  • FragmentActivity 无法解析为类型

    我正在尝试来自的应用程序这个博客 http android developers blogspot com 2011 02 android 30 fragments api html 在延长的同时FragmentActivity 我收到以下
  • 如何在 60 分钟后删除共享首选项

    我想存储登录数据 但希望在 60 分钟后删除该数据 执行此操作的正确方法是什么 在这 60 分钟内可以关闭 停止 打开应用程序 我不想使用内部数据库 这是我的访问代码SharedPreferences sharedpreferences g
  • AndEngine MenuScene - 无法单击按钮

    我有一个关于 android 和 andengine 的小问题 这是我的主菜单的源代码 AbstractScene is extending Scene public class MainMenuScene extends Abstract
  • Android 操作项上的通知徽章

    我想在操作栏中放置的购物车图像上添加一个通知徽章 并以编程方式操作它 有帮助吗 您可以显示自定义MenuItem on ActionBar通过创建一个custom layout for MenuItem 要设置自定义布局 您必须使用菜单项属
  • Android Google Map V2:如何在单击另一个标记时更改先前单击的标记的图标

    更新 我通过添加 previousMarker 对象解决了性能问题 因此 只有先前单击的标记将被删除并替换为默认图标 但是 当我单击标记时 信息窗口仍然不显示 我有一个地图视图并在上面设置了一些标记 我想要的是 当我单击一个标记时 它将其图
  • Expresso 的 Android 测试首选项片段

    我在通过 Expresso 测试我的代码时遇到问题 我写了这段代码 public class SettingsActivity extends Activity Override protected void onCreate Bundle
  • onPrepareOptionsMenu 复制 ActionBar 中的项目

    当我使用 onPrepareOptionsMenu 添加菜单项时 该菜单项会在操作栏中复制其自身 我正在使用片段并在主要活动的 ActionBar 中创建初始菜单 如下所示 Override public boolean onCreateO
  • 调试android数据绑定?

    谁能告诉我如何调试或找到数据绑定生成的代码 从this https www youtube com watch v NBbeQMOcnZ0链接我发现它生成了所需的代码 我猜您正在寻找自动生成的绑定 java 文件 我也在寻找他们 最后我在这
  • 在数组列表中过滤 Filterable 不取消之前的过滤

    我看过过滤器方法文档 其中显示调用过滤器会取消所有先前未执行的过滤请求 并发布一个稍后将执行的新过滤请求 但我收到的实际回调有些不同 在我的实现中 它不会取消先前的过滤器请求并调用publishResults 最近一次搜索条件后的上一次搜索

随机推荐

  • 我如何告诉 Moq 返回任务?

    我有一个接口声明 Task DoSomethingAsync 我使用 Moq 框架进行测试 TestMethod public async Task MyAsyncTest Mock
  • 如何使用 JAVASCRIPT 播放和暂停嵌入的 Spotify?

    有人可以解释一下如何播放和暂停这个 Spotify 嵌入对象吗 我试图找到该玩家的 ID 但找不到 URL https open spotify com embed podcast show 5iKz9gAsyuQ1xLG6MFLtQg 这
  • 在 AVX2 中重现 _mm256_sllv_epi16 和 _mm256_sllv_epi8

    我很惊讶地看到 mm256 sllv epi16 8 m256i v1 m256i v2 and mm256 srlv epi16 8 m256i v1 m256i v2 不在英特尔内联指南我没有找到任何解决方案来仅使用 AVX2 重新创建
  • 无法在 Ubuntu 上安装 Elastic Beanstalk CLI

    我正在尝试使用以下命令在新的 Ubuntu 14 04 在适用于 Windows 的 Linux 子系统上 上安装 Elastic Beanstalk CLI awsebcli sudo pip install awsebcli 但启动eb
  • 如何从文本文件列表中的单词中删除行?

    file1 gt word list txt gt 超过 1 000 000 行 file2 gt list txt gt 超过 1 000 000 行 我有一个包含单词列表的文件 我想从一个大文本文件中删除此文件中所有单词的所有出现 Ex
  • SQLSTATE[HY093] :插入 mysql 数据库期间的 pdo 语句

    这是我实现插入数据库的php代码
  • Android XML 对象序列化

    我想在 Android 中将对象序列化为 XML 有建议的库吗 PS 已经尝试过 XStream 但它无法在 Android 上正确序列化枚举 问题在这里 Android 中枚举的序列化问题 你有没有尝试过简单的http simple so
  • 为什么 SQL Server 2012 中的变量表回滚不起作用?

    我创建了一个变量表 在我的存储过程中 有很多事务 现在 每当发生错误时 我想回滚特定事务 该事务包含一些从变量表中插入 更新或删除记录的语句 这只是我的实际问题的一个例子 declare tab table val int insert i
  • 进度条属性改变事件不触发

    我正在使用 JProgressBar 显示从 DataBase 加载的数据的进度 我正在使用 SwingWorker 类来加载后台线程中的数据Tutorial 我的应用程序的 ProgressBar 的属性更改事件没有触发 请指导我我做错了
  • PostgreSQL:count() 还是保留一个计数器?

    我有两个处于一对多关系的表 假设对于表中的每一行foo 表中可以有 0 行或多行bar引用该行foo 客户想知道有多少行bar引用一行foo 对于中的所有行foo 我可以通过以下查询来完成此操作 SELECT count bar id FR
  • 在 Matlab 中将字符串单元格转换为双精度型

    我如何转换单元格如下 gt gt A 2 2 23 23 6 A 2 2 23 23 6 为以下双倍 A 2 0000 2 0000 NaN 23 0000 23 6000 str2double可以直接在字符串元胞数组上调用 gt gt X
  • 重新检查文档的拼写是否与 VBA 代码不同

    我想在添加字典后重新检查文档中的拼写 问题是下面的代码 大部分来自宏记录器 CustomDictionaries Add FileName c test dictionary dic Application ResetIgnoreAll A
  • NoClassDefFoundError FirebaseOptions,android?

    当我在设备上运行我的应用程序时 我收到此异常 java lang NoClassDefFoundError com google firebase FirebaseOptions at com google firebase Firebas
  • 如何使用字符串联合填充对象类型的可选嵌套关系?

    我正在尝试创建一个Populate需要 2 个泛型的类型 具有可选关系的对象类型 引用其他对象类型的键 以及可以深度填充 或者更确切地说 设置为非可选 关系的 Path 字符串的联合 例如 有 3 个实体 它们都可以选择性地相互引用 typ
  • 将Actionbarsherlock导入到eclipse中

    有人可以告诉我如何正确导入 SherlockFragmentActivity java 和 ActionBarSherlock 文件夹的步骤吗 我不太确定如何做到这一点 并且在尝试时遇到很多错误 提取 ActionBarSherlock 项
  • javascript eval 可能会带来哪些问题

    我尝试谷歌搜索 但没有得到非常具体的答案 话又说回来 我可能没有使用正确的关键字 有人能指出 javascript eval 可能导致的 安全 问题吗 举个例子 非常好 如果您可以指向具有相同功能的现有网络资源 也可以 Edit 我只需要评
  • MS Access 在传递查询中使用表单

    我有一个名为菲茨 安特 达根 一个名为查询FietsAantDagen和一个名为Txtinput 我正在尝试使用 SQL Server 的直通查询 并使用文本表单的输入作为查询中的输入 Query SELECT Fiets id Fiets
  • 在c++/windows中获取线程状态

    必须有一个函数来获取系统中线程的当前状态 因为有这个应用程序 http www softwareverify com cpp thread status monitor index html 它必须使用某种 API 函数或其他东西 如何在
  • d3嵌套分组条形图

    首先 如果我的英语很难理解 我会尽力的 我对 D3 js 相当陌生 我正在尝试使用嵌套数据创建 D3 分组条形图 我查看了此处共享的一些解决方案 但它们仅显示一级分组 就我而言 数据将来自具有以下数据结构的 csv 文件 groups ca
  • 多次调用 Looper 会导致“向死线程上的处理程序发送消息”

    我使用 Executor 固定线程池 和我自己的 ThreadFactory 添加了 Looper Handler HANDLER new Handler Executor THREADS Executors newFixedThreadP