public synchronized void start(final String url, final String path,
                                   final boolean pathAsDirectory,
                                   final int callbackProgressTimes,
                                   final int callbackProgressMinIntervalMillis,
                                   final int autoRetryTimes, final boolean forceReDownload,
                                   final FileDownloadHeader header, final boolean isWifiRequired) {
        if (FileDownloadLog.NEED_LOG) {
            FileDownloadLog.d(this, "request start the task with url(%s) path(%s) isDirectory(%B)",
                    url, path, pathAsDirectory);
        }

        // clear pause all marker so that the delay pause all check doesn't obstruct normal start of
        // new task
        PauseAllMarker.clearMarker();

        final int id = FileDownloadUtils.generateId(url, path, pathAsDirectory);
        FileDownloadModel model = mDatabase.find(id);

        List<ConnectionModel> dirConnectionModelList = null;

        if (!pathAsDirectory && model == null) {
            // try dir data.
            final int dirCaseId = FileDownloadUtils
                    .generateId(url, FileDownloadUtils.getParent(path),
                            true);
            model = mDatabase.find(dirCaseId);
            if (model != null && path.equals(model.getTargetFilePath())) {
                if (FileDownloadLog.NEED_LOG) {
                    FileDownloadLog.d(this, "task[%d] find model by dirCaseId[%d]", id, dirCaseId);
                }

                dirConnectionModelList = mDatabase.findConnectionModel(dirCaseId);
            }
        }

        if (FileDownloadHelper.inspectAndInflowDownloading(id, model, this, true)) {
            if (FileDownloadLog.NEED_LOG) {
                FileDownloadLog.d(this, "has already started download %d", id);
            }
            return;
        }

        final String targetFilePath = model != null ? model.getTargetFilePath()
                : FileDownloadUtils.getTargetFilePath(path, pathAsDirectory, null);
        if (FileDownloadHelper.inspectAndInflowDownloaded(id, targetFilePath, forceReDownload,
                true)) {
            if (FileDownloadLog.NEED_LOG) {
                FileDownloadLog.d(this, "has already completed downloading %d", id);
            }
            return;
        }

        final long sofar = model != null ? model.getSoFar() : 0;
        final String tempFilePath = model != null ? model.getTempFilePath()
                : FileDownloadUtils.getTempPath(targetFilePath);
        if (FileDownloadHelper.inspectAndInflowConflictPath(id, sofar, tempFilePath, targetFilePath,
                this)) {
            if (FileDownloadLog.NEED_LOG) {
                FileDownloadLog
                        .d(this, "there is an another task with the same target-file-path %d %s",
                                id, targetFilePath);
            }

            // because of the file is dirty for this task.
            if (model != null) {
                mDatabase.remove(id);
                mDatabase.removeConnections(id);
            }
            return;
        }

        // real start
        // - create model
        boolean needUpdate2DB;
        if (model != null
                && (model.getStatus() == FileDownloadStatus.paused
                || model.getStatus() == FileDownloadStatus.error
                || model.getStatus() == FileDownloadStatus.pending
                || model.getStatus() == FileDownloadStatus.started
                || model.getStatus() == FileDownloadStatus.connected) // FileDownloadRunnable
            // invoke #isBreakpointAvailable to determine whether it is really invalid.
                ) {
            if (model.getId() != id) {
                // in try dir case.
                mDatabase.remove(model.getId());
                mDatabase.removeConnections(model.getId());

                model.setId(id);
                model.setPath(path, pathAsDirectory);
                if (dirConnectionModelList != null) {
                    for (ConnectionModel connectionModel : dirConnectionModelList) {
                        connectionModel.setId(id);
                        mDatabase.insertConnectionModel(connectionModel);
                    }
                }

                needUpdate2DB = true;
            } else {
                if (!TextUtils.equals(url, model.getUrl())) {
                    // for cover the case of reusing the downloaded processing with the different
                    // url( using with idGenerator ).
                    model.setUrl(url);
                    needUpdate2DB = true;
                } else {
                    needUpdate2DB = false;
                }
            }
        } else {
            if (model == null) {
                model = new FileDownloadModel();
            }
            model.setUrl(url);
            model.setPath(path, pathAsDirectory);

            model.setId(id);
            model.setSoFar(0);
            model.setTotal(0);
            model.setStatus(FileDownloadStatus.pending);
            model.setConnectionCount(1);
            needUpdate2DB = true;
        }

        // - update model to db
        if (needUpdate2DB) {
            mDatabase.update(model);
        }

        final DownloadLaunchRunnable.Builder builder = new DownloadLaunchRunnable.Builder();

        final DownloadLaunchRunnable runnable =
                builder.setModel(model)
                        .setHeader(header)
                        .setThreadPoolMonitor(this)
                        .setMinIntervalMillis(callbackProgressMinIntervalMillis)
                        .setCallbackProgressMaxCount(callbackProgressTimes)
                        .setForceReDownload(forceReDownload)
                        .setWifiRequired(isWifiRequired)
                        .setMaxRetryTimes(autoRetryTimes)
                        .build();

        // - execute
        mThreadPool.execute(runnable);

    }
