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

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

    /**
* 加载网络图片
*/
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. Android之Activity的生命周期

    PS:写一发关于Activity的生命周期,也算是面试的重点内容. 学习内容: 1.Activity的生命周期 2.面对多种情况的时候Activity的生命周期 3.onSaveInstanceSta ...

  2. WCF序列化

    在WCF中,提供了专门用来序列化和反序列操作的类,该类就是DataContractSerializer类.一般而言,WCF会自动选择使用DataContractSerializer来对可序列话数据契约 ...

  3. Vue2.0流式渲染中文乱码问题

    在参照vue2.0中文官方文档学习服务端渲染之流式渲染时,因为响应头默认编码类型为GBK,而文件为UFT-8类型,所以出现了中文乱码问题. 解决办法:设置响应头编码类型即可 response.setH ...

  4. Winform如何实现ComboBox模糊查询

    最近朋友问了一个关于Winform实现ComboBox模糊查询的知识点,自己好久没有搞Winform了,就上手练了一下,废话不多说,进入正题. 前台设计: 前台就是一个简单的Form窗体+一个Comb ...

  5. C# 6.0的字典(Dictionary)的语法

    在C# 6.0,当我们使用Dictionary时,我们可以使用新语法,来去简化程序以提高效率. public Dictionary<string, object> OldToolLocat ...

  6. 九个Console命令,让js调试更简单

    一.显示信息的命令 最常用的就是console.log了. 二.占位符 console上述的集中度支持printf的占位符格式,支持的占位符有:字符(%s).整数(%d或%i).浮点数(%f)和对象( ...

  7. 【iOS】关联属性存取数据

    有时候我们需要在现有的类存放一些额外的信息,通常的做法是继承一个子类,然后定义新增加的属性,然而如果我们为每个需要的类都添加一个类显得太麻烦了,objc提供了一个关联属性的特性,可以给一个对象关联一个 ...

  8. 'display' VS 'visibility'

    常用的display属性值: none此元素不会被显示并且不占用空间: block此元素显示为块级元素,此元素前后会带有换行符: inline默认,此元素会被显示为内联元素,元素前后没有换行符: in ...

  9. Ajax.ActionLink打开页面之后,表单验证失效

    这两天遇到这个问题搞了很久,原因是验证插件默认是在页面初始化时初始化,ajax调用导致页面不会初始化,所以验证插件也没有初始化.解决方案如下 @Ajax.ActionLink("Edit&q ...

  10. 关于JS

    首先推荐一个小插件:W3Cfuns前端开发工具箱 整理一些杂乱的知识点. 1,Dom用于操作html元素 2,window.location.reload();//刷新当前页********** 3, ...