Android ThreadUtil 线程公共类,判断是否在主线程/ 子线程执行 相关操作
前言:通常,我们写的公共的模块给别人用,但是这个模块又必须在特定的线程中执行。
比如,一个加载网络图片的的方法,需要在子线程中执行。
/**
* 加载网络图片
*/
private void loadImage() {
try {
//用延时3秒操作来模拟网络操作
Thread.sleep( 3000 );
} catch (InterruptedException e) {
e.printStackTrace();
}
}
但是其他的同事在使用的时候,可能一不小心就在主线程中执行了 loadImage() 方法。这样就势必造成了界面卡顿。
为了避免这种情况,我们需要一个线程判断的工具 ThreadUtil 来帮助我们处理。
- 当前线程是主线程,抛出异常,不去加载
- 当前线程是子线程,继续执行,完成加载
package com.app;
import android.os.Looper; /**
* Created by ${zyj} on 2016/6/7.
*/
public class ThreadUtil { /**
* Throws an {@link java.lang.IllegalArgumentException} if called on a thread other than the main thread.
*/
public static void assertMainThread() {
if (!isOnMainThread()) {
throw new IllegalArgumentException("You must call this method on the main thread");
}
} /**
* Throws an {@link java.lang.IllegalArgumentException} if called on the main thread.
*/
public static void assertBackgroundThread() {
if (!isOnBackgroundThread()) {
throw new IllegalArgumentException("YOu must call this method on a background thread");
}
} /**
* Returns {@code true} if called on the main thread, {@code false} otherwise.
*/
public static boolean isOnMainThread() {
return Looper.myLooper() == Looper.getMainLooper();
} /**
* Returns {@code true} if called on the main thread, {@code false} otherwise.
*/
public static boolean isOnBackgroundThread() {
return !isOnMainThread();
} }
然后我们把 loadImage() 修改一下,就成了
/**
* 加载网络图片
*/
private void loadImage() {
//判断是否在子线程。 子线程:继续执行 主线程:抛出异常
ThreadUtil.assertBackgroundThread(); try {
//用延时3秒操作来模拟网络操作
Thread.sleep( 3000 );
} catch (InterruptedException e) {
e.printStackTrace();
}
}
可以看到在 loadImage() 方法中多了一句: ThreadUtil.assertBackgroundThread();
在 assertBackgroundThread() 方法里,判断如果不是子线程就直接抛出 "YOu must call this method on a background thread"
正确的调用应该是:在子线程中调用 loadImage() ,比如:
new Thread(new Runnable() {
@Override
public void run() {
loadImage();
}
}).start();
总结:
- ThreadUitl 是参考图片加载框架Glide写的 .
- ThreadUtil.assertBackgroundThread(); 要求在子线程中执行
- ThreadUtil.assertMainThread() ; 要求在主线程运行
- 代码示例已上传到 github: https://github.com/zyj1609wz/ZUtils
Android ThreadUtil 线程公共类,判断是否在主线程/ 子线程执行 相关操作的更多相关文章
- Handler主线程子线程之间的互相通信
Handler主线程子线程之间的互相通信 package com.wyl.dansnote; import android.app.Activity; import android.os.Bundle ...
- Android 主线程和线程之间相互发送消息
通过分析Activity源码,我们知道每个Activity都有一个Looper,所以主线程在接收Message是不需要调用Looper.prepare()和Looper.loop(),但是线程是不带L ...
- 【Java面试题】30 子线程循环10次,接着主线程循环100,接着又回到子线程循环10次,接着再回到主线程又循环100,如此循环50次,请写出程序。
题目如下: 子线程循环10次,接着主线程循环100,接着又回到子线程循环10次, 接着再回到主线程又循环100,如此循环50次 思路如下: 子线程语主线程为互斥,可用SYNCHRONIZED.很容易想 ...
- Android Studio 2.0 Beta 5公布,修复几个与即时执行相关的严重BUG.
Android Studio 2.0 Beta 5公布,修复几个与即时执行相关的严重BUG. This build fixes a couple of important bugs related t ...
- Android之Handler用法总结/安卓中只有主线程可以修改UI
Handler传递消息的方式可以实现实时刷新以及长按连续响应事件. 按钮响应 btnadd_fcl.setOnTouchListener(new View.OnTouchListener() { pr ...
- 【转载】Delphi7从子线程中发送消息到主线程触发事件执行
在对数据库的操作时,有时要用一个子线程来进行后台的数据操作.比如说数据备份,转档什么的.在主窗口还能同是进行其它操作.而有时后台每处理一个数据文件,要向主窗口发送消息,让主窗口实时显示处理进度在窗口上 ...
- 用Handler的post()方法来传递线程中的代码段到主线程中执行
自定义的线程中是不能更新UI的,但是如果遇到更新UI的事情,我们可以用handler的post()方法来将更新UI的方法体,直接传送到主线程中,这样就能直接更新UI了.Handler的post()方法 ...
- C#(WPF和WinForm)在普通类中调用到主线程的方法,SynchronizationContext的用法。
一.SynchronizationContext类用法: 1.对于WindowsFrom应用程序,如果想在某个类中,不方便使用到控件的Invoke方法时,可以使用WindowsBase.dll下的Sy ...
- 事件循环和线程没有必然关系(就像Windows子线程默认没有消息循环一样),模态对话框和事件循环也没有必然关系(QWidget直接就可以)
周末天冷,索性把电脑抱到床上上网,这几天看了 dbzhang800 博客关于 Qt 事件循环的几篇 Blog,发现自己对 Qt 的事件循环有不少误解.从来只看到现象,这次借 dbzhang800 的博 ...
随机推荐
- 20款精致的长阴影 LOGO 设计【附免费生成工具】
长阴影(Long Shadow)概念来自于最新非常流行的扁平化设计(Flat Design).扁平化设计趋势影响最大的是用户界面元素和图标,但它也开始蔓延到其他网页设计的其他部分. 长阴影其实就是扩展 ...
- 基于Mono.Cecil的静态注入
Aop注入有2种方式:动态注入和静态注入,其中动态注入有很多实现了 动态注入有几种方式: 利用Remoting的ContextBoundObject或MarshalByRefObject. 动态代理( ...
- 用Latex写学术论文: IEEE Latex模板和文档设置(\documentclass)
1.可以在博客园中使用latex代码输出公式,以后再以不用复制图片粘贴啦: http://www.cnblogs.com/cmt/p/3279312.html 例如以下代码两边加上 $ 符号后 x(k ...
- 【转】jQuery中.bind() .live() .delegate() .on()的区别
bind(type,[data],fn) 为每个匹配元素的特定事件绑定事件处理函数 $("a").bind("click",function(){alert(& ...
- 【原创】验证代理IP是否有用
/// <summary> /// 验证代理IP是否有用 /// </summary> /// <param name="ip">IP地址< ...
- var 的使用
List<Enterprise> epList = ViewBag.epList; foreach (var item in epList){ //todo ... } 当 List< ...
- Castle ActiveRecord相关错误
1.Could not compile the mapping document: (string)错误? 如果确保配置文件没有错误,那请检查用户身份,必须是Administrator才行,即使有管理 ...
- 半连通分量--Tarjan/Kosaraju算法
一个有向图称为半连通(Semi-Connected),满足:对于图中任两点u,v,存在一条u到v的有向路径或者从v到u的有向路径. 若满足,则称G’是G的一个导出子图. 若G’是G的导出子图,且G’半 ...
- LeetCode124:Binary Tree Maximum Path Sum
题目: Given a binary tree, find the maximum path sum. The path may start and end at any node in the tr ...
- 获取Android版本信息和电话信息
Android的版本信息可以通过android.os.Build获得,电话信息可以通过TelephonyManager获得,代码如下: private void get_infor(){ sd ...