public synchronized void start(final String url, final String path,
                                   final boolean pathAsDirectory,
                                   final int callbackProgressTimes,
                                   final int callbackProgressMinIntervalMillis,
                                   final int autoRetryTimes, final boolean forceReDownload,
                                   final FileDownloadHeader header, final boolean isWifiRequired) {
        if (FileDownloadLog.NEED_LOG) {
            FileDownloadLog.d(this, "request start the task with url(%s) path(%s) isDirectory(%B)",
                    url, path, pathAsDirectory);
        }

        
        
        PauseAllMarker.clearMarker();

        final int id = FileDownloadUtils.generateId(url, path, pathAsDirectory);
        FileDownloadModel model = mDatabase.find(id);

        List<ConnectionModel> dirConnectionModelList = null;

        if (!pathAsDirectory && model == null) {
            
            final int dirCaseId = FileDownloadUtils
                    .generateId(url, FileDownloadUtils.getParent(path),
                            true);
            model = mDatabase.find(dirCaseId);
            if (model != null && path.equals(model.getTargetFilePath())) {
                if (FileDownloadLog.NEED_LOG) {
                    FileDownloadLog.d(this, "task[%d] find model by dirCaseId[%d]", id, dirCaseId);
                }

                dirConnectionModelList = mDatabase.findConnectionModel(dirCaseId);
            }
        }

        if (FileDownloadHelper.inspectAndInflowDownloading(id, model, this, true)) {
            if (FileDownloadLog.NEED_LOG) {
                FileDownloadLog.d(this, "has already started download %d", id);
            }
            return;
        }

        final String targetFilePath = model != null ? model.getTargetFilePath()
                : FileDownloadUtils.getTargetFilePath(path, pathAsDirectory, null);
        if (FileDownloadHelper.inspectAndInflowDownloaded(id, targetFilePath, forceReDownload,
                true)) {
            if (FileDownloadLog.NEED_LOG) {
                FileDownloadLog.d(this, "has already completed downloading %d", id);
            }
            return;
        }

        final long sofar = model != null ? model.getSoFar() : 0;
        final String tempFilePath = model != null ? model.getTempFilePath()
                : FileDownloadUtils.getTempPath(targetFilePath);
        if (FileDownloadHelper.inspectAndInflowConflictPath(id, sofar, tempFilePath, targetFilePath,
                this)) {
            if (FileDownloadLog.NEED_LOG) {
                FileDownloadLog
                        .d(this, "there is an another task with the same target-file-path %d %s",
                                id, targetFilePath);
            }

            
            if (model != null) {
                mDatabase.remove(id);
                mDatabase.removeConnections(id);
            }
            return;
        }

        
        
        boolean needUpdate2DB;
        if (model != null
                && (model.getStatus() == FileDownloadStatus.paused
                || model.getStatus() == FileDownloadStatus.error
                || model.getStatus() == FileDownloadStatus.pending
                || model.getStatus() == FileDownloadStatus.started
                || model.getStatus() == FileDownloadStatus.connected) 
            
                ) {
            if (model.getId() != id) {
                
                mDatabase.remove(model.getId());
                mDatabase.removeConnections(model.getId());

                model.setId(id);
                model.setPath(path, pathAsDirectory);
                if (dirConnectionModelList != null) {
                    for (ConnectionModel connectionModel : dirConnectionModelList) {
                        connectionModel.setId(id);
                        mDatabase.insertConnectionModel(connectionModel);
                    }
                }

                needUpdate2DB = true;
            } else {
                if (!TextUtils.equals(url, model.getUrl())) {
                    
                    
                    model.setUrl(url);
                    needUpdate2DB = true;
                } else {
                    needUpdate2DB = false;
                }
            }
        } else {
            if (model == null) {
                model = new FileDownloadModel();
            }
            model.setUrl(url);
            model.setPath(path, pathAsDirectory);

            model.setId(id);
            model.setSoFar(0);
            model.setTotal(0);
            model.setStatus(FileDownloadStatus.pending);
            model.setConnectionCount(1);
            needUpdate2DB = true;
        }

        
        if (needUpdate2DB) {
            mDatabase.update(model);
        }

        final DownloadLaunchRunnable.Builder builder = new DownloadLaunchRunnable.Builder();

        final DownloadLaunchRunnable runnable =
                builder.setModel(model)
                        .setHeader(header)
                        .setThreadPoolMonitor(this)
                        .setMinIntervalMillis(callbackProgressMinIntervalMillis)
                        .setCallbackProgressMaxCount(callbackProgressTimes)
                        .setForceReDownload(forceReDownload)
                        .setWifiRequired(isWifiRequired)
                        .setMaxRetryTimes(autoRetryTimes)
                        .build();

        
        mThreadPool.execute(runnable);

    }
