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

 

     

 

时间: 2024-09-22 07:04:51

Android ThreadUtil 线程公共类,判断是否在主线程/ 子线程执行 相关操作的相关文章

关于主线程子线程运行顺序的疑惑

问题描述 关于主线程子线程运行顺序的疑惑 这里是书上截得一段程序,我不明白!这是运行结果:为什么运行结果一开始是waiting for thread to finish也就是主线程先跑的.为什么一开始不是子线程先跑?求大神解答 解决方案 因为pthread_join的存在,join使得主线程和子线程同步,主线程阻塞住等待子线程运行完. 不同语言略有差异,但是基本上都是类似的,找一篇文章你看下http://blog.csdn.net/hmk2011/article/details/6289151

java编程中主线程子线程交替问题分析

问题:子线程循环 10 次,接着主线程循环 100 次,接着又回到子线程循环 10 次,接着再回到主线程又循环 100 次,如此循环50次. 分析:这个实际上是很简单的问题,即子线程run,主线程阻塞--->子线程阻塞,主线程run,能够使线程阻塞的方法有很多,最常见的是sleep与wait:当然,需要控制的话,用wait/notify.子线程与主线程共同操作一个Resource 对象,而Resource对象中由两个方法分别实现子线程与主线程的操作对象 代码如下: package treadga

android-Android线程间同步问题,实现主线程死等新线程处理结束

问题描述 Android线程间同步问题,实现主线程死等新线程处理结束 我的主线程是activity,在主线程里开启了线程R1,希望R1的任务处理完成后通知主线程继续,否则主线程一直等待,怎么实现? 解决方案 首先你这样的需求是违背android官方设计的,你应该考虑一下要实现你的功能,换一种需求(实现方式)是否可以. 主线程负责呈现画面增强交互,不应该阻塞,非要实现这样的功能, 可以在主线程是activity开启线程R1,然后什么事儿也不做,当R1的任务处理完成后通知主线程继续后再做事儿(绘制画

linux 把主线程cancel 掉后,由主线程创建的子线程会不会被cancel掉?

问题描述 linux 把主线程cancel 掉后,由主线程创建的子线程会不会被cancel掉? linux 把主线程cancel 掉后,由主线程创建的子线程会不会被cancel掉? 解决方案 不会.进程是独立的,不是线程.

子线程和主线程业务依次执行循环50次

子线程业务:循环10次 主线程业务:循环20次 这两个循环(业务)需要交替执行共50次 要用到共同数据的(包括同步锁)或共同算法(加密解密)的若干个方法应该归在同一个类上,这种设计正好体现了高内聚和程序的健壮性  while (bShouldSub) {                 try {                     this.wait();                 } catch (InterruptedException e) {                 

android开发-请问里面 的strResult如何给主线程用啊,求大神解答,最好简单写下代码

问题描述 请问里面 的strResult如何给主线程用啊,求大神解答,最好简单写下代码 new Thread(new Runnable() { @Override public void run() { Looper.prepare(); // TODO Auto-generated method stub String path = "http://www.shopmanage.com/landlady/spm"; // String path = "http://221.

android中抽象公共类,复用公共方法为多个对象

今天学习如何实现愤怒的小鸟,用到了JBox2D构建物理世界(这个不是这篇文章重点,但是很谢谢这个开源玩意) 一般一个独立的物体的实体类 import org.jbox2d.dynamics.Body; import org.liky.angrybird.util.Globals; import org.liky.angrybird.util.ImageUtils; import android.graphics.Canvas; import android.graphics.Paint; imp

Android中主线程与子线程之间相互通信教程

有时候,我们也可能碰到这样子的一种需求:需要主线程来向子线程发送消息,希望子线程来完成什么任务.如果这样子应该怎么做呢?这就是这篇文章将要讨论的内容. 一.HandlerThread类 主线程发送消息给子线程,通常思维逻辑就是:其实很简单,在主线程中实例化一个Handler,然后让他与子线程相关联(只要它与子线程的Looper相关联即可),这样子它处理的消息就是该子线程中的消息队列,而处理的逻辑都是在该子线程中执行的,不会占用主线程的时间.那么我们就来实现一下,看看这样子到底行得通还是行不通.新

Java线程池类ThreadPoolExecutor、ScheduledThreadPoolExecutor及Executors工厂类

Java中的线程池类有两个,分别是:ThreadPoolExecutor和ScheduledThreadPoolExecutor,这两个类都继承自ExecutorService.利用这两个类,可以创建各种不同的Java线程池,为了方便我们创建线程池,Java API提供了Executors工厂类来帮助我们创建各种各样的线程池.下面我们分别介绍一下这三个类. Java线程池ExecutorService继承树: 一.ThreadPoolExecutor ThreadPoolExecutor是Exe