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

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

    /**
* 加载网络图片
*/
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. Windows Azure Web Site (13) Azure Web Site备份

    <Windows Azure Platform 系列文章目录> 我们在使用Windows Azure Web Site的时候,经常会遇到需要对Web Site进行备份的情况.在这里笔者简单 ...

  2. jQuery.ajax()的相关参数及使用

    jQuery.ajax(),有很多项参数,小弟菜鸟级别,有时候想不起来,现在记录下来便于以后查看,也欢迎大神指正. 常用的几类,可以称为模板样式写法: $.ajax({ url: "url& ...

  3. 第17/24周 悲观并发控制(Pessimistic Concurrency)

    大家好,欢迎回到性能调优培训.今天标志着第5个月培训的开始,这个月我们会谈论SQL Server里的锁.阻塞和死锁(Locking, Blocking, and Deadlocking). SQL S ...

  4. 加速Web开发的9款知名HTML5框架

    与手工编码比起来,HTML5框架在准确性和正确率方面给予了保证.大多数HTML5框架都会有一个组合或者包含一些额外的组件,比如jQuery Scripts.CSS3样式表则以改善多媒体特征的功能性和响 ...

  5. 使用elk+redis搭建nginx日志分析平台

    elk+redis 搭建nginx日志分析平台 logstash,elasticsearch,kibana 怎么进行nginx的日志分析呢?首先,架构方面,nginx是有日志文件的,它的每个请求的状态 ...

  6. Coreseek + Sphinx + Mysql + PHP构建中文检索引擎

    首先明确几个概念 Sphinx是开源的搜索引擎,它支持英文的全文检索.所以如果单独搭建Sphinx,你就已经可以使用全文索引了.但是往往我们要求的是中文索引,怎么做呢?国人提供了一个可供企业使用的,基 ...

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

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

  8. C#2.0 to 4.0

    //xmlElement.set_InnerText(value); xmlElement.InnerText = value; ).ToCharArray());//Convert.ToChar(s ...

  9. setTimeout,setInterval,process.nextTick,setImmediate in Nodejs

    Nodejs的特点是事件驱动,异步I/O产生的高并发,产生此特点的引擎是事件循环,事件被分门别类地归到对应的事件观察者上,比如idle观察者,定时器观察者,I/O观察者等等,事件循环每次循环称为Tic ...

  10. IIS上部署MVC网站,打开后ExtensionlessUrlHandler-Integrated-4.0解决方法IIS上部署MVC网站,打开后500错误

    IIS上部署MVC网站,打开后ExtensionlessUrlHandler-Integrated-4.0解决方法 IIS上部署MVC网站,打开后500错误:处理程序“ExtensionlessUrl ...