public synchronized void start ( final String url , final String path , final boolean pathAsDirectory , final int callbackProgressTimes , final int callbackProgressMinIntervalMillis , final int autoRetryTimes , final boolean forceReDownload , final FileDownloadHeader header , final boolean isWifiRequired ) { if ( FileDownloadLog . NEED_LOG ) { FileDownloadLog . d ( this , "request start the task with url(%s) path(%s) isDirectory(%B)" , url , path , pathAsDirectory ) ; } // clear pause all marker so that the delay pause all check doesn't obstruct normal start of // new task PauseAllMarker . clearMarker ( ) ; final int id = FileDownloadUtils . generateId ( url , path , pathAsDirectory ) ; FileDownloadModel model = mDatabase . find ( id ) ; List < ConnectionModel > dirConnectionModelList = null ; if ( ! pathAsDirectory && model == null ) { // try dir data. final int dirCaseId = FileDownloadUtils . generateId ( url , FileDownloadUtils . getParent ( path ) , true ) ; model = mDatabase . find ( dirCaseId ) ; if ( model != null && path . equals ( model . getTargetFilePath ( ) ) ) { if ( FileDownloadLog . NEED_LOG ) { FileDownloadLog . d ( this , "task[%d] find model by dirCaseId[%d]" , id , dirCaseId ) ; } dirConnectionModelList = mDatabase . findConnectionModel ( dirCaseId ) ; } } if ( FileDownloadHelper . inspectAndInflowDownloading ( id , model , this , true ) ) { if ( FileDownloadLog . NEED_LOG ) { FileDownloadLog . d ( this , "has already started download %d" , id ) ; } return ; } final String targetFilePath = model != null ? model . getTargetFilePath ( ) : FileDownloadUtils . getTargetFilePath ( path , pathAsDirectory , null ) ; if ( FileDownloadHelper . inspectAndInflowDownloaded ( id , targetFilePath , forceReDownload , true ) ) { if ( FileDownloadLog . NEED_LOG ) { FileDownloadLog . d ( this , "has already completed downloading %d" , id ) ; } return ; } final long sofar = model != null ? model . getSoFar ( ) : 0 ; final String tempFilePath = model != null ? model . getTempFilePath ( ) : FileDownloadUtils . getTempPath ( targetFilePath ) ; if ( FileDownloadHelper . inspectAndInflowConflictPath ( id , sofar , tempFilePath , targetFilePath , this ) ) { if ( FileDownloadLog . NEED_LOG ) { FileDownloadLog . d ( this , "there is an another task with the same target-file-path %d %s" , id , targetFilePath ) ; } // because of the file is dirty for this task. if ( model != null ) { mDatabase . remove ( id ) ; mDatabase . removeConnections ( id ) ; } return ; } // real start // - create model boolean needUpdate2DB ; if ( model != null && ( model . getStatus ( ) == FileDownloadStatus . paused || model . getStatus ( ) == FileDownloadStatus . error || model . getStatus ( ) == FileDownloadStatus . pending || model . getStatus ( ) == FileDownloadStatus . started || model . getStatus ( ) == FileDownloadStatus . connected ) // FileDownloadRunnable // invoke #isBreakpointAvailable to determine whether it is really invalid. ) { if ( model . getId ( ) != id ) { // in try dir case. mDatabase . remove ( model . getId ( ) ) ; mDatabase . removeConnections ( model . getId ( ) ) ; model . setId ( id ) ; model . setPath ( path , pathAsDirectory ) ; if ( dirConnectionModelList != null ) { for ( ConnectionModel connectionModel : dirConnectionModelList ) { connectionModel . setId ( id ) ; mDatabase . insertConnectionModel ( connectionModel ) ; } } needUpdate2DB = true ; } else { if ( ! TextUtils . equals ( url , model . getUrl ( ) ) ) { // for cover the case of reusing the downloaded processing with the different // url( using with idGenerator ). model . setUrl ( url ) ; needUpdate2DB = true ; } else { needUpdate2DB = false ; } } } else { if ( model == null ) { model = new FileDownloadModel ( ) ; } model . setUrl ( url ) ; model . setPath ( path , pathAsDirectory ) ; model . setId ( id ) ; model . setSoFar ( 0 ) ; model . setTotal ( 0 ) ; model . setStatus ( FileDownloadStatus . pending ) ; model . setConnectionCount ( 1 ) ; needUpdate2DB = true ; } // - update model to db if ( needUpdate2DB ) { mDatabase . update ( model ) ; } final DownloadLaunchRunnable . Builder builder = new DownloadLaunchRunnable . Builder ( ) ; final DownloadLaunchRunnable runnable = builder . setModel ( model ) . setHeader ( header ) . setThreadPoolMonitor ( this ) . setMinIntervalMillis ( callbackProgressMinIntervalMillis ) . setCallbackProgressMaxCount ( callbackProgressTimes ) . setForceReDownload ( forceReDownload ) . setWifiRequired ( isWifiRequired ) . setMaxRetryTimes ( autoRetryTimes ) . build ( ) ; // - execute mThreadPool . execute ( runnable ) ; }
synchronize for safe: check downloading, check resume, update data, execute runnable
synchronize for safe : check downloading check resume update data execute runnable