本文在上一节Android---手动创建线程与GUI线程同步(一)的基础上来进行改进

上一节我们实现了在子线程中进行耗时工作,并通过Handler更改GUI中的UI,但是我们并不能通过它来获取后台工作线程返回数据。这时可以通过对上一节的代码进行改进。重写Handler的handleMessage方法,具体代码如下:

1>布局与上一节一致

代码如下:

<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"android:paddingBottom="@dimen/activity_vertical_margin"android:paddingLeft="@dimen/activity_horizontal_margin"android:paddingRight="@dimen/activity_horizontal_margin"android:paddingTop="@dimen/activity_vertical_margin"tools:context="com.cxc.threadandhandler.MainActivity" ><TextViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:text="Thread用于耗时任务 + Handler用于GUI同步" /><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal" ><TextViewandroid:id="@+id/show_info_tv"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="显示后台任务情况" /><Buttonandroid:id="@+id/start_task_bt"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Start Task" /></LinearLayout></LinearLayout>

2>具体代码如下:

2.1>MainActivity代码如下:

package com.cxc.threadandhandler;import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;public class MainActivity extends Activity {private static final String TAG = "com.cxc.threadandhandler.mainactivity";private TextView show_info_tv;private Button start_task_bt;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Log.d(TAG, "---onCreate---");initViews();}private void initViews() {Log.d(TAG, "---initViews---");show_info_tv = (TextView) findViewById(R.id.show_info_tv);start_task_bt = (Button) findViewById(R.id.start_task_bt);start_task_bt.setOnClickListener(myButtonClickListener);}OnClickListener myButtonClickListener = new OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubswitch (v.getId()) {case R.id.start_task_bt:// to-do// 将耗时的操作移到子线程中Log.d(TAG, "---Start Task Button Click---");BackgroundThread backgroundThread = new BackgroundThread();Thread myThread = new Thread(backgroundThread);myThread.start();break;default:break;}}};class BackgroundThread implements Runnable {private MyHandler mMyHander = null;private HandlerThread mhandlerThread = null;public BackgroundThread() {// TODO Auto-generated constructor stubmhandlerThread = new HandlerThread("handler_thread");mhandlerThread.start();mMyHander = new MyHandler(mhandlerThread.getLooper());}@Overridepublic void run() {// TODO Auto-generated method stubLog.d(TAG,"-----work thread ---"+Thread.currentThread().getId());backgroundThreadProcessing();}// 在后台执行一些处理的方法---耗时操作private void backgroundThreadProcessing() {// to-do 耗时操作Log.d(TAG,"-----work thread -backgroundThreadProcessing ---"+Thread.currentThread().getId());for (int i = 0; i < 10; i++) {Bundle bundle = new Bundle();// 设置参数bundle.putString("info", "----后台处理情况--" + i);Message msg = mMyHander.obtainMessage();msg.setData(bundle);msg.sendToTarget();Log.d(TAG, "***"+Thread.currentThread().currentThread().getId()+"-send:" + "----后台处理情况--" + i);//myHandler.sendMessage(msg);try {Thread.sleep(1000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}class MyHandler extends Handler {// 构造函数public MyHandler() {}public MyHandler(Looper looper) {super(looper);}@Overridepublic void handleMessage(Message msg) {// TODO Auto-generated method stubsuper.handleMessage(msg);// 接收“后台”线程发送来的参数Bundle bundle = msg.getData();String str = bundle.getString("info");Log.d(TAG, "---"+Thread.currentThread().currentThread().getId()+"-receive:" + str);// 在这里不能设置TextView 的值,因为此时Handler没有运行在GUI线程中//show_info_tv.setText(str);}}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {// Inflate the menu; this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.main, menu);return true;}@Overridepublic boolean onOptionsItemSelected(MenuItem item) {// Handle action bar item clicks here. The action bar will// automatically handle clicks on the Home/Up button, so long// as you specify a parent activity in AndroidManifest.xml.int id = item.getItemId();if (id == R.id.action_settings) {return true;}return super.onOptionsItemSelected(item);}
}

2.3>Log如下:

06-04 16:17:27.694  18409-18409/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ ---onCreate---
06-04 16:17:27.694  18409-18409/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ ---initViews---
06-04 16:17:30.239  18409-18409/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ ---Start Task Button Click---
06-04 16:17:30.249  18409-18664/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ -----work thread ---14937
06-04 16:17:30.254  18409-18664/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ -----work thread -backgroundThreadProcessing ---14937
06-04 16:17:30.254  18409-18664/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ ***14937-send:----后台处理情况--0
06-04 16:17:30.254  18409-18661/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ ---14936-receive:----后台处理情况--0
06-04 16:17:30.254  18409-18664/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ ***14937-send:----后台处理情况--1
06-04 16:17:30.254  18409-18661/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ ---14936-receive:----后台处理情况--1
06-04 16:17:30.254  18409-18664/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ ***14937-send:----后台处理情况--2
06-04 16:17:30.254  18409-18661/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ ---14936-receive:----后台处理情况--2
06-04 16:17:30.254  18409-18664/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ ***14937-send:----后台处理情况--3
06-04 16:17:30.254  18409-18661/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ ---14936-receive:----后台处理情况--3
06-04 16:17:30.254  18409-18664/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ ***14937-send:----后台处理情况--4
06-04 16:17:30.254  18409-18661/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ ---14936-receive:----后台处理情况--4
06-04 16:17:30.259  18409-18664/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ ***14937-send:----后台处理情况--5
06-04 16:17:30.259  18409-18661/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ ---14936-receive:----后台处理情况--5
06-04 16:17:30.259  18409-18664/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ ***14937-send:----后台处理情况--6
06-04 16:17:30.259  18409-18661/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ ---14936-receive:----后台处理情况--6
06-04 16:17:30.259  18409-18664/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ ***14937-send:----后台处理情况--7
06-04 16:17:30.259  18409-18661/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ ---14936-receive:----后台处理情况--7
06-04 16:17:30.259  18409-18661/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ ---14936-receive:----后台处理情况--8
06-04 16:17:30.259  18409-18664/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ ***14937-send:----后台处理情况--8
06-04 16:17:30.259  18409-18664/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ ***14937-send:----后台处理情况--9
06-04 16:17:30.259  18409-18661/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ ---14936-receive:----后台处理情况--9

