虽然使用Intent Service 和创建AsyncTasks是非常有用的捷径,但还是有一些需要创建和管理自己的线程来执行后台处理的场景。通常的情况就是存在长时间运行或者相互联系的线程,它们需要一些比目前两种技术描述的更加微秒或者复杂的管理操作。

这里我们将介绍如何创建和启动新的Thread对象,以及如何在更新UI前与GUI线程同步。

可以使用Android的Handler类与java.lang.Thread中提供的线程类创建和管理子线程。

代码清单如下:

1>布局如下

1.1>效果

1.2>代码如下:

<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>详细代码如下:

package com.demo.cxc.threadhandlerdemo;import android.os.Handler;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;public class MainActivity extends AppCompatActivity {private static final String TAG = "MainActivity";private TextView show_info_tv;private Button start_task_bt;/*//在主线程上初始化一个handler//每个Handler实例,都会绑定到创建他的线程中(一般是位于主线程)//Handler对象初始化后,就默认与对它初始化的进程的消息队列绑定//在这里myHandler与GUI线程(主线程)的消息队列绑定*/private Handler myHandler = new Handler();@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Log.d(TAG, "---onCreate---Thread id:" + Thread.currentThread().getId());initViews();}private void initViews() {Log.d(TAG, "---initViews---thread id:" + Thread.currentThread().getId());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);}View.OnClickListener myButtonClickListener = new View.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---");Thread myThread = new Thread(null,doBackgroundThreadProcessingRunnable, "background");myThread.start();break;default:break;}}};// 执行后台处理方法的Runnableprivate Runnable doBackgroundThreadProcessingRunnable = new Runnable() {@Overridepublic void run() {// TODO Auto-generated method stubLog.d(TAG, "---doBackgroundThreadProcessingRunnable run---thread id :" + Thread.currentThread().getId());backgroundThreadProcessing();}};// 在后台执行一些处理的方法---耗时操作private void backgroundThreadProcessing() {// to-do 耗时操作for (int i = 0; i < 10; i++) {Log.d(TAG, "*****thread id :" + Thread.currentThread().getId() + "---backgroundThreadProcessing---i:" + i);// 当前线程休眠1000mstry {Thread.sleep(1000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}// 在UI主线程上使用Handler发布doUpdateGUI Runnable/** doUpdateGUIRunnable对象并没有新建一个单独的线程,* 而是运行在myHandler所在的线程中,* 在这里就是GUI线程中* */myHandler.post(doUpdateGUIRunnable);}}// 执行updateGUI方法的Runnableprivate Runnable doUpdateGUIRunnable = new Runnable() {@Overridepublic void run() {// TODO Auto-generated method stubLog.d(TAG, "++++++doUpdateGUIRunnable run---thread id :" + Thread.currentThread().getId());updateGUI();}};// 这个方法必须由UI线程调用private void updateGUI() {// to-do 更新UIshow_info_tv.setText(show_info_tv.getText().toString() + "¥¥");}}

2.2>运行效果:

2.3> Log输出如下:

