Picasso源码完全解析(四)--Action分发和执行

本文详细解析了Picasso中图片加载请求如何通过Dispatcher分发和处理。从Dispatcher的实例化到消息循环机制的建立,再到Action的具体分发过程,深入探讨了其内部实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


Picasso源码完全解析(一)--概述

Picasso源码完全解析(二)--Picasso实例的创建

Picasso源码完全解析(三)--Request和Action的创建

Picasso源码完全解析(四)--Action分发和执行

Picasso源码完全解析(五)--图片的获取(BitmapHunter)

Picasso源码完全解析(六)--请求的取消、暂停、和恢复

Picasso源码完全解析(七)-- CleanupThread 取消请求


Picasso源码完全解析(四)--Action分发和执行

上节讲到 我们的每个图片请求最后生成一个Action被提交给Picasso执行,那么那么多的Action Picasso是怎么执行的呢?

void enqueueAndSubmit(Action action) {
    Object target = action.getTarget();
    if (target != null && targetToAction.get(target) != action) {
        // This will also check we are on the main thread.
        cancelExistingRequest(target);
        targetToAction.put(target, action);
    }
    submit(action);
}

void submit(Action action) {
    dispatcher.dispatchSubmit(action);
}

可以看到最终Action是通过Dispatcher进行分发的和执行的,下面详细介绍Dispatcher是如何进行消息分发和执行的。

消息循环的建立

首先来看看Dispatcher的主要成员变量:

private static final int RETRY_DELAY = 500;
private static final int AIRPLANE_MODE_ON = 1;
private static final int AIRPLANE_MODE_OFF = 0;

static final int REQUEST_SUBMIT = 1;
static final int REQUEST_CANCEL = 2;
static final int REQUEST_GCED = 3;
static final int HUNTER_COMPLETE = 4;
static final int HUNTER_RETRY = 5;
static final int HUNTER_DECODE_FAILED = 6;
static final int HUNTER_DELAY_NEXT_BATCH = 7;
static final int HUNTER_BATCH_COMPLETE = 8;
static final int NETWORK_STATE_CHANGE = 9;
static final int AIRPLANE_MODE_CHANGE = 10;
static final int TAG_PAUSE = 11;
static final int TAG_RESUME = 12;
static final int REQUEST_BATCH_RESUME = 13;

private static final String DISPATCHER_THREAD_NAME = "Dispatcher";
private static final int BATCH_DELAY = 200; // ms

final DispatcherThread dispatcherThread;//消息循环线程
final Context context;
final ExecutorService service;//执行线程池
final Downloader downloader;//下载器
final Map<String, BitmapHunter> hunterMap;
final Map<Object, Action> failedActions;
final Map<Object, Action> pausedActions;
final Set<Object> pausedTags;
final Handler handler;//消息处理者
final Handler mainThreadHandler;
final Cache cache;//内存缓存
final Stats stats;//统计快照
final List<BitmapHunter> batch;
final NetworkBroadcastReceiver receiver;//网络状况广播接受者
final boolean scansNetworkChanges;

boolean airplaneMode;

主要的成员变量如上面注释所示。

在看看Dispatcher的实例化时机。

 public Picasso build() {
        Context context = this.context;

        if (downloader == null) {
            downloader = Utils.createDefaultDownloader(context);
        }
        if (cache == null) {
            cache = new LruCache(context);
        }
        if (service == null) {
            service = new PicassoExecutorService();
        }
        if (transformer == null) {
            transformer = RequestTransformer.IDENTITY;
        }

        Stats stats = new Stats(cache);

        Dispatcher dispatcher = new Dispatcher(context, service, HANDLER, downloader, cache, stats);

        return new Picasso(context, dispatcher, cache, listener, transformer, requestHandlers, stats,
                defaultBitmapConfig, indicatorsEnabled, loggingEnabled);
    }

可以看到Dispatcher是在Picasso被创建前实例化的,并作为picasso的一个成员变量。

再看看Dispatcher的构造函数:

    Dispatcher(Context context, ExecutorService service, Handler mainThreadHandler,
           Downloader downloader, Cache cache, Stats stats) {
        this.dispatcherThread = new DispatcherThread();
        this.dispatcherThread.start();
        Utils.flushStackLocalLeaks(dispatcherThread.getLooper());
        this.context = context;
        this.service = service;
        this.hunterMap = new LinkedHashMap<String, BitmapHunter>();
        this.failedActions = new WeakHashMap<Object, Action>();
        this.pausedActions = new WeakHashMap<Object, Action>();
        this.pausedTags = new HashSet<Object>();
        this.handler = new DispatcherHandler(dispatcherThread.getLooper(), this);
        this.downloader = downloader;
        this.mainThreadHandler = mainThreadHandler;
        this.cache = cache;
        this.stats = stats;
        this.batch = new ArrayList<BitmapHunter>(4);
        this.airplaneMode = Utils.isAirplaneModeOn(this.context);
        this.scansNetworkChanges = hasPermission(context, Manifest.permission.ACCESS_NETWORK_STATE);
        this.receiver = new NetworkBroadcastReceiver(this);
        receiver.register();
    }

可以看出Dispatcher在实例化的时候主要是做了一些初始化的操作,最重要的是开启了一个消息循环线程DispatcherThread

 static class DispatcherThread extends HandlerThread {
    DispatcherThread() {
        super(Utils.THREAD_PREFIX + DISPATCHER_THREAD_NAME, THREAD_PRIORITY_BACKGROUND);
    }
}

DispatcherThread其实是一个HandlerThread,也就是一个带有Looper的线程。

 this.handler = new DispatcherHandler(dispatcherThread.getLooper(), this);

紧接着用DispatcherThread的Looper实例化了一个Handler,用来处理消息循环线程的所有消息。

到此Dispatcher的消息循环机制就建立起来了。

Action的分发 和 处理

由上面的分析可以知道,当Dispatcher被创建后,就建立一个消息循环线程,通过这个HandlerThread关联的Handler可以进行消息的分发和处理。

我们提交给picasso的所有Action都是这样被分发的:

 dispatcher.dispatchSubmit(action);

再看看dispatcher.dispatchSubmit()

void dispatchSubmit(Action action) {
    handler.sendMessage(handler.obtainMessage(REQUEST_SUBMIT, action));
}

可以看到是通过Handler向HandlerThread发消息进行分发的。

根据Hander机制,最终消息在Handler的 handlerMessage()回调中被处理:

 case REQUEST_SUBMIT: {
    Action action = (Action) msg.obj;
    dispatcher.performSubmit(action);
    break;
}

最后消息的执行是通过dispatcher.performSubmit()得到执行的。

类似的,对Action的其他操作,也是通过这种机制分发和处理的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值