从Log日志来看,mMyHandler确定没有运行在GUI线程中,所以也就不能在使用更改UI了。

这里需要注意,这里用到的多线程并非由Runnable对象开启的,而是ThreadHandler对象开启的。Runnable对象只是作为一个封装了操作的对象被传递,并未产生新线程。

Android---手动创建线程与GUI线程同步(二)相关推荐

  1. Android---手动创建线程与GUI线程同步(三)

    Android---手动创建线程与GUI线程同步的第三种方法: 在GUI线程中调用runOnUiThread(Runnable runnable), 此时work Thread与GUI线程在同一个线程 ...

  2. Android手动创建和解析Json

    Android手动创建和解析Json 概述 现在Android开发中创建和解析Json大都是利用Gson.fastJson等可以映射对象的第三方库,确实非常方便,使用Gson解析可以参考我的另一篇文章 ...

  3. Android---手动创建线程与GUI线程同步(一)

    虽然使用Intent Service 和创建AsyncTasks是非常有用的捷径,但还是有一些需要创建和管理自己的线程来执行后台处理的场景.通常的情况就是存在长时间运行或者相互联系的线程,它们需要一些 ...

  4. android手动创建数据表,Android开发—数据库应用—手动创建(SQLite)数据库--手动创建数据表(table)...

    /* (程序头部注释开始) * 程序的版权和版本声明部分 * Copyright (c) 2011, 烟台大学计算机学院学生 * All rights reserved. * 文件名称:数据库应用-手 ...

  5. 我会手动创建线程,为什么让我使用线程池?

    你有一个思想,我有一个思想,我们交换后,一个人就有两个思想 If you can NOT explain it simply, you do NOT understand it well enough ...

  6. 消息机制(GUI线程讲解)

    文章目录 前奏 窗口代码 你能回答这些问题吗? 消息队列: 消息队列在何处呢? 那么Windows如何解决的呢? 重点: 总结: 前奏 首先我们来画一个窗口: 窗口代码 #include<Win ...

  7. android 多线程创建texture,从源码角度剖析Android系统EGL及GL线程

    本文转载自天天P图攻城狮微信公众号,作者:天天P图Android工程师kenneyqin(覃华峥),原文链接https://mp.weixin.qq.com/s/j_N5_C7iQUPWENdRYfj ...

  8. java 多线程编程(包括创建线程的三种方式、线程的生命周期、线程的调度策略、线程同步、线程通信、线程池、死锁等)

    1 多线程的基础知识 1.1 单核CPU和多核CPU 单核CPU,其实是一种假的多线程,因为在一个时间单元内,也只能执行一个线程的任务.微观上这些程序是分时的交替运行,只不过是给人的感觉是同时运行,那 ...

  9. 手把手教你手动创建线程池

    点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达 今日推荐:2020,搞个 Mac 玩玩!个人原创+1博客:点击前往,查看更多 作者:IamHYN 链接:https://s ...

最新文章

  1. 2018.12.28-bzoj-2006-[NOI2010]超级钢琴
  2. Qt 静态编译后的exe太大, 可以这样压缩.
  3. 时间同步软件 windows_电脑上好用的便利贴软件,PC端便签软件
  4. MATLAB-Direct access of structure fields returned by a function call is not allowed 的解决方法~
  5. [watevrCTF-2019]Pickle Store
  6. 《逻辑与计算机设计基础(原书第5版)》——3.9 二进制加法器
  7. java版本的getorcreate,getOrCreate for java-rest-api neo4j失敗
  8. 东明县计算机学校,东明县职业中等专业学校2021年招生信息
  9. 红帽:将开源进行到底
  10. 课题开题报告范文样本_成都汽车职业技术学校举行 2020年省、市、区课题开题报告会...
  11. 探讨 | 深入探讨Redis管道
  12. android 自定义布局 根据布局获取类,android自定义布局中的平滑移动之ViewGroup实现...
  13. fhq-treap模板
  14. debian安装gcolor2
  15. java 测试 jar_java – 从可执行jar运行spring测试
  16. atitit.软件设计模式大的总结attialx总结
  17. 高质量病毒——暴风一号(BoyFine)代码.vbs
  18. 联想微型计算机v1.0,联想Energy Management
  19. java前后端分离使用token_前后端分离以及token的使用
  20. 9门主流编程语言---详细对比

热门文章

  1. C# 打开Word文档错误
  2. POJ1226 Substrings(二分+后缀数组)
  3. Mac下Sublime text2中文乱码问题的解决
  4. jquery 获取checkbox的checked属性总是undefined
  5. java中的神奇this
  6. java 中的 Scanner
  7. FPGrowth算法总结复习
  8. HTML5-Canvas 图形变换+状态保存
  9. SimpleDateFormat使用方法详解
  10. 好长时间没有到博客园来看看了