之前的例子都是我们在子线程(WorkerThread)当中处理并发送消息,然后在主线程(UI线程)中获取消息并修改UI,那么可以不可以在由主线程发送消息,子线程接收呢?我们按照之前的思路写一下代码:

package cn.lixyz.handlertest;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button; public class MainActivity extends Activity { private Button button;
private Handler handler;
private int i = 0; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); button = (Button) findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("TTTT", "onClick:" + Thread.currentThread().getName());
Message msg = handler.obtainMessage();
handler.sendMessage(msg);
}
}); WorkerThread wt = new WorkerThread();
wt.start();
} class WorkerThread extends Thread {
@Override
public void run() {
super.run();
handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
Log.d("TTTT", "收到了消息对象");
}
};
}
}
}

MainActivity.java

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity"> <Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="30dp"
android:text="Send Message" /> </LinearLayout>

activity_main.xml

上面的问题貌似没什么错误,但运行时却出错

抛出异常:

09-17 04:01:31.655  15854-15869/? E/AndroidRuntime﹕ FATAL EXCEPTION: Thread-120
Process: cn.lixyz.handlertest, PID: 15854
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
at android.os.Handler.<init>(Handler.java:200)
at android.os.Handler.<init>(Handler.java:114)
at cn.lixyz.handlertest.MainActivity$WorkerThread$1.<init>(MainActivity.java:48)
at cn.lixyz.handlertest.MainActivity$WorkerThread.run(MainActivity.java:48)

  

提示我们没有调用Looper.prepare(),无法创建线程,原因是非主线程中默认是没有创建Looper对象的,需要先调用Looper.prepare()启用Looper。修改一下上面的代码。

package cn.lixyz.handlertest;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button; public class MainActivity extends Activity { private Button button;
private Handler handler; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); button = (Button) findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Message msg = handler.obtainMessage();
msg.what = 100;
handler.sendMessage(msg);
Log.d("TTTT", "sendMessage:" + Thread.currentThread().getName());
}
}); WorkerThread wt = new WorkerThread();
wt.start();
} class WorkerThread extends Thread {
@Override
public void run() {
super.run();
Looper.prepare();
handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
Log.d("TTTT", "handleMessage:" + Thread.currentThread().getName());
int i = msg.what;
Log.d("TTTT", "收到了消息对象:" + i);
}
};
Looper.loop();
}
}
}

MainActivity.java

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity"> <Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="30dp"
android:text="Send Message" /> </LinearLayout>

activity_main.xml

运行结果:

09-17 04:29:48.669  28397-28397/cn.lixyz.handlertest D/TTTT﹕ sendMessage:main
09-17 04:29:48.669 28397-28410/cn.lixyz.handlertest D/TTTT﹕ handleMessage:Thread-141
09-17 04:29:48.669 28397-28410/cn.lixyz.handlertest D/TTTT﹕ 收到了消息对象:100

上面代码表示,消息是从MainThread发送的,WorkerThread接收到了消息。

 PS:非UI线程默认是没有创建Looper对象的,所以需要主线程向子线程传递消息时,需创建Looper对象并启动循环,子线程才可以循环着从MaessageQueue中取出消息。  

