Android 主线程与子线程区分和实践
前言
这个是一个入门的话题但是也要通透的简单的说一下对于学过java或者Android的都知道,在代码中主线程不能进行耗时操作,子线程不能更新UI,比如在自定义view时,想要让View重绘,需要先判断当前线程到底是不是主线程,然后根据判断结果来决定到底是调用 invalidate() 还是 postInvalidate() 方法. 如果当前是主线程,就调用 invalidate()方法;而如果当前是子线程,就调用 postInvalidate() 方法,注意:子线程中不能调用 invalidate() 方法,否则就会报异常,提示我们不能在子线程中更新UI。
那么该这么判断呢?可以用这个来进行判断
boolean b = Thread.currentThread() == Looper.getMainLooper().getThread();
方式1:
打个比方如果我们不知道onCreate是不是主线程怎么办(当然onCreate肯定是主线程)用这个先判断一下,然后再决定是否做耗时操作
public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);boolean b = Thread.currentThread() == Looper.getMainLooper().getThread();Toast.makeText(MainActivity.this, b+"", Toast.LENGTH_SHORT).show();}
}
结果是返回true确定了是主线程(我们可以在这里更新UI比如setText,Toast等)但是这个时候我们就不能做耗时操作了,会有人问什么是耗时操作呢?
例如
1.下载文件
2.文件操作
3.比较大的数据初始化操作
4.音频格式转换
5.网络链接操作
等
那么有这个些操作的时候就应该在主线程创建个子线程了,在Thread里面操作
public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);new Thread(new Runnable() {@Overridepublic void run() {boolean b = Thread.currentThread() == Looper.getMainLooper().getThread();//这个不是耗时操作}}).start();}
}
这个时候Thread.currentThread() == Looper.getMainLooper().getThread()这个结果肯定是false了但是这个我为啥没有在Thread里面添加Toast呢?答案是Toast是UI操作,但是我们不能在子线程做UI操作这个时候我们应该切换到主线程Toast
public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);new Thread(new Runnable() {@Overridepublic void run() {boolean b = Thread.currentThread() == Looper.getMainLooper().getThread();runOnUiThread(new Runnable() {@Overridepublic void run() {Toast.makeText(MainActivity.this, b+"", Toast.LENGTH_SHORT).show();}});}}).start();}
}
这样返回的就是false了因为我们是在子线程里面获取的Thread.currentThread(),如果在runOnUiThread里面获取Thread.currentThread()再Toast那就是true了。
但是要考虑一种情况就是Runnable是一个匿名内部类,所以它会持有当前Activity的隐式引用。如果Activity销毁,但是线程任务还未执行完毕,就会导致Activity无法被GC回收,造成内存泄漏。
public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);new Thread(new mRunnable()).start();}private static class mRunnable implements Runnable{@Overridepublic void run() {boolean b = Thread.currentThread() == Looper.getMainLooper().getThread();runOnUiThread(new Runnable() {@Overridepublic void run() {Toast.makeText(MainActivity.this, b+"", Toast.LENGTH_SHORT).show();}});}}
}
方式2
第二种方式是用Handler话不多说上代码,这种方式的通信打个比方就是软件开屏页面倒计时会用到
public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);HandlerThread handlerThread = new HandlerThread("HandlerThread");handlerThread.start();Handler handler=new Handler(handlerThread.getLooper()){@Overridepublic void handleMessage(@NonNull Message msg) {super.handleMessage(msg);if (msg.what==1){Log.e("handlerThread=====","子线程执行");}}};Log.e("handlerThread=====","主线程执行");handler.sendEmptyMessage(1);}
}
//附上handler销毁的方式需要的话可以手动销毁
handler.removeCallbacksAndMessages(null);
结尾
编码过程中答案不唯一按照自己的思路进行,查漏补缺都会是一个很好的锻炼
Android 主线程与子线程区分和实践相关推荐
- android主线程和子线程的区别
android 主线程和子线程有什么区别 本文较为深入的分析了android中UI主线程与子线程.分享给大家供大家参考. 具体如下:在一个Android 程序开始运行的时候,会单独启动一个Proces ...
- android线程通信方式,Android 主线程和子线程通信问题
Android 如今不支持View在子线程中创建及调用其方法.假设要实现子线程内容更新之后.将结果及时反馈到主线程中,该怎样出来呢? 能够在主线程中创建Handler来实现. 这样子线程的结果.能够通 ...
- android 主线程和子线程交互方式
在android的设计思想中,为了确保用户顺滑的操作体验.一些耗时的任务不能够在UI线程中运行,像访问网络就属于这类任务.因此我们必须要重新开启一个后台线程运行这些任务.然而,往往这些任务最终又会直接 ...
- Android线程之主线程向子线程发送消息
和大家一起探讨Android线程已经有些日子了,谈的最多的就是如何把子线程中的数据发送给主线程进行处理,进行UI界面的更新,为什么要这样,请查阅之前的随笔.本篇我们就来讨论一下关于主线程向子线程如何发 ...
- android子线程没有运行完,android假如主线程依赖子线程A的执行结果,如何让A执行完成,之后主线程再往下执行呢?...
/* String ObjectResult="原先的结果"; //使用VOLLY框架(与问题无关) JsonObjectRequest jsonObjectRequest = n ...
- Android之HandlerThread源码分析和简单使用(主线程和子线程通信、子线程和子线程通信)
1.先熟悉handler方式实现主线程和子线程互相通信方式,子线程和子线程的通信方式 如果不熟悉或者忘记了,请参考我的这篇博客 Android之用Handler实现主线程和子线程互相通信以及子 ...
- java中子线程与主线程通信_Android笔记(三十二) Android中线程之间的通信(四)主线程给子线程发送消息...
之前的例子都是我们在子线程(WorkerThread)当中处理并发送消息,然后在主线程(UI线程)中获取消息并修改UI,那么可以不可以在由主线程发送消息,子线程接收呢?我们按照之前的思路写一下代码: ...
- android 线程传递数据,Android Handle主线程向子线程发送数据
一.前言: 今天,下载apk的时候,下载进度回调到主线程,主线程刷新通知栏,造成页面阻塞掉,不能点击页面(下载结束后,可以正常点击页面). 所以,要在进度回调发送消息到子线程,在子线程的Handler ...
- Android的主线程与子线程
在上一篇文章Android的进程.线程与优先级中我们提到: 线程(thread):是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.一个进程至少对应一个线程. CP ...
最新文章
- 【JavaScript】核心语法之数组
- 从C语言的角度重构数据结构系列(三)- 顺序存储结构和链式存储结构之顺序表
- CNS级lncRNA权威文章解读及前沿发展
- 关于数组方面的算法分析
- 京东扩招 1.5 万员工;程维卸任快的打车法人;库克纪念乔布斯 64 岁诞辰 | 极客头条...
- 获取当前组策略配置的信息
- python---保留两位小数
- 大众给于微软Win8平板过于热情的期待,多属盲目行为
- oracle地理数据库,Oracle 中的多个地理数据库 (geodatabase)
- php sqlite并发访问,PHP基于文件锁实现sqlite的并发操作
- 网站如何被百度蜘蛛快速抓取?
- java练手小项目雷霆战机
- Could not acquire change log lock. Currently locked by XXX
- 【数论】GDKOI day1 讲座(数论基本知识 详)
- 数据分析方法-AARRR用户增长模型
- iOS支付宝、微信支付
- Android中给定一个日期判断是周几.
- 我在成都火车站捡了个彝族美女 第1节:车站捡来的美女
- 表格td的宽度不随内容自适应
- 黑马小程序品优购商城项目分析
热门文章
- □ 影片名:《木乃伊》(5156) 在线播放
- 2021年香河一中高考成绩查询,香河一中高考成绩
- 第六课 511遇见易语言大漠找字FindStrFastEx打多怪实例
- Python笔记 | 依概率随机产生姓氏案例
- 显示器跟服务器的最大距离,关于显示器与人眼之间的距离
- 变形迁移(Deformation Transfer)DT
- crontab定时运行bash脚本,重启zeppelin
- ngss for oracle,学习笔记:Oracle bbed工具在Windows平台上兼容9i 10g 11g 12c运
- openCv--裁剪图像不规则区域
- 诛仙账号合并服务器,战区合并及部分服务器数据互通公告