前言:通常,我们写的公共的模块给别人用,但是这个模块又必须在特定的线程中执行。

比如,一个加载网络图片的的方法,需要在子线程中执行。

    /**
* 加载网络图片
*/
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 线程公共类,判断是否在主线程/ 子线程执行 相关操作的更多相关文章

  1. Handler主线程子线程之间的互相通信

    Handler主线程子线程之间的互相通信 package com.wyl.dansnote; import android.app.Activity; import android.os.Bundle ...

  2. Android 主线程和线程之间相互发送消息

    通过分析Activity源码,我们知道每个Activity都有一个Looper,所以主线程在接收Message是不需要调用Looper.prepare()和Looper.loop(),但是线程是不带L ...

  3. 【Java面试题】30 子线程循环10次,接着主线程循环100,接着又回到子线程循环10次,接着再回到主线程又循环100,如此循环50次,请写出程序。

    题目如下: 子线程循环10次,接着主线程循环100,接着又回到子线程循环10次, 接着再回到主线程又循环100,如此循环50次 思路如下: 子线程语主线程为互斥,可用SYNCHRONIZED.很容易想 ...

  4. Android Studio 2.0 Beta 5公布,修复几个与即时执行相关的严重BUG.

    Android Studio 2.0 Beta 5公布,修复几个与即时执行相关的严重BUG. This build fixes a couple of important bugs related t ...

  5. Android之Handler用法总结/安卓中只有主线程可以修改UI

    Handler传递消息的方式可以实现实时刷新以及长按连续响应事件. 按钮响应 btnadd_fcl.setOnTouchListener(new View.OnTouchListener() { pr ...

  6. 【转载】Delphi7从子线程中发送消息到主线程触发事件执行

    在对数据库的操作时,有时要用一个子线程来进行后台的数据操作.比如说数据备份,转档什么的.在主窗口还能同是进行其它操作.而有时后台每处理一个数据文件,要向主窗口发送消息,让主窗口实时显示处理进度在窗口上 ...

  7. 用Handler的post()方法来传递线程中的代码段到主线程中执行

    自定义的线程中是不能更新UI的,但是如果遇到更新UI的事情,我们可以用handler的post()方法来将更新UI的方法体,直接传送到主线程中,这样就能直接更新UI了.Handler的post()方法 ...

  8. C#(WPF和WinForm)在普通类中调用到主线程的方法,SynchronizationContext的用法。

    一.SynchronizationContext类用法: 1.对于WindowsFrom应用程序,如果想在某个类中,不方便使用到控件的Invoke方法时,可以使用WindowsBase.dll下的Sy ...

  9. 事件循环和线程没有必然关系(就像Windows子线程默认没有消息循环一样),模态对话框和事件循环也没有必然关系(QWidget直接就可以)

    周末天冷,索性把电脑抱到床上上网,这几天看了 dbzhang800 博客关于 Qt 事件循环的几篇 Blog,发现自己对 Qt 的事件循环有不少误解.从来只看到现象,这次借 dbzhang800 的博 ...

随机推荐

  1. storm坑之---传递对象

    继之前遇到的那个同步问题的坑之后(storm坑之---同步问题),最近对代码又做了调整和重构,并且又遇到了另一个storm开发中应该值得警惕的坑.接下来说说这个坑的大体情况. 在我的storm程序中, ...

  2. Azure Backup (1) 将SQL Server 2012虚拟机中数据库备份到Azure Storage

    <Windows Azure Platform 系列文章目录> 本文介绍的是由国内世纪互联运维的China Azure,相比国外的Global Azure.主要区别是存储账号的DNS地址不 ...

  3. js基础篇——cookie使用要点

    1.Cookie数量和长度的限制.各个浏览器的限制不同IE7+和Firefox最大限制为50条,chrome和Safari无限制,IE6-最大限制20条.且所有浏览器限制每个cookie长度不能超过4 ...

  4. Swift泛型协议的N种用法

    They said "you should learn a new language every year," so I  learned Swift. Now  I  learn ...

  5. Bise IE6 在你的网站上加上它让IE滚蛋吧

    <!--[if lt IE 7]> <style type="text/css"> .broswer_tips{height:26px;background ...

  6. 做一个会PS切图的前端开发

    系列链接 做一个会使用PS的前端开发 做一个会PS切图的前端开发 切图方法分类 PhotoShop从CS版本演变到现在的CC版本,切图功能发生了比较大的变化,我们可以把PhotoShop CS版本时的 ...

  7. LINUX总结

    LINUX总结 crazyacking 2016-02-26 主要对socket编程,多线程,定时器,条件变量总结 多线程篇 概念: 多线程就是允许一个进程内存存在多个控制权,实现多个线程并发执行. ...

  8. 【要什么自行车】ASP.NET MVC4笔记02:上传文件 uploadify 组件使用

    参考:http://www.cnblogs.com/luotaoyeah/p/3321070.html 1.下载 uploadify 组件,copy至 Content文件夹 <link href ...

  9. Scalaz(17)- Monad:泛函状态类型-State Monad

    我们经常提到函数式编程就是F[T].这个F可以被视为一种运算模式.我们是在F运算模式的壳子内对T进行计算.理论上来讲,函数式程序的运行状态也应该是在这个运算模式壳子内的,也是在F[]内更新的.那么我们 ...

  10. 泛函编程(25)-泛函数据类型-Monad-Applicative

    上两期我们讨论了Monad.我们说Monad是个最有概括性(抽象性)的泛函数据类型,它可以覆盖绝大多数数据类型.任何数据类型只要能实现flatMap+unit这组Monad最基本组件函数就可以变成Mo ...