Android笔记(三十二) Android中线程之间的通信(四)主线程给子线程发送消息的更多相关文章

  1. Java 并发编程中的 CountDownLatch 锁用于多个线程同时开始运行或主线程等待子线程结束

    Java 5 开始引入的 Concurrent 并发软件包里面的 CountDownLatch 其实可以把它看作一个计数器,只不过这个计数器的操作是原子操作,同时只能有一个线程去操作这个计数器,也就是 ...

  2. Android 使用handler实现线程间发送消息 (主线程 与 子线程之间)、(子线程 与 子线程之间)

    keyword:Android 使用handler实现线程间发送消息 (主线程 与 子线程之间).(子线程 与 子线程之间) 相信大家平时都有使用到异步线程往主线程(UI线程)发送消息的情况. 本文主 ...

  3. Android线程之主线程向子线程发送消息

    和大家一起探讨Android线程已经有些日子了,谈的最多的就是如何把子线程中的数据发送给主线程进行处理,进行UI界面的更新,为什么要这样,请查阅之前的随笔.本篇我们就来讨论一下关于主线程向子线程如何发 ...

  4. Handler详解系列(四)——利用Handler在主线程与子线程之间互发消息,handler详解

    MainActivity如下: package cc.c; import android.app.Activity; import android.os.Bundle; import android. ...

  5. Handler具体解释系列(四)——利用Handler在主线程与子线程之间互发消息

    MainActivity例如以下: package cc.c; import android.app.Activity; import android.os.Bundle; import androi ...

  6. JAVA进阶----主线程等待子线程各种方案比较(转)

    创建线程以及管理线程池基本理解 参考原文链接:http://www.oschina.net/question/12_11255?sort=time 一.创建一个简单的java线程 在 Java 语言中 ...

  7. 在C#主线程和子线程将数据传递给对方如何实现

    在C#中主线程和子线程怎样实现互相传递数据 老帅 在C#中创建线程Thread时,能够有多种方法,而主线程和子线程之间又怎样实现互相传递数据,每种创建方法传递參数的效果是不同的,逐一看一下:  一.不 ...

  8. [C#参考]主线程和子线程之间的参数传递

    几个进程在大多数情况下要包含很多的子线程,那么他们之间免不了的要互相传递很多的参数,那么参数怎么传递的呢? 主线程向子线程传递参数的方法 第一种方法:Thraed类有一个带参数的委托类型的重载形式,这 ...

  9. Python_线程、线程效率测试、数据隔离测试、主线程和子线程

    0.进程中的概念 三状态:就绪.运行.阻塞 就绪(Ready):当进程已分配到除CPU以外的所有必要资源,只要获得处理机便可立即执行,这时的进程状态成为就绪状态. 执行/运行(Running)状态:当 ...

随机推荐

  1. PAT 甲级 1070 Mooncake (25 分)(结构体排序,贪心,简单)

    1070 Mooncake (25 分)   Mooncake is a Chinese bakery product traditionally eaten during the Mid-Autum ...

  2. 【源码解析】Flink 是如何处理迟到数据

    相信会看到这篇文章的都对Flink的时间类型(事件时间.处理时间.摄入时间)和Watermark有些了解,当然不了解可以先看下官网的介绍:https://ci.apache.org/projects/ ...

  3. c# Invoke的新用法

    在C# 3.0及以后的版本中有了Lamda表达式,像上面这种匿名委托有了更简洁的写法..NET Framework 3.5及以后版本更能用Action封装方法.例如以下写法可以看上去非常简洁: voi ...

  4. GNU C之__attribute__

    __attribute__可以设置函数属性(Function Attribute).变量属性(Variable Attribute)和类型属性(Type Attribute) __attribute_ ...

  5. 如何愉悦使用mybatis

    mybatis-generator+plugins 单独的generator是免不了全部人工的,配上各种插件则不然,感谢项目 itfsw/mybatis-generator-plugin 使用如下: ...

  6. Python29之字符str与字节bytes

    详解见这位大神:https://www.cnblogs.com/xiaobingqianrui/p/9870480.html 实际上字符串和字节之间的转换过程,就是编码解码的过程,我们必须显示的指定编 ...

  7. 关于使用 symfony 3.4.32中Luckynumber 页面的 route 书写

    关于symfony 3.4.32的安装与配置及第一个页面Luckynumber 的route书写 1.symfony 的安装与配置 symfony官网文档:https://symfony.com/do ...

  8. Django模板语言中的Filters的使用方法

    Filters可以称为过滤器.下面我们简单介绍是如何使用他的. Filters的语法: {{ value|filter_name:参数 }} Django大概提供了六十个内置过滤器,下面我们简单介绍几 ...

  9. k8s开发实践

    代码自动生成:https://blog.openshift.com/kubernetes-deep-dive-code-generation-customresources/ 自定义controlle ...

  10. 题解-CSA Beta Round#1 Number Elimination

    Problem CSA-Beta Round#3 题意概要:给定 \(n\) 个数组成的序列,定义一次操作: 在当前序列中选择两个数,将其中较小的数从序列中删除(若两个数相同,则删除在序列中更靠前的) ...