06-04 15:52:12.949  27514-27514/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ ---onCreate---Thread id:1
06-04 15:52:12.949  27514-27514/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ ---initViews---thread id:1
06-04 15:52:19.829  27514-27514/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ ---Start Task Button Click---
06-04 15:52:19.829  27514-28040/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ ---doBackgroundThreadProcessingRunnable run---thread id :14444
06-04 15:52:19.829  27514-28040/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ *****thread id :14444---backgroundThreadProcessing---i:0
06-04 15:52:20.829  27514-28040/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ *****thread id :14444---backgroundThreadProcessing---i:1
06-04 15:52:20.829  27514-27514/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ ++++++doUpdateGUIRunnable run---thread id :1
06-04 15:52:21.829  27514-28040/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ *****thread id :14444---backgroundThreadProcessing---i:2
06-04 15:52:21.829  27514-27514/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ ++++++doUpdateGUIRunnable run---thread id :1
06-04 15:52:22.834  27514-28040/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ *****thread id :14444---backgroundThreadProcessing---i:3
06-04 15:52:22.834  27514-27514/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ ++++++doUpdateGUIRunnable run---thread id :1
06-04 15:52:23.829  27514-28040/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ *****thread id :14444---backgroundThreadProcessing---i:4
06-04 15:52:23.829  27514-27514/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ ++++++doUpdateGUIRunnable run---thread id :1
06-04 15:52:24.829  27514-28040/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ *****thread id :14444---backgroundThreadProcessing---i:5
06-04 15:52:24.829  27514-27514/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ ++++++doUpdateGUIRunnable run---thread id :1
06-04 15:52:25.829  27514-28040/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ *****thread id :14444---backgroundThreadProcessing---i:6
06-04 15:52:25.834  27514-27514/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ ++++++doUpdateGUIRunnable run---thread id :1
06-04 15:52:26.834  27514-28040/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ *****thread id :14444---backgroundThreadProcessing---i:7
06-04 15:52:26.834  27514-27514/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ ++++++doUpdateGUIRunnable run---thread id :1
06-04 15:52:27.834  27514-28040/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ *****thread id :14444---backgroundThreadProcessing---i:8
06-04 15:52:27.839  27514-27514/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ ++++++doUpdateGUIRunnable run---thread id :1
06-04 15:52:28.834  27514-28040/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ *****thread id :14444---backgroundThreadProcessing---i:9
06-04 15:52:28.834  27514-27514/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ ++++++doUpdateGUIRunnable run---thread id :1
06-04 15:52:29.839  27514-27514/com.demo.cxc.threadhandlerdemo D/MainActivity﹕ ++++++doUpdateGUIRunnable run---thread id :1

从以上Log 可以看出,doUpdateGUIRunnable确定是运行在GUI线程中,即myHandler.post(doUpdateGUIRunnable)会使doUpdateGUIRunable对象运行在创建myHandler的线程中,在这里也就是GUI线程中了。

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

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

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

  2. Android---手动创建线程与GUI线程同步(二)

    本文在上一节Android---手动创建线程与GUI线程同步(一)的基础上来进行改进 上一节我们实现了在子线程中进行耗时工作,并通过Handler更改GUI中的UI,但是我们并不能通过它来获取后台工作 ...

  3. Android手动创建和解析Json

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

  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. IT痴汉的工作现状25-技术之养成
  2. 【css】垂直居中的几种写法
  3. [codevs 1033] 蚯蚓的游戏问题
  4. Django项目知识点(五)
  5. PyQt5:窗口的基本功能
  6. IBATISNETNET 1.3 开发指南系列文章
  7. 【kali】kali环境下安装dvwa
  8. 科学数据中心资源和用户访问控制体系
  9. linux的创建线程池,Linux下通用线程池的创建与使用(上) (3)
  10. CCF201703-5 引水入城(100分题解链接)
  11. 项亮《推荐系统实践》读书笔记1-推荐系统评价指标
  12. web前端实训day06——学子商城登录页面实现
  13. 【离散数学】高级计数技术
  14. 数据库设计--企业人事管理系统(有关数据库的课程设计)
  15. Field II 超声声场仿真(2): 接收灵敏度(原理代码)
  16. 【HTML 教程系列第 9 篇】什么是 HTML 中的换行标签 br
  17. 虚拟化高级应用、Win快捷键操作 、 Win+R快速调用
  18. 分布式丛林探险系列之 Redis 主从复制模式
  19. 2022年茶艺师(初级)考试模拟100题及答案
  20. 中国的各地节日美食都又哪些

热门文章

  1. 2015结束,2016开始
  2. iOS 远程通知(Remote Notification)和本地通知(Local Notification)
  3. 如何在Access中参数化日期类型,以解决Data type mismatch in criteria expression的问题...
  4. CTime,Systemtime的比较还有转换成日期格式。
  5. C# 2.0 套接字编程实例初探
  6. VBA自定义函数集锦[2]
  7. 搜索引擎优化不是网页标签优化
  8. 20165214 2018-2019-2 《网络对抗技术》Exp6 信息搜集与漏洞扫描 Week9
  9. 软件工程——结对编程第一次作业
  10. android style 中一些颜色的定义