DownloadManager之DownloadService浅析

本文主要解析Android系统的DownloadService,探讨其功能、生命周期和与DownloadProvider的交互。DownloadService作为下载管理的核心,主要负责接收更新、构建本地下载列表以及清理已删除的下载信息,实现对下载任务的管理和控制。

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

用粗糙而简陋的语言描述完了Andriod系统的DownloadManager的DownloadThread类,那么,继续我们的粗糙吧。现在就来描述一下DownloadManager的生命——DownloadService类。一如前面的思路,现在假设我们都没看过DownloadService的实现。我们打算怎么弄懂它呢,或者,对于这个神奇的类,你有哪些疑问呢。以下是我能想到的问题:

1、它完成了什么功能,最主要做了什么事儿,这肯定是我们第一个关心的。

2、系统服务与我们所用的应用层Service有什么不同吗?

3、对于一个Service,它实现了哪些接口?

4、这里是不是就是下载的开始点呢?

先看看第三个问题吧,第三个问题最简单,为什么呢,看看源码,看它Override 了几个接口就知道了。

/**
 * Performs the background downloads requested by applications that use the Downloads provider.
 */
public class DownloadService extends Service {
   
    @Override
    public IBinder onBind(Intent i) {
        throw new UnsupportedOperationException("Cannot bind to Download Manager Service");
    }

   
    @Override
    public void onCreate() {
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
    }

    @Override
    public void onDestroy() {
    }

    @Override
    protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
    }
}

从实现的接口上来说,它只是实现了一个服务最基础的几个接口,并没有其他特殊接口。不过,这里有一个比较有意思的接口实现,对了,就是OnBind()。它告诉别人,你不能绑定我,只能启动我。一般来说,如果我们要绑定一个服务,可能会希望通过与服务注册一个远程回调,然后服务通过远程的回调将计算结果传给绑定服务的客户端。那么,可想而知,DownloadService是希望不与客户端直接通信的。这算不算与我们写的Service的不同点呢。

那么它是怎么通信的,简单点说,就是通过DownloadProvider来进行的。其实,这样做也能很容易就理解到。因为如果是采用接口的方式的话,服务可能还没发完所有回调,结果自己挂调了,那么就有可能它的客户端就得不到正常的更新。从而导致状态错误。

接下来,可以看第一个问题了。它都做了些什么。从面向对象的角度来说。一个类能不能做什么,是不是先要看看它有哪些成员属性以及成员方法呢。那就行看其成员属性吧。

 /** amount of time to wait to connect to MediaScannerService before timing out */
   // 等待扫描服务的超时时间
    private static final long WAIT_TIMEOUT = 10 * 1000;

    /** Observer to get notified when the content observer's data changes */
    //能够监听DownloadProvider的Observer
    private DownloadManagerContentObserver mObserver;

    /** Class to handle Notification Manager updates */
    // 通知栏箮理
    private DownloadNotifier mNotifier;

   //下载队列,通过从DownloadProvider里取出,并将每条下载记录与其生成的下载ID作为一个Map值。
    private Map<Long, DownloadInfo> mDownloads = Maps.newHashMap();

    /**
     * The thread that updates the internal download list from the content
     * provider.
     */
     //更新线程,是DownloadService的一个内部类,同时,这个也是其功臣类,幕后的英雄。
    @VisibleForTesting
    UpdateThread mUpdateThread;

    /**
     * Whether the internal download list should be updated from the content
     * provider.
     */
     //判断是否需要更新mDownloads
    private boolean mPendingUpdate;

    /**
     * The ServiceConnection object that tells us when we're connected to and disconnected from
     * the Media Scanner
     */
     //媒体扫描,不关的可以不管,目前我就没管它
    private MediaScannerConnection mMediaScannerConnection;

    private boolean mMediaScannerConnecting;

    /**
     * The IPC interface to the Media Scanner
     */
    private IMediaScannerService mMediaScannerService;
    
    //外观接口,其实就是通过这个接口去做一些公共的事
    @VisibleForTesting
    SystemFacade mSystemFacade;
    //存储管理
    private StorageManager mStorageManager;

   以上基本就是DoiwnloadService的成员属性了。关于媒体扫描,暂时可以不管,因为它并不决定下载,初步理解阶段,我们只关心我们最关心的问题。这里,我们只关心最有用,关系也最紧密的两个成员,即mDonwnloads以及mUpdateThread。

    简单的过了一遍其成员接口,以及其它所实现的接口。应该对其一些感性的认识了,至少不应该那么陌生了。好了,那么真正去分析这个类吧。

    对于一个服务,最让人容易想到的就是其生命周期。所以,引导我们的头,肯定是其onCrreate与onStartCommand.大家都知道,onCreate只执行一次,而onStartCommand会随服务被startService而启动多次。下面依次来看这两个代码。

  /**
     * Initializes the service when it is first created
     */
    @Override
    public void onCreate() {
        super.onCreate();
        
        //初始化外观接口
        if (mSystemFacade == null) {
            mSystemFacade = new RealSystemFacade(this);
        }
        
        //实始化并注册一个监听DownloadProvider的Observer
        mObserver = new DownloadManagerContentObserver();
        getContentResolver().registerContentObserver(Downloads.Impl.ALL_DOWNLOADS_CONTENT_URI,
                true, mObserver);
        //媒体扫描相关
        mMediaScannerService = null;
        mMediaScannerConnecting = false;
        mMediaScannerConnection = new MediaScannerConnection();
        // 通知管理
        mNotifier = new DownloadNotifier(this);
        mNotifier.cancelAll();
        //初始化存储管理
        mStorageManager = StorageManager.getInstance(getApplicationContext());
        //从DownloadProvider更新下载。
        updateFromProvider();
    }

    onCreate与我们的习惯写法应该差不多,就是初始化实例。当然,这里也做了一件很重要的事情,那就是从DownloadProvider更新下载。

  @Override
    public int onSta
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值