Full Code of lingochamp/FileDownloader for AI

master 6237a8cac174 cached
189 files
1.1 MB
286.1k tokens
1854 symbols
1 requests
Download .txt
Showing preview only (1,202K chars total). Download the full file or copy to clipboard to get everything.
Repository: lingochamp/FileDownloader
Branch: master
Commit: 6237a8cac174
Files: 189
Total size: 1.1 MB

Directory structure:
gitextract_oil8rr72/

├── .github/
│   └── issue_template.md
├── .gitignore
├── .idea/
│   ├── codeStyleSettings.xml
│   ├── codeStyles/
│   │   ├── Project.xml
│   │   └── codeStyleConfig.xml
│   ├── compiler.xml
│   ├── copyright/
│   │   ├── apache2.xml
│   │   └── profiles_settings.xml
│   ├── dictionaries/
│   │   └── Jacksgong.xml
│   ├── encodings.xml
│   ├── gradle.xml
│   ├── inspectionProfiles/
│   │   ├── Project_Default.xml
│   │   └── profiles_settings.xml
│   ├── modules.xml
│   ├── runConfigurations.xml
│   └── vcs.xml
├── .travis.yml
├── CHANGELOG-ZH.md
├── CHANGELOG.md
├── LICENSE.txt
├── README-zh.md
├── README.md
├── build.gradle
├── checkstyle.xml
├── demo/
│   ├── .gitignore
│   ├── build.gradle
│   ├── filedownloaderdemo.jks
│   ├── proguard-rules.pro
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           ├── assets/
│           │   ├── filedownloader.properties
│           │   └── performance_test_data
│           ├── java/
│           │   └── com/
│           │       └── liulishuo/
│           │           └── filedownloader/
│           │               └── demo/
│           │                   ├── Constant.java
│           │                   ├── DemoApplication.java
│           │                   ├── GlobalMonitor.java
│           │                   ├── HybridTestActivity.java
│           │                   ├── MainActivity.java
│           │                   ├── MultitaskTestActivity.java
│           │                   ├── NotificationSampleActivity.java
│           │                   ├── SingleTaskTestActivity.java
│           │                   ├── TasksManagerDemoActivity.java
│           │                   ├── Utils.java
│           │                   └── performance/
│           │                       ├── IntParcel.java
│           │                       ├── LongParcel.java
│           │                       └── PerformanceTestActivity.java
│           └── res/
│               ├── drawable/
│               │   └── bg_item_task_manager.xml
│               ├── layout/
│               │   ├── activity_hybrid_test.xml
│               │   ├── activity_main.xml
│               │   ├── activity_mutitask_test.xml
│               │   ├── activity_notification_minset.xml
│               │   ├── activity_notification_sample.xml
│               │   ├── activity_performance.xml
│               │   ├── activity_single.xml
│               │   ├── activity_tasks_manager_demo.xml
│               │   └── item_tasks_manager.xml
│               ├── menu/
│               │   └── menu_main.xml
│               ├── values/
│               │   ├── colors.xml
│               │   ├── donottranslate.xml
│               │   ├── strings.xml
│               │   └── styles.xml
│               ├── values-zh/
│               │   └── strings.xml
│               └── xml/
│                   └── network_security_config.xml
├── gradle/
│   ├── bintray.gradle
│   ├── mvn-local.gradle
│   ├── mvn-push.gradle
│   └── wrapper/
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── install.sh
├── library/
│   ├── .gitignore
│   ├── LICENSE
│   ├── build.gradle
│   ├── gradle.properties
│   ├── proguard-rules.pro
│   └── src/
│       ├── main/
│       │   ├── AndroidManifest.xml
│       │   ├── aidl/
│       │   │   └── com/
│       │   │       └── liulishuo/
│       │   │           └── filedownloader/
│       │   │               ├── i/
│       │   │               │   ├── IFileDownloadIPCCallback.aidl
│       │   │               │   └── IFileDownloadIPCService.aidl
│       │   │               ├── message/
│       │   │               │   └── MessageSnapshot.aidl
│       │   │               └── model/
│       │   │                   ├── FileDownloadHeader.aidl
│       │   │                   └── FileDownloadTaskAtom.aidl
│       │   ├── java/
│       │   │   └── com/
│       │   │       └── liulishuo/
│       │   │           └── filedownloader/
│       │   │               ├── BaseDownloadTask.java
│       │   │               ├── DownloadSpeedMonitor.java
│       │   │               ├── DownloadTask.java
│       │   │               ├── DownloadTaskHunter.java
│       │   │               ├── FileDownloadConnectListener.java
│       │   │               ├── FileDownloadEventPool.java
│       │   │               ├── FileDownloadLargeFileListener.java
│       │   │               ├── FileDownloadLine.java
│       │   │               ├── FileDownloadLineAsync.java
│       │   │               ├── FileDownloadList.java
│       │   │               ├── FileDownloadListener.java
│       │   │               ├── FileDownloadMessageStation.java
│       │   │               ├── FileDownloadMessenger.java
│       │   │               ├── FileDownloadMonitor.java
│       │   │               ├── FileDownloadQueueSet.java
│       │   │               ├── FileDownloadSampleListener.java
│       │   │               ├── FileDownloadServiceProxy.java
│       │   │               ├── FileDownloadServiceSharedTransmit.java
│       │   │               ├── FileDownloadServiceUIGuard.java
│       │   │               ├── FileDownloadTaskLauncher.java
│       │   │               ├── FileDownloader.java
│       │   │               ├── IDownloadSpeed.java
│       │   │               ├── IFileDownloadMessenger.java
│       │   │               ├── IFileDownloadServiceProxy.java
│       │   │               ├── ILostServiceConnectedHandler.java
│       │   │               ├── IQueuesHandler.java
│       │   │               ├── ITaskHunter.java
│       │   │               ├── IThreadPoolMonitor.java
│       │   │               ├── LostServiceConnectedHandler.java
│       │   │               ├── MessageSnapshotGate.java
│       │   │               ├── PauseAllMarker.java
│       │   │               ├── QueuesHandler.java
│       │   │               ├── connection/
│       │   │               │   ├── DefaultConnectionCountAdapter.java
│       │   │               │   ├── FileDownloadConnection.java
│       │   │               │   ├── FileDownloadUrlConnection.java
│       │   │               │   └── RedirectHandler.java
│       │   │               ├── database/
│       │   │               │   ├── FileDownloadDatabase.java
│       │   │               │   ├── NoDatabaseImpl.java
│       │   │               │   ├── RemitDatabase.java
│       │   │               │   ├── SqliteDatabaseImpl.java
│       │   │               │   └── SqliteDatabaseOpenHelper.java
│       │   │               ├── download/
│       │   │               │   ├── ConnectTask.java
│       │   │               │   ├── ConnectionProfile.java
│       │   │               │   ├── CustomComponentHolder.java
│       │   │               │   ├── DownloadLaunchRunnable.java
│       │   │               │   ├── DownloadRunnable.java
│       │   │               │   ├── DownloadStatusCallback.java
│       │   │               │   ├── FetchDataTask.java
│       │   │               │   └── ProcessCallback.java
│       │   │               ├── event/
│       │   │               │   ├── DownloadEventPoolImpl.java
│       │   │               │   ├── DownloadEventSampleListener.java
│       │   │               │   ├── DownloadServiceConnectChangedEvent.java
│       │   │               │   ├── IDownloadEvent.java
│       │   │               │   ├── IDownloadEventPool.java
│       │   │               │   └── IDownloadListener.java
│       │   │               ├── exception/
│       │   │               │   ├── FileDownloadGiveUpRetryException.java
│       │   │               │   ├── FileDownloadHttpException.java
│       │   │               │   ├── FileDownloadNetworkPolicyException.java
│       │   │               │   ├── FileDownloadOutOfSpaceException.java
│       │   │               │   ├── FileDownloadSecurityException.java
│       │   │               │   └── PathConflictException.java
│       │   │               ├── message/
│       │   │               │   ├── BlockCompleteMessage.java
│       │   │               │   ├── IFlowDirectly.java
│       │   │               │   ├── IMessageSnapshot.java
│       │   │               │   ├── LargeMessageSnapshot.java
│       │   │               │   ├── MessageSnapshot.java
│       │   │               │   ├── MessageSnapshotFlow.java
│       │   │               │   ├── MessageSnapshotTaker.java
│       │   │               │   ├── MessageSnapshotThreadPool.java
│       │   │               │   └── SmallMessageSnapshot.java
│       │   │               ├── model/
│       │   │               │   ├── ConnectionModel.java
│       │   │               │   ├── FileDownloadHeader.java
│       │   │               │   ├── FileDownloadModel.java
│       │   │               │   ├── FileDownloadStatus.java
│       │   │               │   └── FileDownloadTaskAtom.java
│       │   │               ├── notification/
│       │   │               │   ├── BaseNotificationItem.java
│       │   │               │   ├── FileDownloadNotificationHelper.java
│       │   │               │   └── FileDownloadNotificationListener.java
│       │   │               ├── services/
│       │   │               │   ├── BaseFileServiceUIGuard.java
│       │   │               │   ├── DefaultIdGenerator.java
│       │   │               │   ├── DownloadMgrInitialParams.java
│       │   │               │   ├── FDServiceSeparateHandler.java
│       │   │               │   ├── FDServiceSharedHandler.java
│       │   │               │   ├── FileDownloadBroadcastHandler.java
│       │   │               │   ├── FileDownloadManager.java
│       │   │               │   ├── FileDownloadService.java
│       │   │               │   ├── FileDownloadThreadPool.java
│       │   │               │   ├── ForegroundServiceConfig.java
│       │   │               │   └── IFileDownloadServiceHandler.java
│       │   │               ├── stream/
│       │   │               │   ├── FileDownloadOutputStream.java
│       │   │               │   └── FileDownloadRandomAccessFile.java
│       │   │               └── util/
│       │   │                   ├── DownloadServiceNotConnectedHelper.java
│       │   │                   ├── ExtraKeys.java
│       │   │                   ├── FileDownloadExecutors.java
│       │   │                   ├── FileDownloadHelper.java
│       │   │                   ├── FileDownloadLog.java
│       │   │                   ├── FileDownloadProperties.java
│       │   │                   ├── FileDownloadSerialQueue.java
│       │   │                   └── FileDownloadUtils.java
│       │   └── res/
│       │       └── values/
│       │           └── strings.xml
│       └── test/
│           ├── java/
│           │   └── com/
│           │       └── liulishuo/
│           │           └── filedownloader/
│           │               ├── FileDownloaderTest.java
│           │               ├── connection/
│           │               │   └── FileDownloadUrlConnectionTest.java
│           │               ├── download/
│           │               │   ├── DownloadLaunchRunnableTest.java
│           │               │   └── DownloadRunnableTest.java
│           │               └── util/
│           │                   └── FileDownloadUtilsTest.java
│           └── resources/
│               └── mockito-extensions/
│                   └── org.mockito.plugins.MockMaker
├── okcat.yml
└── settings.gradle

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/issue_template.md
================================================
#### Before Issue

1. Please search on the [Issues](https://github.com/lingochamp/FileDownloader/issues)
2. Please search on the [wiki](https://github.com/lingochamp/FileDownloader/wiki)
3. Please set `FileDownloadLog.NEED_LOG=true` and review the Logcat output from main process and `:filedownloader` process ( pay attention to Warn and Error level logcat)

#### Issue

1. What problem do you get?
2. Which version of FileDownloader are you using when you produce such problem?
3. How to reproduce such problem?
4. Do you set `FileDownloadLog.NEED_LOG=true`?
5. Could you please reproduce this problem and provide all main process and `:filedownloader` process logcat 
6. Can you fix it by yourself and request PR, if not, what's problem do you get when you try to fix it

>P.S. If you don't know how to get `:filedownloader` process, it's recommended to using `pidcat` to just filter all your application logcat, or define `process.non-separate=true` on [filedownloader.properties](https://github.com/lingochamp/FileDownloader/wiki/filedownloader.properties)

---

请在Issue前认真的跟进上面提到的建议,这样将可以极大的加快你遇到问题的处理。


================================================
FILE: .gitignore
================================================
*.iml
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
/.idea/misc.xml
/.idea/checkstyle-idea.xml
/.idea/caches
.DS_Store
/build
/captures
.classpath
.project
.settings
.vscode


================================================
FILE: .idea/codeStyleSettings.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="ProjectCodeStyleSettingsManager">
    <option name="PER_PROJECT_SETTINGS">
      <value>
        <option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="99" />
        <option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="99" />
        <option name="PACKAGES_TO_USE_IMPORT_ON_DEMAND">
          <value />
        </option>
        <option name="IMPORT_LAYOUT_TABLE">
          <value>
            <package name="android" withSubpackages="true" static="false" />
            <emptyLine />
            <package name="com" withSubpackages="true" static="false" />
            <emptyLine />
            <package name="junit" withSubpackages="true" static="false" />
            <emptyLine />
            <package name="net" withSubpackages="true" static="false" />
            <emptyLine />
            <package name="org" withSubpackages="true" static="false" />
            <emptyLine />
            <package name="java" withSubpackages="true" static="false" />
            <emptyLine />
            <package name="javax" withSubpackages="true" static="false" />
            <emptyLine />
            <package name="" withSubpackages="true" static="false" />
            <emptyLine />
            <package name="" withSubpackages="true" static="true" />
            <emptyLine />
          </value>
        </option>
        <option name="RIGHT_MARGIN" value="100" />
        <AndroidXmlCodeStyleSettings>
          <option name="USE_CUSTOM_SETTINGS" value="true" />
        </AndroidXmlCodeStyleSettings>
        <Objective-C-extensions>
          <file>
            <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" />
            <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro" />
            <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef" />
            <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum" />
            <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant" />
            <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global" />
            <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct" />
            <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl" />
            <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function" />
          </file>
          <class>
            <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property" />
            <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize" />
            <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod" />
            <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod" />
            <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod" />
            <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod" />
          </class>
          <extensions>
            <pair source="cpp" header="h" />
            <pair source="c" header="h" />
          </extensions>
        </Objective-C-extensions>
        <XML>
          <option name="XML_KEEP_LINE_BREAKS" value="false" />
          <option name="XML_ALIGN_ATTRIBUTES" value="false" />
          <option name="XML_SPACE_INSIDE_EMPTY_TAG" value="true" />
        </XML>
        <codeStyleSettings language="XML">
          <option name="FORCE_REARRANGE_MODE" value="1" />
          <indentOptions>
            <option name="CONTINUATION_INDENT_SIZE" value="4" />
          </indentOptions>
          <arrangement>
            <rules>
              <section>
                <rule>
                  <match>
                    <AND>
                      <NAME>xmlns:android</NAME>
                      <XML_NAMESPACE>^$</XML_NAMESPACE>
                    </AND>
                  </match>
                </rule>
              </section>
              <section>
                <rule>
                  <match>
                    <AND>
                      <NAME>xmlns:.*</NAME>
                      <XML_NAMESPACE>^$</XML_NAMESPACE>
                    </AND>
                  </match>
                  <order>BY_NAME</order>
                </rule>
              </section>
              <section>
                <rule>
                  <match>
                    <AND>
                      <NAME>.*:id</NAME>
                      <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
                    </AND>
                  </match>
                </rule>
              </section>
              <section>
                <rule>
                  <match>
                    <AND>
                      <NAME>.*:name</NAME>
                      <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
                    </AND>
                  </match>
                </rule>
              </section>
              <section>
                <rule>
                  <match>
                    <AND>
                      <NAME>name</NAME>
                      <XML_NAMESPACE>^$</XML_NAMESPACE>
                    </AND>
                  </match>
                </rule>
              </section>
              <section>
                <rule>
                  <match>
                    <AND>
                      <NAME>style</NAME>
                      <XML_NAMESPACE>^$</XML_NAMESPACE>
                    </AND>
                  </match>
                </rule>
              </section>
              <section>
                <rule>
                  <match>
                    <AND>
                      <NAME>.*</NAME>
                      <XML_NAMESPACE>^$</XML_NAMESPACE>
                    </AND>
                  </match>
                  <order>BY_NAME</order>
                </rule>
              </section>
              <section>
                <rule>
                  <match>
                    <AND>
                      <NAME>.*:layout_width</NAME>
                      <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
                    </AND>
                  </match>
                </rule>
              </section>
              <section>
                <rule>
                  <match>
                    <AND>
                      <NAME>.*:layout_height</NAME>
                      <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
                    </AND>
                  </match>
                </rule>
              </section>
              <section>
                <rule>
                  <match>
                    <AND>
                      <NAME>.*:layout_.*</NAME>
                      <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
                    </AND>
                  </match>
                  <order>BY_NAME</order>
                </rule>
              </section>
              <section>
                <rule>
                  <match>
                    <AND>
                      <NAME>.*:width</NAME>
                      <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
                    </AND>
                  </match>
                  <order>BY_NAME</order>
                </rule>
              </section>
              <section>
                <rule>
                  <match>
                    <AND>
                      <NAME>.*:height</NAME>
                      <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
                    </AND>
                  </match>
                  <order>BY_NAME</order>
                </rule>
              </section>
              <section>
                <rule>
                  <match>
                    <AND>
                      <NAME>.*</NAME>
                      <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
                    </AND>
                  </match>
                  <order>BY_NAME</order>
                </rule>
              </section>
              <section>
                <rule>
                  <match>
                    <AND>
                      <NAME>.*</NAME>
                      <XML_NAMESPACE>.*</XML_NAMESPACE>
                    </AND>
                  </match>
                  <order>BY_NAME</order>
                </rule>
              </section>
            </rules>
          </arrangement>
        </codeStyleSettings>
      </value>
    </option>
    <option name="PREFERRED_PROJECT_CODE_STYLE" value="Default (1)" />
  </component>
</project>

================================================
FILE: .idea/codeStyles/Project.xml
================================================
<component name="ProjectCodeStyleConfiguration">
  <code_scheme name="Project" version="173">
    <option name="RIGHT_MARGIN" value="100" />
    <AndroidXmlCodeStyleSettings>
      <option name="USE_CUSTOM_SETTINGS" value="true" />
    </AndroidXmlCodeStyleSettings>
    <JavaCodeStyleSettings>
      <option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="99" />
      <option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="99" />
      <option name="PACKAGES_TO_USE_IMPORT_ON_DEMAND">
        <value />
      </option>
      <option name="IMPORT_LAYOUT_TABLE">
        <value>
          <package name="android" withSubpackages="true" static="false" />
          <emptyLine />
          <package name="com" withSubpackages="true" static="false" />
          <emptyLine />
          <package name="junit" withSubpackages="true" static="false" />
          <emptyLine />
          <package name="net" withSubpackages="true" static="false" />
          <emptyLine />
          <package name="org" withSubpackages="true" static="false" />
          <emptyLine />
          <package name="java" withSubpackages="true" static="false" />
          <emptyLine />
          <package name="javax" withSubpackages="true" static="false" />
          <emptyLine />
          <package name="" withSubpackages="true" static="false" />
          <emptyLine />
          <package name="" withSubpackages="true" static="true" />
          <emptyLine />
        </value>
      </option>
    </JavaCodeStyleSettings>
    <Objective-C-extensions>
      <file>
        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" />
        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro" />
        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef" />
        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum" />
        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant" />
        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global" />
        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct" />
        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl" />
        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function" />
      </file>
      <class>
        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property" />
        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize" />
        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod" />
        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod" />
        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod" />
        <option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod" />
      </class>
      <extensions>
        <pair source="cpp" header="h" fileNamingConvention="NONE" />
        <pair source="c" header="h" fileNamingConvention="NONE" />
      </extensions>
    </Objective-C-extensions>
    <XML>
      <option name="XML_KEEP_LINE_BREAKS" value="false" />
      <option name="XML_ALIGN_ATTRIBUTES" value="false" />
      <option name="XML_SPACE_INSIDE_EMPTY_TAG" value="true" />
    </XML>
    <codeStyleSettings language="XML">
      <option name="FORCE_REARRANGE_MODE" value="1" />
      <indentOptions>
        <option name="CONTINUATION_INDENT_SIZE" value="4" />
      </indentOptions>
      <arrangement>
        <rules>
          <section>
            <rule>
              <match>
                <AND>
                  <NAME>xmlns:android</NAME>
                  <XML_NAMESPACE>^$</XML_NAMESPACE>
                </AND>
              </match>
            </rule>
          </section>
          <section>
            <rule>
              <match>
                <AND>
                  <NAME>xmlns:.*</NAME>
                  <XML_NAMESPACE>^$</XML_NAMESPACE>
                </AND>
              </match>
              <order>BY_NAME</order>
            </rule>
          </section>
          <section>
            <rule>
              <match>
                <AND>
                  <NAME>.*:id</NAME>
                  <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
                </AND>
              </match>
            </rule>
          </section>
          <section>
            <rule>
              <match>
                <AND>
                  <NAME>.*:name</NAME>
                  <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
                </AND>
              </match>
            </rule>
          </section>
          <section>
            <rule>
              <match>
                <AND>
                  <NAME>name</NAME>
                  <XML_NAMESPACE>^$</XML_NAMESPACE>
                </AND>
              </match>
            </rule>
          </section>
          <section>
            <rule>
              <match>
                <AND>
                  <NAME>style</NAME>
                  <XML_NAMESPACE>^$</XML_NAMESPACE>
                </AND>
              </match>
            </rule>
          </section>
          <section>
            <rule>
              <match>
                <AND>
                  <NAME>.*</NAME>
                  <XML_NAMESPACE>^$</XML_NAMESPACE>
                </AND>
              </match>
              <order>BY_NAME</order>
            </rule>
          </section>
          <section>
            <rule>
              <match>
                <AND>
                  <NAME>.*:layout_width</NAME>
                  <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
                </AND>
              </match>
            </rule>
          </section>
          <section>
            <rule>
              <match>
                <AND>
                  <NAME>.*:layout_height</NAME>
                  <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
                </AND>
              </match>
            </rule>
          </section>
          <section>
            <rule>
              <match>
                <AND>
                  <NAME>.*:layout_.*</NAME>
                  <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
                </AND>
              </match>
              <order>BY_NAME</order>
            </rule>
          </section>
          <section>
            <rule>
              <match>
                <AND>
                  <NAME>.*:width</NAME>
                  <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
                </AND>
              </match>
              <order>BY_NAME</order>
            </rule>
          </section>
          <section>
            <rule>
              <match>
                <AND>
                  <NAME>.*:height</NAME>
                  <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
                </AND>
              </match>
              <order>BY_NAME</order>
            </rule>
          </section>
          <section>
            <rule>
              <match>
                <AND>
                  <NAME>.*</NAME>
                  <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
                </AND>
              </match>
              <order>BY_NAME</order>
            </rule>
          </section>
          <section>
            <rule>
              <match>
                <AND>
                  <NAME>.*</NAME>
                  <XML_NAMESPACE>.*</XML_NAMESPACE>
                </AND>
              </match>
              <order>BY_NAME</order>
            </rule>
          </section>
        </rules>
      </arrangement>
    </codeStyleSettings>
  </code_scheme>
</component>

================================================
FILE: .idea/codeStyles/codeStyleConfig.xml
================================================
<component name="ProjectCodeStyleConfiguration">
  <state>
    <option name="PREFERRED_PROJECT_CODE_STYLE" value="Default (1)" />
  </state>
</component>

================================================
FILE: .idea/compiler.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="CompilerConfiguration">
    <option name="DEFAULT_COMPILER" value="Javac" />
    <resourceExtensions />
    <wildcardResourcePatterns>
      <entry name="!?*.java" />
      <entry name="!?*.form" />
      <entry name="!?*.class" />
      <entry name="!?*.groovy" />
      <entry name="!?*.scala" />
      <entry name="!?*.flex" />
      <entry name="!?*.kt" />
      <entry name="!?*.clj" />
    </wildcardResourcePatterns>
    <annotationProcessing>
      <profile default="true" name="Default" enabled="false">
        <processorPath useClasspath="true" />
      </profile>
    </annotationProcessing>
  </component>
</project>

================================================
FILE: .idea/copyright/apache2.xml
================================================
<component name="CopyrightManager">
  <copyright>
    <option name="myName" value="apache2" />
    <option name="notice" value="Copyright (c) 2015 LingoChamp Inc.&#10;&#10;Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);&#10;you may not use this file except in compliance with the License.&#10;You may obtain a copy of the License at&#10;&#10;  http://www.apache.org/licenses/LICENSE-2.0&#10;&#10;Unless required by applicable law or agreed to in writing, software&#10;distributed under the License is distributed on an &quot;AS IS&quot; BASIS,&#10;WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.&#10;See the License for the specific language governing permissions and&#10;limitations under the License." />
  </copyright>
</component>

================================================
FILE: .idea/copyright/profiles_settings.xml
================================================
<component name="CopyrightManager">
  <settings default="apache2">
    <LanguageOptions name="Groovy">
      <option name="fileTypeOverride" value="1" />
    </LanguageOptions>
    <LanguageOptions name="HTML">
      <option name="fileTypeOverride" value="1" />
      <option name="prefixLines" value="false" />
    </LanguageOptions>
    <LanguageOptions name="Properties">
      <option name="fileTypeOverride" value="1" />
    </LanguageOptions>
    <LanguageOptions name="SPI">
      <option name="fileTypeOverride" value="1" />
    </LanguageOptions>
    <LanguageOptions name="XML">
      <option name="fileTypeOverride" value="1" />
      <option name="prefixLines" value="false" />
    </LanguageOptions>
  </settings>
</component>

================================================
FILE: .idea/dictionaries/Jacksgong.xml
================================================
<component name="ProjectDictionaryState">
  <dictionary name="Jacksgong">
    <words>
      <w>buildship</w>
      <w>chunked</w>
      <w>classpathentry</w>
      <w>dreamtobe</w>
      <w>etag</w>
      <w>filedownloader</w>
      <w>gradleclasspathcontainer</w>
      <w>gradleprojectbuilder</w>
      <w>gradleprojectnature</w>
      <w>jacksgong</w>
      <w>javabuilder</w>
      <w>javanature</w>
      <w>liulishuo</w>
      <w>okhttp</w>
      <w>robolectric</w>
      <w>sofar</w>
    </words>
  </dictionary>
</component>

================================================
FILE: .idea/encodings.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="Encoding">
    <file url="PROJECT" charset="UTF-8" />
  </component>
</project>

================================================
FILE: .idea/gradle.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="GradleSettings">
    <option name="linkedExternalProjectsSettings">
      <GradleProjectSettings>
        <compositeConfiguration>
          <compositeBuild compositeDefinitionSource="SCRIPT" />
        </compositeConfiguration>
        <option name="distributionType" value="DEFAULT_WRAPPED" />
        <option name="externalProjectPath" value="$PROJECT_DIR$" />
        <option name="modules">
          <set>
            <option value="$PROJECT_DIR$" />
            <option value="$PROJECT_DIR$/demo" />
            <option value="$PROJECT_DIR$/library" />
          </set>
        </option>
        <option name="resolveModulePerSourceSet" value="false" />
      </GradleProjectSettings>
    </option>
  </component>
</project>

================================================
FILE: .idea/inspectionProfiles/Project_Default.xml
================================================
<component name="InspectionProjectProfileManager">
  <profile version="1.0">
    <option name="myName" value="Project Default" />
    <inspection_tool class="AndroidLintMinSdkTooLow" enabled="false" level="WARNING" enabled_by_default="false" />
    <inspection_tool class="AndroidLintMissingPermission" enabled="false" level="ERROR" enabled_by_default="false" />
    <inspection_tool class="DanglingJavadoc" enabled="false" level="WARNING" enabled_by_default="false" />
    <inspection_tool class="NullableProblems" enabled="false" level="WARNING" enabled_by_default="false">
      <option name="REPORT_NULLABLE_METHOD_OVERRIDES_NOTNULL" value="true" />
      <option name="REPORT_NOT_ANNOTATED_METHOD_OVERRIDES_NOTNULL" value="true" />
      <option name="REPORT_NOTNULL_PARAMETER_OVERRIDES_NULLABLE" value="true" />
      <option name="REPORT_NOT_ANNOTATED_PARAMETER_OVERRIDES_NOTNULL" value="true" />
      <option name="REPORT_NOT_ANNOTATED_GETTER" value="true" />
      <option name="REPORT_NOT_ANNOTATED_SETTER_PARAMETER" value="true" />
      <option name="REPORT_ANNOTATION_NOT_PROPAGATED_TO_OVERRIDERS" value="true" />
      <option name="REPORT_NULLS_PASSED_TO_NON_ANNOTATED_METHOD" value="true" />
    </inspection_tool>
    <inspection_tool class="SameParameterValue" enabled="false" level="WARNING" enabled_by_default="false" />
    <inspection_tool class="SameReturnValue" enabled="false" level="WARNING" enabled_by_default="false" />
    <inspection_tool class="UnusedReturnValue" enabled="false" level="WARNING" enabled_by_default="false" />
    <inspection_tool class="WeakerAccess" enabled="false" level="WARNING" enabled_by_default="false">
      <option name="SUGGEST_PACKAGE_LOCAL_FOR_MEMBERS" value="true" />
      <option name="SUGGEST_PACKAGE_LOCAL_FOR_TOP_CLASSES" value="true" />
      <option name="SUGGEST_PRIVATE_FOR_INNERS" value="false" />
    </inspection_tool>
    <inspection_tool class="unused" enabled="false" level="WARNING" enabled_by_default="false">
      <option name="LOCAL_VARIABLE" value="true" />
      <option name="FIELD" value="true" />
      <option name="METHOD" value="true" />
      <option name="CLASS" value="true" />
      <option name="PARAMETER" value="true" />
      <option name="REPORT_PARAMETER_FOR_PUBLIC_METHODS" value="true" />
      <option name="ADD_MAINS_TO_ENTRIES" value="true" />
      <option name="ADD_APPLET_TO_ENTRIES" value="true" />
      <option name="ADD_SERVLET_TO_ENTRIES" value="true" />
      <option name="ADD_NONJAVA_TO_ENTRIES" value="true" />
    </inspection_tool>
  </profile>
</component>

================================================
FILE: .idea/inspectionProfiles/profiles_settings.xml
================================================
<component name="InspectionProjectProfileManager">
  <settings>
    <option name="PROJECT_PROFILE" value="Project Default" />
    <option name="USE_PROJECT_PROFILE" value="true" />
    <version value="1.0" />
  </settings>
</component>

================================================
FILE: .idea/modules.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="ProjectModuleManager">
    <modules>
      <module fileurl="file://$PROJECT_DIR$/FileDownloader.iml" filepath="$PROJECT_DIR$/FileDownloader.iml" />
      <module fileurl="file://$PROJECT_DIR$/demo/demo.iml" filepath="$PROJECT_DIR$/demo/demo.iml" />
      <module fileurl="file://$PROJECT_DIR$/library/library.iml" filepath="$PROJECT_DIR$/library/library.iml" />
    </modules>
  </component>
</project>

================================================
FILE: .idea/runConfigurations.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="RunConfigurationProducerService">
    <option name="ignoredProducers">
      <set>
        <option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
        <option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
        <option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
      </set>
    </option>
  </component>
</project>

================================================
FILE: .idea/vcs.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="VcsDirectoryMappings">
    <mapping directory="$PROJECT_DIR$" vcs="Git" />
  </component>
</project>

================================================
FILE: .travis.yml
================================================
language: android

jdk:
# build-tools 24.0.2 need jdk8 or above.
- oraclejdk8
android:
  components:
    # Ref https://github.com/travis-ci/travis-ci/issues/6260.
    - tools
    - platform-tools
    - build-tools-28.0.3
    - android-28
    - extra

script:
  - ./gradlew clean check

after_script:
    - cat ./demo/build/outputs/lint-results.xml
    - cat ./library/build/outputs/lint-results.xml

sudo: false

before_cache:
  - rm -f  $HOME/.gradle/caches/modules-2/modules-2.lock
  - rm -fr $HOME/.gradle/caches/*/plugin-resolution/

cache:
  directories:
    - $HOME/.gradle/caches/
    - $HOME/.gradle/wrapper/
    - $HOME/.android/build-cache


================================================
FILE: CHANGELOG-ZH.md
================================================
# Change log

> [ Change log in english](https://github.com/lingochamp/FileDownloader/blob/master/CHANGELOG.md)

## Version 1.7.7

- 修复: FileDownloadThreadPool 可能会抛出 ArrayIndexOutOfBoundsException 和 ClassCastException。 closes #1258
- 修复: 从 1.6.x 升级到 1.7.x 后恢复之前的下载任务时出现 416 错误。
- 修复: Demo 中下载通知示例无法显示通知。closes #1224
- 修复: blockComplete 可能会在主线程中回调。closes #1069
- 修复: NoDatabaseImpl 中 SparseArray 非线程安全问题。closes #1225 

## Version 1.7.6

_2019-02-20_

#### 修复

- 修复: 在Android O以及更高版本手机上,在所有任务结束后自动将前台服务关闭. closes #1096
- 修复: 修复'Context.startForegroundService() did not then call Service.startForeground()'的问题. closes #1104
- 修复: 确保在调用停止任务后,运行中的通知被关闭. closes #1136
- 修复: 修复在重试时小概率NPE. closes #1100

## Version 1.7.5

_2018-08-03_

#### 修复

- 修复: 修复在Android O的系统上,当应用不在前台,并且不在白名单的时候,由于下载服务无法通过`JobScheduler`来执行下载事务,只能通过`startService`,引起 "Not allowed to start service Intent..." 的问题。 closes #1078

#### Enhance

- 提升实用性: 支持`Content-Disposition`中的非UTF-8编码。 closes #1057
- 提高实用性: 处理了阿里云服务错误反馈`416`的情况`。 closes #1050

## Version 1.7.4

_2018-05-19_

#### 修复 

- 修复: 修复在Android 8或更高版本上,当应用在后台时,并且此时正在下载,但是下载服务的链接断开,此时尝试重新绑定的时候发生'IllegalStateException'的问题。closes #1017
- 修复: 修复响应头带回来的文件名可能存在安全隐患的问题. closes #1028

## Version 1.7.3

_2018-04-20_

#### 修复

修复: 修复由于在下载结束时`fd`没有被主动释放,导致当有大量的任务被不断的发起执行时有可能引发的OOM问题。

## Version 1.7.2

_2018-03-14_

#### 修复

- 修复: 将原本所需要下载的文件大小为`0`的时候,回调错误,修改为直接回调完成。closes #789
- 修复: 修复当存在另外一个正在下载的相同临时文件路径的任务时,数据库中存在数据未被删除的问题。closes #953
- 修复: 修复在重试后重试之前下载的进度丢失的问题。closes #949
- 修复: 修复当试探连接没有提供`Content-Range`字段,但是提供`Content-Length`字段时,计算出的总长度始终是`1`的问题。

#### 性能与提高

- 提高实用性: 当在响应头中不存在`Content-Length`字段时,使用隐藏在`Content-Range`中的内容大小数据。 closes #967

## Version 1.7.1

_2018-02-05_

#### 修复

- 修复: 修复当后端不支持`HEAD`方法的时候,返回`405`响应状态导致下载失败的问题。 close #942

## Version 1.7.0

_2018-02-01_

#### 修复

- 修复: 通过同步处理暂停操作与状态的更新来修复状态不是一个正确向前的流的问题。 close #889
- 修复: 修复在`pending`状态回调时带回来已经被弃用的`sofar-bytes`。 close #884
- 修复: 修复当`filename`没有用`"`包裹时,无法通过`content-dispostion`获取文件名的问题。 close #908
- 修复: 修正`setCallbackProgressTimes`设置的次数不能正常生效的问题。 close #901
- 修复: 修复由于试探连接采用`0-infinite`的`Range`导致下载了无用内容到tcp-window的问题。close #933
- 修复: 在连接`ending`的时候再次主动关闭输入流,防止输入流泄漏特别是对于试探连接来说。

#### 性能与提高

- 提高实用性: 当临时文件重命名为目标文件成功时,不再做一次移除临时文件的操作,防止一些文件系统报错的问题。close #912
- 提高实用性: 当确定本地提供的`Range`是正确的,但是后端却返回`416`时,将完全弃用`Range`请求头。close #921
- 提高性能: 为试探连接使用`HEAD`的请求替代`GET`方法,提高试探通信效率。 ref #933

#### 其他

如果你正在使用`filedownloader-okhttp3-connection`,请将其更新到`1.1.0`版本来适配`1.7.0`版本。 

## Version 1.6.9

_2017-12-16_

#### 修复

- 修复(serial-queue): 修复在`FileDownloadSerialQueue`遇到的死锁。 closes #858
- 修复: 不再在非单元测试环境使用`j-unit`,避免在一些小米手机上发生`no-static-method-found`的问题。 closes #867
- 修复: 修复每次重试减少两次重试机会的问题。 closes #838
- 修复: 修复在`pending`的时候暂停任务,而后获取到该任务都是`pending`的状态的问题。 closes #855

#### 性能与提高

- 提高实用性: 开放`SqliteDatabaseImpl`、`RemitDatabase`、`NoDatabaseImpl`,便于上层覆盖他们。
- 提高实用性: 支持从更高的版本降级到该版本。
- 提高实用性: 当上层没有主动添加`User-Agent`的时候,内部添加默认的`User-Agent`。 closes #848
- 提高性能: 修改所有的线程池中线程的存活时间(从5s修改为15s),避免在高频下载中,各池子频繁的释放与创建线程
- 提高性能: 使用`RemitDatabase`作为默认的数据库,在很多小任务很快的结束下载(2s内),其数据库操作将会变得十分冗余,而这部分的数据库操作将被取消

#### RemitDatabase

FileDownloader中大多数数据库长尾问题,是由于有很多很小的任务同时执行:

- 由于很小的任务每次启动、等待、连接、下载进度、结束都会促发入库
- 一旦任务很小网速很快的时候,一个小任务实际下载耗时可能在1-2s完成
- 因此整个引擎不得不为该1-2s完成的任务完成一连串的数据库入库、更新到从数据库删除的操作
- 也就是说单个类似的任务在1-2s内促发了至少5次数据库操作,期间包含入库与最后的删除
- 一个任务还好,当这样的任务数上升到几百个的层面,这样高频持续的数据库操作,就很容易暴露各种数据库问题(包含文件系统问题)
- 而现有体系在上层推任务大量任务到下载服务的时候, 会高频持续的3个并行对这些任务做入库处理,在这个点上数据库问题也容易发生(包含文件系统问题)

---

而相比之下写入数据库是为了断点续传,这个短期的频繁数据库操作,实质的作用甚微,早期的提供外接接口来控制下载进度间的入库频率显然无法覆盖该问题。

---

因此,还是为FileDownloader推出新的`RemitDatabase`用于解决该问题,除去期间的多线程安全问题的处理,核心思想如下:
![][RemitDatabase-png]

- 如果某一个任务的整体数据更新与结束在2s(该值可定制)内,则不再有数据库操作,全程只存内存
- 如果某一个任务的数据更新与结束操过2s,则分为两部分,2s前只存内存,2s开始同时存内存与数据库
- 如果某一个任务最终的结束是暂停或错误,则在最后的状态更新中,同时存内存与数据库

## Version 1.6.8

_2017-10-13_

#### 修复

- 修复: 修复断点续传失败, 由于Network线程中的`isAlive`不可靠导致的问题。 this closes #793
- 修复: 修复断点续传失败,由于多个线程频繁的更新`status`并且`DownloadStatusCallback`的`sendMessage`无法保证有序性,导致下一次启动时最终状态是`process`无法断点续传(具体原因参看[这里](https://github.com/lingochamp/FileDownloader/issues/793#issuecomment-336370126))。 this refs #793, #764, #721, #769, #763, #761, #716
- 修复: 不再由于任务已经结束依然存在需要派发的信息而让用户程序奔溃,因为这个对用户并不会照成影响。 this closes #562
- 修复: 修复当用户频繁调用`pause`时,有可能出现`it can't take a snapshot for the task xxx`错误的问题。
- 修复: 修复由于内部存储的任务对象大小存在问题,导致这样的对象任务每一次启动都必然会`416`的问题。

## Version 1.6.7

_2017-10-12_

#### 修复

- 修复: 避免`error`与`pause`的状态被运行中的状态覆盖导致下次断点续传失败。 closes #769, closes #764, closes #761, closes #763, closes #721, closes #716
- 修复: 感谢 @hongbiangoal 对问题的定位,修复了当某一个分块的断点进度大于1.99G时,请求的范围出现负数的情况。 closes #791

## Version 1.6.6

_2017-09-29_

#### 修复

- 修复(文件完整性): 只有在确保缓存已经完全固化到本地文件了才更新数据库的进度,防止在该次暂停时固化失败,然后数据库更新了进度,导致下一次断点续传的时候(使用预分配策略的情况下),本地已经下载的文件的进度与数据库记录的进度实际不一致,导致最后下载完成了文件不完整的问题。 Closes #745
- 修复(清理): 修复调用`FileDownloader#clearAllTaskData`并没有清理连接表的问题。 Closes #754

#### 性能与提高

- 提高性能: 使用`BufferedOutputStream`来优化默认输出流,现在虚拟机内的缓存大小为8192字节。

## Version 1.6.5

_2017-09-11_

#### 修复

- 修复(crash): 修复因为使用`%d`格式化`AtomicLong`导致`IllegalFormatConversionException`的问题。 Closes #743

## Version 1.6.4

_2017-08-21_

#### 新接口

- 新增 `NoDatabaseImpl`: 为了有些用户需要一个没有数据库的FileDownloader的用户。 Refs #727

#### 性能与提高

- 提高性能: 使用`AtomicLong`代替锁的方式,使得下载进度递增性能更好。

#### 修复

- 修复(分块下载): 修复在断点续传时之前已经下载了分块下载的最后一块,可是在继续下载时重新请求了最后一块给了错误的Range导致416的错误。 Closes #737
- 修复(npe): 修复极小概率当事件监听已经被其他线程移除时还在分发事件导致NPE的问题。 Closes #723

## Version 1.6.3

_2017-07-29_

#### 修复

- 修复: 修复当正在处理回调结束任务的事务时,调用了`pause`极小概率出现NPE的问题。 Closes #680
- 修复: 修复当暂停或恢复`FileDownloaderSerialQueue`的时候,其已经完成了该操作,出现`MissingFormatArgumentException`的问题。 Closes #699

## Version 1.6.2

_2017-07-16_

#### 修复

- 修复: 修复当FileDownloader下载文件有一个分块从大于1.99G的地方开始下载,就会发生'offset < 0'异常的问题。 Closes #669

## Version 1.6.1

_2017-07-13_

#### 性能与提高

- 提高实用性: 当返回的`content-length`不等于通过Range计算出来的`content-length`时直接抛回`GiveUpException`而不继续下载。 Closes #636

#### 修复

- 修复: 修复下载出现错误或暂停下载时强制多`sync`了一次的问题。
- 修复: 修复当从断点中恢复chuncked任务后下载文件被损坏的问题。

## Version 1.6.0

_2017-07-07_

#### 修复

- 修复(no-response): 修复当多线程分块下载同时完成时,有可能会由于线程安全问题导致completed无法得到回调的问题,具体情况参看[这里](https://github.com/lingochamp/FileDownloader/issues/631#issuecomment-313387299)。 Closes #631

## Version 1.5.9

_2017-07-04_

#### 修复

- 修复(duplicate-permission): 修复在Android 5.0或更高版本系统的手机中已经有一个应用引用了1.5.7或更新版本的FileDownloader后,再安装引用1.5.7或更新版本的FileDownloader的应用会报`INSTALL_FAILED_DUPLICATE_PERMISSION`的问题,这个问题是因为在1.5.7版本中我们申明了一个接收结束广播的权限导致,现在我们移除了这个权限申明来修复这个问题。Closes #641

## Version 1.5.8

_2017-06-28_

#### 修复

- 修复(无响应): 修复非常快速的对相同任务启动、暂停来回切换会使得任务到后面没有响应的问题。Closes #625

## Version 1.5.7

_2017-06-25_

#### 新接口

- 支持在`filedownloader.properties`中配置`broadcast.completed`: 决定是否需要在任务下载完成后发送一个完成的广播。 Closes #605
- 支持接收201的http返回状态码。 Closes #545
- 为`FileDownloadSerialQueue`支持暂停与继续功能. Closes #547
- 在FileDownloader内部处理了各类重定向的情况(300、301、302、303、307、308)。 Closes #611
- 弃用了`FileDownloader#init`取而代之的是`FileDownloader#setup`,现在如果你不需要定制组件,就只需要在使用FileDownloader之前的任意使用调用这个方法就行。 Closes #500

> - 如果你使用`broadcast.completed`并且接收任务完成的广播,你需要在AndroidManifest中注册Action为`filedownloader.intent.action.completed`的广播并且使用`FileDownloadBroadcastHandler`来处理接收到的`Intent`。
> - 现在, 不再使用`FileDownloader#init`, 取而代之的,如果你需要注册你的定制组件,你需要在`Application#onCreate`中调用`FileDownloader.setupOnApplicationOnCreate(application):InitCustomMaker`, 否则你只需要在使用FileDownloader之前的任意时候调用`FileDownloader.setup(Context)`即可。

#### 修复

- 修复: 修复来`FileDownloadQueueSet`无法处理使wifi-required失效的操作。 感谢 @qtstc
- 修复(output-stream): 修复当提供的output-stream不支持seek时,FileDownloader无法使用的问题。 Closes #622

#### 性能与提高

- 提高实用性: 覆盖使用不同的Url来复用下载进度的情况(结合`idGenerator`一起使用)。 Closes #617

## Version 1.5.6

_2017-06-18_

#### 修复

- 修复(crash): 修复当调用`findRunningTaskIdBySameTempPath`的同时请求了暂停可能导致NPE奔溃的问题。 Closes #613
- 修复(crash): 修复返回状态是`206`并且它的ETAG发生变化时导致`IllegalArgumentException`错误奔溃的问题。 Closes #612
- 修复(crash): 修复当用户请求下载需要Wifi并当前不是Wifi环境时,出现`FileDownloadNetworkPolicyException`未处理导致奔溃的问题。 感谢 @qtstc
- 修复(crash): 修复当用户直接从`v1.4.3`升级到`v1.5.2`并且在一些其他综合因素下(具体可以参见 #610 ) 初始化数据库时出现`IllegalStateException`错误奔溃的问题。Closes #610
- 修复(crash): 修复当回调流已经结束当时与此同时刚好出现错误或下载完成或暂停,小概率会出现`IllegalStateException`奔溃的问题。
- 修复(no-response): 修复在接收到`connected`回调之后,多线程下载建立连接,此时在检验连接与数据获取连接期间服务端数据发生错误或变更导致启动下载后没有响应的问题。

#### 性能与提高

- 提高实用性: 当父级目录创建失败时直接回调`error`。 Closes #542
- 提高实用性: 处理了返回状态是`416`的情况。 Refs #612

## Version 1.5.5

_2017-06-12_

#### 修复

- 修复(max-network-thread-count): 修复当任务都是多线程下载时,`download.max-network-thread-count`参数没起作用,并同时下载任务无上限的问题。 Closes #607

## Version 1.5.4

_2017-06-11_

#### 新接口

- 通过`IdGenerator`支持了定制下载任务id生成器。 Closes #224

#### 性能与提高

- 提高实用性: 将`FileDownloadModel`的维护从`FileDownloadDatabase`中解藕,让`FileDownloadDatabase`只关心数据库相关操作。
- 提高实用性: 将数据库初始化的维护工作从默认的数据库实现中解藕出来,让定制的数据库也能够被采用相同机制维护到。

## Version 1.5.3

_2017-06-08_

#### 修复

- 修复(crash): 修复在计算平均速度的过程中`connected`与`completed`几乎同时回调时发生`divide by zero`异常的问题。 Refs #601
- 修复(crash): 修复触发暂停的同时,`FetchDataTask`已经被创建并请求执行,但是还没有来得及被执行,导致NPE奔溃的问题。 Closes #601

## Version 1.5.2

_2017-06-07_

#### 修复

- 修复(crash): 修复当任务需要回调`error`或者被暂停时,刚好该任务的某个或几个链接完成下载,此时遇到NPE或者是`ConcurrentModificationException`的异常。Closes #598
- 修复(crash): 修复当任务被暂停时,任务从开始到被暂停还没来得及同步一次数据到文件系统或者数据库,此时遇到NPE的异常。Refs #598
- 修复(crash): 修复当采用多链接下载一个任务时,非首次建链失败或者是创建`FetchDataTast`失败,此时遇到NPE的异常。Refs #598
- 修复(speed-calculate): 修复忽略整个下载进度回调,并且只使用`FinishListener`时,此时下载速度始终是`0`的问题。
- 修复(finish-listener): 修复对于之前已经下载好的任务,并且只监听来`FinishListener`,此时`FinishListener`的`over`方法不会被回调到的问题。

#### 性能与提高

- 提升性能: 开启了默认数据库的WAL,使得读与写可并行操作来提高性能,因为我们的绝大多数场景读写是会在不同线程中同时执行的,开启这个以后会导致内存的增加,但是在大多数情况下极大的提高了数据库的写入速度,并且更加稳定(更少的使用`fsync()`)。

## Version 1.5.1

_2017-06-05_

#### 修复

- 修复(crash): 修复在`FileDownloader.init`中,当没有提供`InitCustomMaker`时出现的NPE奔溃。 Closes #592
- 修复(callback): 修复当之前有多个链接服务于该任务并且正在从端点恢复时,在`pending`中没有带回其正确的`sofarBytes`的问题。
- 修复(speed-monitor): 矫正`IDownloadSpeed.Monitor`在断点续传下总平均速度不准确的问题。

#### 性能与提高

- 提高稳定性: 当触发暂停时,主动同步FetchTask中的进度确保其进度得到固化到文件系统。
- 提高稳定性: 当在`FileDownloader.init`中提供的`context`为空时,抛`IllegalArgumentException`以更早的暴露问题。

## Version 1.5.0

_2017-06-05_

#### 新接口

- 支持对单个任务多连接(多线程)下载。  Closes #102
- 支持通过`ConnectionCountAdapter`定制对每个任务使用连接(线程)数据的定制(可以通过`FileDownloader#init`设置进去)

#### 性能与提高

- 提高性能: 重构整个下载的逻辑与原始回调逻辑,并删除了1000行左右的`FileDownloadRunnable`。

对于每个任务默认的连接(线程)数目策略,你可以通过`ConnectionCountAdapter`来定制自己的策略:

- 1个连接(线程): 文件大小 [0, 1MB)
- 2个连接(线程): 文件大小 [1MB, 5MB)
- 3个连接(线程): 文件大小 [5MB, 50MB)
- 4个连接(线程): 文件大小 [50MB, 100MB)
- 5个连接(线程): 文件大小 [100MB, -)

## Version 1.4.3

_2017-05-07_

#### 修复

- 修复: 移除重复的被弃用的方法: `FileDownloader#init(Application)`, 因为`Application`是 `Context`的实现。

## Version 1.4.2

_2017-03-15_

#### 修复

- 修复(Same File Path): 避免多个问题同时对相同的文件写入,一旦存在另外一个正在运行中的任务与当前任务的文件存储路径一致,当前任务将会收到`PathConflictException`来拒绝启动。 Closes #471

#### New Interfaces

-  新增 `FileDownloadSerialQueue#getWaitingTaskCount`: 获取动态串行队列中正在等待启动的任务个数。Refs #345

## Version 1.4.1

_2017-02-03_

#### 修复

- 修复(高并发): 修复由于Messenger在已经收到结束的信息将Task对象赋值为Null以后依然收到其他消息,导致NPE的问题。 Closes #462
- 修复(`FileDownloadHttpException`): 修复由于在建立连接后无法取到请求头以至于遇到`FileDownloadHttpException`时发生`IllegalStateException`的问题。 Closes #458

## Version 1.4.0

_2017-01-11_

#### 性能与提高

- 提高性能: 优化`FileDownloader#init`中的逻辑, 使其更加的轻量(仅仅做了赋值`context`与`maker`的操作)

#### 修复

- 修复(pause): 修复高并发情况下,当在启动一个任务的时候,很短的时间间隔内去暂停一个任务,可能无法暂停下来任务的问题。 Closes #402
- 修复(init FileDownloader): 修复在很低概率下在`FileDownloadService`所在进程初始化FileDownloader时出现Crash的问题。 Closes #420  
- 修复(FileDownloadHttpException): 修复在遇到`FileDownloadHttpException`类型Crash时,由于字符串的formatter无法匹配导致Crash的问题 Closes #438

## Version 1.3.9

_2016-12-18_

### 核心:

- 这个版本开始,你可以定制自己的网络连接组件: [FileDownloadConnection][FileDownloadConnection-java-link],默认情况下我们使用[这个][FileDownloadUrlConnection-java-link]。
- 这个版本开始,我们不再默认依赖okhttp,你可以根据自己的需求进行定制。(如果你依然想要使用okhttp,可以考虑集成下这个[仓库](https://github.com/Jacksgong/filedownloader-okhttp3-connection))

> 如果你依然需要配置`timeout`、`proxy`,请不用担心,我已经对默认的网络连接组件实现了这几个接口: [DemoApplication](https://github.com/lingochamp/FileDownloader/blob/master/demo/src/main/java/com/liulishuo/filedownloader/demo/DemoApplication.java#L35),如果有需要可以看看。

#### 新接口

- 新增 `FileDownloadQueueSet#reuseAndStart`: 添加 '复用并启动'接口,主要用于在启动队列任务之前,先对任务队列中的所有任务进行尽可能的复用。 Ref #383
- 新增 `FileDownloadConnection`: 支持定制化网络连接组件,不再默认依赖okhttp。 Closes #158

## Version 1.3.0

_2016-10-31_

#### 新接口

- 新增 `FileDownloadSerialQueue`: 便于动态管理串行执行的队列。 Closes #345.
- 移除 `FileDownloadListener`类中的`callback`方法, 并且新增`FileDownloadListener#isInvalid`方法,用于告知FileDownloader该监听器是否已经无效,不再接收任何消息。
- 新增 `FileDownloader#clearAllTaskData`: 清空`filedownloader`数据库中的所有数据。 Closes #361.

#### 性能与提高

- 提高实用性(`FileDownloadListener#blackCompleted`): 确保`blockCompleted`回调可以接收任何的`Exception`。 Closes #369.
- 提高实用性(service-not-connected): 在service-not-connected-helper中输出提示与原因, 这样当你调用有些需要确保下载服务已经连接上的方式,但下载服务没有连接上时,不但在`Logcat`中可以收到原因,还能收到提示。

#### 修复

- 修复(reuse): 修复调用`BaseDownloadTask#pause`之后短时间内调用`BaseDownloadTask#reuse`方法,可能会抛出异常的问题。 Closes #329.

## Version 1.2.2

_2016-10-15_

#### 修复

- 修复(fatal-crash): 修复当任务没有`FileDownloadListener`时,也不能收到该任务`FileDownloadMonitor.IMonitor#onTaskOver`的回调的问题。 Closes #348.

## Version 1.2.1

_2016-10-09_

#### 修复

- <s>修复(fatal-crash): 修复当任务没有`FileDownloadListener`时,也不能收到该任务`FileDownloadMonitor.IMonitor#onTaskOver`的回调的问题。 Closes #348.</s> 十分的抱歉这个问题在1.2.1版本中依然存在,最终在1.2.2中验证修复。

## Version 1.2.0

_2016-10-04_

#### 新接口

- 新增 `FileDownloader#insureServiceBind()`: 便于阻塞当前线程,并且启动下载服务,服务启动之后再执行需要服务的请求。 Refs #324.
- 新增 `FileDownloader#insureServiceBindAsync()`: 便于启动下载服务,并且在服务启动之后,执行需要下载服务的请求。 Refs #324.
- 新增 `FileDownloader#bindService(runnable:Runnable)`: 便于启动下载服务,并且在服务启动之后,执行 `runnable`。 Refs #324.
- 新增 `FileDownloader#init(Context,InitCustomMaker)`: 便于初始化下载引擎的时候可以传入更多的定制化组件。 Refs #157.

#### Enhancement

- 提高实用性(`InitCustomMaker#database`): 支持定制化数据库组件(`FileDownloadDatabase`),并且实现默认的数据库组件: `DefaultDatabaseImpl`。 Closes #157.
- 提高实用性(`InitCustomMaker#outputStreamCreator`): 支持定制化输出流组件(`FileDownloadOutputStream`),并且实现默认的输出流组件: `FileDownloadRandomAccessFile`,与一些可替代的组件: `FileDownloadBufferedOutputStream`、`FileDownloadOkio`。Closes #301.

## Version 1.1.5

_2016-09-29_

#### 新接口

- 支持在`filedownloader.properties`中配置`file.non-pre-allocation`: 是否不需要在开始下载的时候,预申请整个文件的大小(`content-length`), 默认值是`false`。Closes #313 .

#### 修复

- 修复(fatal-crash): 修复由于`ThreadPoolExecutor#getActiveCount()`是一个大概的值,导致在其反回的不是正确值时,thread-pool库中存在`StackOverflowError`Crash的问题。Closes #321 .
- 修复(minor-crash): 修复在一些小概率情况下出现Crash Message是'No reused downloaded file in this message'的IllegalStateException的问题。 Closes #316 .
- 修复(minor-crash): 修复当在下载服务还没有连接上时,同时有几个串行队列任务需要执行,在一些小概率的情况下,一些相同的任务会被启动两次导致crash的问题。 Refs #282 .

#### 其他

- 依赖: 取消对thread-pool库的依赖。 Refs #321 .
- MinSDKVersion: 升级`minSdkVersion` : 8->9。 Refs #321 .

## Version 1.1.0

_2016-09-13_

#### 新接口

- 新增 `BaseDownloadTask#setWifiRequired`: 设置任务是否只允许在Wifi网络环境下进行下载。 默认值 `false`。 Closes #281 .

#### 性能与提高

- 提高性能: 替换所有的线程池为exceed-wait-pool(更多详情参见: `FileDownloadExecutors`) 并且所有线程池中的线程将会在闲置五秒后自动结束。 Refs #303 .
- 提高实用性: 当有异常从`FileDownloadListener#blockComplete`抛出时,将会被`catch`并且回调到`FileDownloadListener#error`中而非回调`FileDownloadListener#completed`。 Closes #305 .

#### 修复

- 修复(lost-connect): 避免等待服务连接的列表中在一些小概率情况下存在重复任务的问题。

## Version 1.0.2

_2016-09-06_

#### 修复

- 修复: 服务还没有连接上时,启动的'队列任务'被放在等待队列,当服务连接上以后,FileDownloader尝试重启这些等待队列中的任务,但是抛了`IllegalStateException`的Bug。 Closes #307 .

## Version 1.0.1

_2016-09-05_

#### 新接口

> 如果你之前有使用现在已经被申明弃用的方法`BaseDownloadTask#ready()`, 只需要简单的将它迁移为:`BaseDownloadTask#asInQueueTask():InQueueTask`并且调用`InQueueTask#enqueue()`。

- 添加`BaseDownloadTask#asInQueueTask():InQueueTask`并申明弃用`BaseDownloadTask#ready()`: 申明当前任务是队列任务,并且可以通过`InQueueTask#enqueue()`将当前任务放入全局队列以便于启动队列任务的时候,能被队列收编执行。`InQueueTask#enqueue()`中的操作与`BaseDownloadTask#ready()`相同, 我们通过这个方式封装`ready()`是为了让你更加清晰的了解: 只有当前任务是队列任务,才需要调用该方法;如果当前任务不是队列任务,而却调用了这个方法,你将会收到一个异常(具体异常的原因可以移步到`DownloadTask#start`报的异常信息进行了解)。

#### 修复

- 修复: 当有使用相同`listener`对象的多个孤立任务与队列任务在不同的线程中同时被启动时(后),有可能会遇到IllegalStateException异常的问题。 Closes #282 .

## Version 1.0.0

_2016-08-21_

#### 新接口

- 添加 `BaseDownloadTask#cancel`: 这个方法是为了说明为什么`pause`的操作也可以达到`cancel`的作用。

#### 性能与提高

- 提高性能: 持有`isDownloaderProcess`的结果,防止多次判断。
- 提高实用性: 重构代码的可见层。Closes #283
- 提高实用性: 完善Java Doc。Closes #284
- 提高实用性: 提供Java Doc 站点: http://fd.dreamtobe.cn 。Closes #284

## Version 0.3.5

_2016-08-16_

#### 性能与提高

- 提高实用性: 为FileDownloader中的所有线程添加线程名。
- 提高性能: 调整`block-completed-thread-pool`中的核心线程数: 5->2,减少资源的浪费。

#### 修复

- 修复(SQLiteFullException): 覆盖了在整个下载过程中可能遇到`SQLiteFullException`的错误,就捕获相关错误并回调回 `FileDownloadListener#error` 。 Closes #243
- 修复(提供目录的情况): 修复若是提供的是文件夹,并且对应的任务已经下载完成,再次启动的时候,在直接回调`FileDownloadListener#completed`时,获取的`targetFilePath`可能为null的问题。 Closes #237

## Version 0.3.4

_2016-07-31_

#### 新接口

- 添加 `FileDownloader#clear`: 用于强制根据任务ID清理其在filedownloader中的数据。Closes #218

#### 性能与提高

- 提高实用性: 为 `FileDownloader#start(FileDownloader, boolean)` 添加返回值: 是否成功启动任务下载。Closes #215
- 提高实用性: `FileDownloader#pause` 暂停任务时,不再仅仅是暂停一个任务,而是暂停掉所有ID为指定ID的运行中的任务。

#### 修复

- 修复(初始化-CRASH): 修复初始化FileDownloader时,从`ActivityManager`获取到运行中进程信息为空时发生CRASH。Closes #210
- 修复(小概率-CRASH): 修复当FileDownloadService已经`onDestroy`后,还接收到`snapshot-message`时发生CRASH的情况。 Closes #213
- 修复(消息流准确性): 在真正启动下载时删除目标文件,以此保证当有相同任务正在下载时,获取下载状态,不会获取到已经下载完成的错误的状态。Closes #220
- 修复(启动线性下载): 收集未绑定的任务进行启动而非只是根据FileDownloadListener去收集任务,修复无法启动两个相同`FileDownloadListener`的队列。Closes #233
- 修复(清理Messenger): 在回调 结束的消息 的回调之前进行清理任务的Messenger,而非在回调之后清理,以此确保在回调方法中可以调用`BaseDownloadTask#reuse`。Closes #229

#### 其他

- 所依赖的okhttp从`3.3.1`升到`3.4.1`。

## Version 0.3.3

_2016-07-10_

#### 新接口

- 添加 `FileDownloadUtils#getTempPath`: 获取用于存储还未下载完成文件的临时存储路径: `filename.temp`。 Refs #172.
- 添加 `FileDownloadUtils#isFilenameConverted(context:Context)`: 判断是否所有数据库中下载中的任务的文件名都已经从`filename`(在旧架构中)转为`filename.temp`。
- 添加 `FileDownloader#getStatusIgnoreCompleted(id:int)`:  获取不包含已完成状态的下载状态(如果任务已经下载完成,将收到`INVALID`)。
- 添加 `FileDownloader#getStatus(id:int, path:String)`:  获取下载状态。
- 添加 `FileDownloader#getStatus(url:String, path:String)`:  获取下载状态
- 添加 `FileDownloadUtils#generateId(url:String, path:String, pathAsDirectory:boolean)`: 生成可以被FileDownloader识别的`Download Id`。
- 添加 `BaseDownloadTask#setPath(path:String, pathAsDirectory:boolean)`: 如果`pathAsDirectory`是`true`,`path`就是存储下载文件的文件目录(而不是路径),此时默认情况下文件名`filename`将会默认从`response#header`中的`contentDisposition`中获得。
- 添加 `BaseDownloadTask#isPathAsDirectory`: 判断`BaseDownloadTask#getPath()`返回的路径是文件存储目录(`directory`),还是文件存储路径(`directory/filename`)。
- 添加 `BaseDownloadTask#getTargetFilePath`: 获取目标文件的存储路径。
- 添加 `FileDownloadQueueSet#setDirectory`: 设置队列中所有任务文件存储的目录。

#### 性能与提高

- 提高实用性: 支持将`path`作为目录来存储文件,在这个情况下,文件名默认将从`response#header`中的`contentDisposition`中获得。 Refs #200.
- 提高实用性: 将还未下载完成的文件存储在临时文件中(`filename.temp`)。 Refs #172.
- 提高性能: FileDownloader不再将已经完成下载的任务存储在数据库中,判定任务是否已经下载完成,直接通过判断目标文件是否存在。 Refs #176, #172.
- 提高稳定性: 选用状态是`INVALID`或`progress`优先接收`completed`消息, 以此确保`connected`状态的任务能够留下来接收`progress`状态的消息。 Refs #123
- 提高稳定性: 扩张 __任务同步锁__ 到 __获取相同ID任务队列__ 的外面,以此修复由于有些状态在 __获取相同ID任务队列__ 与 __等待任务同步锁__ 的过程中已经被改变导致有些消息不能被消耗的问题。

#### 修复

- 修复(DB-维护): 保留状态是`pending`并且已经下载的字节数大于0的Model,因为这些Model可以用于恢复断点续传。 Closes #176.
- 修复(crash-NPE): FileDownloader 可能遇到NPE当下载监听器被移除,但是对应任务还在FileDownloader中运行。 Closes #171.

## Version 0.3.2

_2016-06-12_

#### 新接口

- 添加 `BaseDownloadTask#setCallbackProgressMinInterval`: 用于设置每个'progress'方法回调的间隔。 Closes #167 .
- 添加 `FileDownloader#setMaxNetworkThreadCount`: 用于设置最大同时下载的数目(最大同时运行的网络线程)。 Closes #168.
- 添加 `FileDownloader#init(Context,OkHttpClientCustomMaker,int)`: 在下载服务初始化的时候接受设置最大同时下载数目(最大同时运行的网络线程)。 Closes #168.

#### 性能与提高

- 提高稳定性: 确保每个'progress'回调方法之间的最小间隔是5ms,防止对于一个任务而言'progress'回调太频繁导致'防掉帧队列'极速膨胀导致各类Action响应都延时。 Closes #167.
- 提高实用性: 在请求的操作需要在下载服务中完成,但是还未连接上下载服务时,输出对应的'warn'级别的日志。
- 提高性能: 使用`SparseArray`代替`HashMap`用于索引所有的`FileDownloadModel`。

#### 修复

- 修复(crash): 修复在某个下载任务开始下载时,发现任务的状态不正确的情况下,输出日志中提供了错误的参数类型导致的Crash。
- 修复(强制重新下载): 修复错误逻辑导致设置`BaseDownloadTask#setForceReDownload(true)`并且任务已经下载完成会促发'warn'的回调,却没有进行强制重新下载的Bug。
- 修复(class-type): 保持`SocketTimeOutException`的Class类型,不再关心`Throwable`的`message`是否为空。

#### 其他

- 所依赖的okhttp从`3.2.0`升到`3.3.1`。

## Version 0.3.1

_2016-05-19_

#### 性能与提高

- 提高稳定性: 在结束下载时确保缓存中的数据都写入文件。

## Version 0.3.0

_2016-05-13_

#### 修复

> 为什么FileDownload服务可以运行在UI进程? 参考 [filedownloader.properties](https://github.com/lingochamp/FileDownloader/wiki/filedownloader.properties).

- 修复(下载服务共享UI进程时): 修复在下载服务不是运行在独立进程的情况下(非默认情况),附加的header没有带上请求的bug。Closes #149.

## Version 0.2.9

_2016-05-10_

#### 新接口

- 添加 `BaseDownloadTask#isUsing():boolean`: 用于判断当前的Task对象是否在引擎中启动过. Closes #137 。

#### 修复

- 修复(高并发情况下的npe): 当任务的状态是一个未预期的状态是,提供一个默认的错误快照,避免出现npe 。
- 修复(返回错误码-416): 覆盖返回错误码是416或者当出现已下载大小大于等于文件总大小的时候依然断点续传的bug。

## Version 0.2.8

_2016-05-02_

#### 新接口

- 添加 `BaseDownloadTask#getId():int`: 弃用(没有删除该接口) `getDownloadId()`, 建议使用 `getId()` 代替 。

#### 性能与提高

- 提高稳定性: 重构任务启动器,使得启动任务更加可维护,以及标记任务过期更加可靠。
- 提高稳定性: 重构将事件派发给`FileDownloadListener`的体系,新的体系就如同,派件员与快递驿站的关系,每次都会对事件进行快照,打包为一个消息快件,派发到驿站,转包给 `FileDownloadListener`。
- 提高稳定性: 覆盖所有的有关暂停的高并发情况,删掉一些符合预期的警告性日志。
- 提高性能: 减少FileDownloader database I/O 。
- 提高性能: 减少创建对象(更少的内存分配请求,对于GC友好)对于每次回调, 对于一个下载状态的更新,只创建一个快照,整个通讯架构使用。

#### 修复

- 修复: 提供明确的locale用于格式化字符串,避免一些默认locale是非预期的情况发生。Closes #127

## Version 0.2.7

_2016-04-22_

#### 新接口

- 添加 `FileDownloader#setTaskCompleted(taskAtomList:List<FileDownloadTaskAtom>)`: 用于告诉FileDownloader引擎,指定的一系列的任务都已经通过其他方式(非FileDownloader)下载完成。

#### 性能与提高

- 提高稳定性: 假如在下载进程调用 `bindService` 直接抛异常,防止用户在使用过程中,错误的在下载进程绑定服务,而没有暴露这个根本问题,引发其他一系列的异常。Closes #119。

## Version 0.2.6

_2016-04-20_

#### 新接口

- 调整: 将原本需要在根目录创建的 `filedownloader.properties` ,改为到 模块的 `assets` 目录下, 如 `/demo/src/main/assets/filedownloader.properties`。

#### 修复

- 修复 `filedownloader.properties` 中的参数不起作用的bug。 Closes #117.

## Version 0.2.5

_2016-04-19_

#### 新接口

- 添加 `FileDownloader#setTaskCompleted`: 用于告诉FileDownloader引擎,以指定Url与Path的任务已经通过其他方式(非FileDownloader)下载完成。
- 支持 新的配置参数`download.max-network-thread-count` 在 `filedownloader.properties`: 同时下载的最大网络线程数,默认值是3。 Closes #116.

## Version 0.2.4

_2016-04-18_

#### 新接口

- 添加 `BaseDownloadTask#getSpeed` 以及 `BaseDownloadTask#setMinIntervalUpdateSpeed`: 获取任务的下载速度, 下载过程中为实时速度,下载结束状态为平均速度。 Closes #95 。
- 添加 `FileDownloader#startForeground` 以及 `FileDownloader#stopForeground` 用于支持 前台模式([Service#startForeground](http://developer.android.com/intl/zh-cn/reference/android/app/Service.html#startForeground(int, android.app.Notification))),保证用户从最近应用列表移除应用以后下载服务被杀。 Closes #110 。
- 支持 新的配置参数 `download.min-progress-step` 以及 `download.min-progress-time`: 最小缓冲大小以及最小缓冲时间,用于判定是否是时候将缓冲区中进度同步到数据库,以及是否是时候要确保下缓存区的数据都已经写文件。这两个值越小,更新会越频繁,下载速度会越慢,但是应对进程被无法预料的情况杀死时会更加安全。默认值是与 `com.android.providers.downloads.Constants`中的一致 65536(最小缓冲大小) 以及 2000(最小缓冲时间)。
- 支持 新的配置参数 `process.non-separate` 在 `filedownloader.properties` 中 : FileDownloadService 默认是运行在独立进程 `:filedownloader` 上的, 如果你想要FileDownloadService共享并运行在主进程上,以减少不必要的消耗(如IPC的I/O,维护进程的CPU的消耗等), 添加将该配置参数值设置为 `true`。 Closes #106 。

#### 性能与提高

- 提高性能: 提高了下载速度, 优化了同步缓冲区的数据到本地文件以及数据库的架构,很大程度的提高了下载速度。 Closes #112 。

#### 修复

- 修复: 无法重新启动一个已经暂停但是依然存在下载线程池中在pending中的任务。 Closes #111 。

## Version 0.2.3

_2016-04-11_

#### 新接口

- 添加 `FileDownloadOutOfSpaceException`, 当将要下载的文件大小大于剩余磁盘大小时,会抛出这个异常。
- 在 `FileDownloadListener` 新增 `started` 回调方法: 在结束 `pending` 开始运行当前任务的线程时,回调该方法。
- 在 `FileDownloadMonitor.IMonitor` 新增 `onTaskStarted` 回调方法,用于监控在结束 `pending` 开始运行当前任务的线程时,回调该方法。这样就可以在监控中通过 `onTaskBegin`到`onTaskStarted`计算出pending的时间,在`onTaskStarted`到`onTaskOver`计算出真正消耗在下载的时间(Connection、Fetching)。

#### 性能与提高

- 提高实用性: 为 `FinishListener` 的 `over` 方法提供所指向的Task,为了有些时候我们为多个任务添加相同的 `FinishListener` 时,需要这个参数来判断当前是哪个任务的回调。 Closes #69 。
- 提高稳定性: 如果调用一个正在运行中的Task对象的 `start` 方法,直接抛异常;并且为已经结束的Task对象提供 `BaseDownloadTask#reuse` 进行复用。 Closes #91 。
- 提高性能: 在进入事件队列之前,拦截掉一些原本就没有监听器进行监听的事件。

#### 修复

- 修复: 在一些极端情况下,非结束的回调回调次数不符合预期的情况。
- 修复: `progress` 方法的回调中包含了对完成( `sofarBytes==totalBytes` )的回调,导致回调间隔不达预期的bug。
- 修复: 在 `warn` 回调带回 total-bytes,为了覆盖在 主进程被杀,下载进程存在的情况下,主进程重新重启并启动相同任务,total-bytes为0的bug。 Closes #90 。
- 修复: 如果连续出现失败,连续回调 `retry` 时,`retry` 只被回调一次,其他的次数的 `retry` 都不被回调的bug。 Refs: #91 。
- 修复: 在无网络状态下,启动下载,如果存在重试的机会,下载的进度被覆盖,导致下次无法断点续传的bug。 Closes #92 。
- 修复: 有可能在'检测是否可以复用'到'检测是否在下载队列'的这段时间内已经下载完成但是任务还在队列中的极端情况。
- 修复: 线性任务,在下载进程被杀重新启动被转为并行任务的bug。

## Version 0.2.2

_2016-04-06_

#### 新接口

- 添加 `FileDownloadHttpException` 与 `FileDownloadGiveUpRetryException`, 优化异常回调处理机制. Closes #67 。
- 初始化 `FileDownloader` 传入参数由原来需要 `Application` 改为 需要 `Context`( `FileDownloader#init(Context)` ), 优化接口,并且便于单元测试。 Closes #54 。

#### 性能与提高

- 提高稳定性: 在开始获取数据之前,先检查是否有足够的空间用于存储下载文件,如果不够直接抛异常,如果足够将锁定对应空间用于正常存储正在下载的文件。 Closes #46 。
- 提高实用性: 断点续传支持,不再强制要求Etag存在;支持不需要Etag,只要后台支持 `Range` 头部参数就可以支持断点续传。 Close #35 , #66 。

#### 修复

- 修复: 在 `FileDownloadLog.NEED_LOG` 为 `true` 时,并且事件无效的情况下,`EventPool` 出现 `IllegalFormatConversionException` 异常的问题。 Closes #30 。
- 修复: 在 Filedownloader进程被杀以后, 在 `IFileDownloadIPCService` 出现异常。Closes #38 。
- 修复: 修复 response-body 可能存在的泄漏: 'WARNING: A connection to https://... was leaked. Did you forget to close a response body?' Closes #68 。
- 修复: 使用 `internal-string` 作为同步的对象,而非直接用 String对象。
- 修复: 在一些情况下如果存在重复任务,在高并发下进行中的回调次数可能不对的bug。

#### 其他

- 所依赖的okhttp从`3.1.2`升到`3.2.0`。

## Version 0.2.0

_2016-02-15_

#### 新接口

- `filedownloader.properties-http.lenient`: 添加`http.lenient`用于配置下载引擎中是否需要忽略一些http规范性的错误(如: 忽略 `can't know the size of the download file, and its Transfer-Encoding is not Chunked`), 默认值`false`。
- `FileDownloadNotificationHelper`: 用于支持在通知栏中的通知对下载引擎中任务下载状态同步的快速集成。
- `FileDownloader#init(Application,OkHttpClientCustomMaker)`: 用于为下载引擎提供定制的OkHttpClient。

#### 修复

- 修复: 需要重新启动的列表(`FileDownloadTask.NEED_RESTART_LIST`)不为空并且下载服务断开时出现`Concurrent Modification Exception`的异常。
- 修复: 下载引擎连接丢失以后,重连任务的回调失效的bug。
- 修复: 在一些高并发下载情况下,对队列进行暂停,部分暂停不生效的bug。

## Version 0.1.9

_2016-01-23_

> 引擎默认会打开 避免掉帧的处理(使得一次回调(FileDownloadListener)不至于太频繁导致手机显示掉帧), 如果你希望关闭这个功能(关闭以后,所有回调会与之前版本一样,所有的回调会立马抛一个消息ui线程(Handler)): `FileDownloader.getImpl().disableAvoidDropFrame()`.

#### 新接口


- `FileDownloadMonitor`: 现在你可以通过这个来添加一个全局的监听器,方便调试或打点
- `FileDownloader#enableAvoidDropFrame(void)`: 开启 避免掉帧, 原理最多10ms抛一个消息到ui线程,每次在ui线程每次处理5个回调(FileDownloadListener), 默认: 开启。
- `FileDownloader#disableAvoidDropFrame(void)`: 关闭 避免掉帧,会和之前的版本一样,每个回调(FileDownloadListener)都抛一个消息到ui线程,如果频率非常高(如高并发的文件检测)可以导致ui线程被DDOS。
- `FileDownloader#isEnabledAvoidDropFrame(void)`: 是否是 开启了避免掉帧,目前如果没有设置默认是开启的。
- `FileDownloader#setGlobalPost2UIInterval(intervalMillisecond:int)`: 设置最多intervalMillisecond毫秒抛一个消息到ui线程,是 避免掉帧的具体设置。默认: 10ms,如果设置为小于0的数值,会 关闭 避免掉帧。
- `FileDownloader#setGlobalHandleSubPackageSize(packageSize:int)`: 设置每次在ui线程每次处理packageSize个回调,如果已经关闭了 避免掉帧,那么这个值将没有任何意义,默认: 5个。
- `BaseDownloadTask#setSyncCallback(syncCallback:boolean)`: 是否同步回调该task中的所有的回调(FileDownloadListener), 如果设为true, 该task的所有回调会直接在下载线程直接回调,不会抛到ui线程, 默认: false。
- `BaseDownloadTask#isSyncCallback(void):boolean`: 该task是否设置了所有回调(FileDownloadListener)同步调用(直接在下载线程直接调用,而非抛到ui线程)。
- `FileDownloadUtils#setDefaultSaveRootPath`: 设置全局默认的存储路径(Root Path),在task没有指定对应的存储路径的时候,会存储在该目录下。
- `FileDownloadQueueSet`: 用于更方便的指定几个task为一个队列,进行并行/串行下载,并且可以很方便的对整个队列中的所有任务进行统一设置。

#### 性能与提高

- 提高可调试性: 提供了一个全局监听器(`FileDownloadMonitor`),更方便与调试或打点。
- 提高性能: 优化内部EventPool的锁机制,不再处理listener的priority。
- 提高性能: 所有`FileDownloadListener`中的回调将会直接调用,而不再过一层EventPool。

#### 修复

- 修复: `EventPool`中的listener存储器无限制的bug.

## Version 0.1.5

_2016-01-17_

#### 新接口

- `BaseDownloadTask#setTag(key:int, tag:Object)`: 用于存储任意的变量方便回调中使用,以key作为索引。
- `BaseDownloadTask#getTag(key:int)`: 根据key获取存储在task中的变量。
- `BaseDownloadTask#addHeader(name:String, value:String)`: 添加自定义的请求头参数,需要注意的是内部为了断点续传,在判断断点续传有效时会自动添加上(`If-Match`与`Range`参数),请勿重复添加导致400或其他错误。
- `BaseDownloadTask#addHeader(line:String)`: 添加自定义的请求头参数,需要注意的是内部为了断点续传,在判断断点续传有效时会自动添加上(`If-Match`与`Range`参数),请勿重复添加导致400或其他错误。
- `BaseDownloadTask#removeAllHeaders(name:String)`: 删除由自定义添加上去请求参数为`{name}`的所有键对。

#### 性能与提高

- 提高性能: 在未打开Log的情况下,屏蔽了所有Log生成的代码。
- 提高可调试性: 重新过滤所有的日志级别,减少高级别日志输出,并且默认将会打出`Warn`、`Error`、`Assert`级别的log以便于用户在未打开日志的情况下也可以定位到基本的组件异常。

#### 修复

- 修复: 在一些高并发的情况下,有可能内部队列存在残留任务的bug,此bug可能可能引发回调被旧的任务吞掉的问题。
- 修复: 出现网络错误,或者其他错误,重新下载无法自动断点续传的bug。

#### 其他

- 所依赖的okhttp从`2.7.1`升到`3.0.1`。

## Version 0.1.4

_2016-01-13_

#### 新接口

- `FileDownloader#unBindServiceIfIdle(void)`: 如果目前下载进程没有任务正在执行,则关停下载进程
- `FileDownloader#getStatus(downloadId)`: 获取下载Id为downloadId的状态(可参考[任务管理demo](https://github.com/lingochamp/FileDownloader/blob/master/demo/src/main/java/com/liulishuo/filedownloader/demo/TasksManagerDemoActivity.java))
- `FileDownloader#isServiceConnected(void)`: 是否已经启动并且连接上下载进程(可参考[任务管理demo](https://github.com/lingochamp/FileDownloader/blob/master/demo/src/main/java/com/liulishuo/filedownloader/demo/TasksManagerDemoActivity.java))

#### 性能与提高

- 支持[Chunked transfer encoding](https://en.wikipedia.org/wiki/Chunked_transfer_encoding) 数据下载(建议看一眼[Single Task Test](https://github.com/lingochamp/FileDownloader/blob/master/demo/src/main/java/com/liulishuo/filedownloader/demo/SingleTaskTestActivity.java)).
- 提高性能: 减少 IPC。
- 提高性能: 减少线程锁。
- 提高性能: 在`:filedownloader`进程启动时,对数据库中的数据进行第一级别维护。
- 提高性能: 忽略数据库中的`callbackProgressTimes`字段。

#### 修复

- 修复: 在低内存情况下,ui进程处于后台进程的情况下被回收,而下载进程(服务进程)还在, 并且还存在在下载中的任务,此时重新启动ui进程`FileDownloader#pauseAll`无法暂停已经在下载进程启动的任务的bug。
- 修复: 主动调用`FileDownloader#unBinderService`,没有释放连接相关资源的bug。
- 修复: ui进程被干掉,下载进程健还有活跃的并行任务正在下载,ui进程启动以后启动相同的队列列表,无法收到进度只收到warn的bug。

## Version 0.1.3

_2016-01-04_

- 不再受到1.99G限制;如果是大于1.99G的文件,请使用`FileDownloadLargeFileListener`作为监听器,使用对应的`getLargeFileSoFarBytes()`与`getLargeFileTotalBytes()`接口
- 性能优化: 部分接口跨进程通信不受binder thread 阻塞。
- 依赖okhttp,从`2.7.0`升到`2.7.1`

## Version 0.1.2

_2015-12-27_

- 优化线程消化能力
- 修复大队列任务暂停可能部分无效的问题
- 修复大队列并行下载时一定概率下载已经完成回调囤积延后回调的问题

## Version 0.1.1

_2015-12-25_

- event线程区分敏捷线程池与其他线程池,减少资源冗余强制、内部稳定性以及消化能力与性能,
- 添加自动重试接口,新增用户指定如果失败自动重试的次数

## Version 0.1.0

_2015-12-24_

- FileDownloadStatus 由`int`改为`byte`,该参数会频繁的在IPC时被拷贝
- 优化串行or并行任务时,筛选task在准备数据时就筛选好,减少冗余操作,更加安全
- 优化串行任务执行保证使用更可靠的方式

## Version 0.0.9

_2015-12-23_

- 将调用start(启动任务)抛独立线程处理,其中的线程是通过共享非下载进程EventPool中的线程池(可并行8个线程)

## Version 0.0.8

_2015-12-22_

- initial release

[RemitDatabase-png]: https://github.com/lingochamp/FileDownloader/raw/master/art/remit-database.png
[FileDownloadConnection-java-link]: https://github.com/lingochamp/FileDownloader/blob/master/library/src/main/java/com/liulishuo/filedownloader/connection/FileDownloadConnection.java
[FileDownloadUrlConnection-java-link]: https://github.com/lingochamp/FileDownloader/blob/master/library/src/main/java/com/liulishuo/filedownloader/connection/FileDownloadUrlConnection.java


================================================
FILE: CHANGELOG.md
================================================
# Change log

> [中文迭代日志](https://github.com/lingochamp/FileDownloader/blob/master/CHANGELOG-ZH.md)

## Version 1.7.7

- Fix: FileDownloadThreadPool may throw ArrayIndexOutOfBoundsException & ClassCastException. closes #1258
- Fix: Resume a task may occur 416 problem after upgrading from 1.6.x to 1.7.x.
- Fix: Cannot show notification in demo. closes #1224
- Fix: The callback blockComplete may be invoked in main thread.closes #1069
- Fix: The thread unsafe problem of SparseArray in NoDatabaseImpl. closes #1225 

## Version 1.7.6

_2019-02-20_

#### Fix

- Fix: stop foreground service after all tasks finished in Android O. closes #1096
- Fix: fix 'Context.startForegroundService() did not then call Service.startForeground()' issue. closes #1104
- Fix: insure all foreground service running notification is canceled when pause download. closes #1136
- Fix: fix tiny possibility npe during retry. closes #1100

## Version 1.7.5

_2018-08-03_

#### Fix

- Fix: fix raise "Not allowed to start service Intent..." issue when starting DownloadService on Android O and the application isn't on the foreground and also not on the whitelist, because we can't use `JobScheduler` to handle the download affair. closes #1078

#### Enhance

- Improve Practicability: support character set and the launguage encoding for `Content-Disposition`. closes #1057
- Improve Practicability: cover the error response code 416 from aliyun repo. closes #1050

## Version 1.7.4

_2018-05-19_

#### Fix

- Fix: fix raise 'IllegalStateException' on Android 8+ when FileDownloader try to re-bind service after the connection with the service is lost on downloading state and the app is on the background. closes #1017
- Fix: fix directory traversal vulnerability security issue. closes #1028

## Version 1.7.3

_2018-04-20_

#### Fix

Fix: fix `fd` isn't released manually when download finished which may raise oom when there are a large number of tasks that are continuously initiated.

## Version 1.7.2

_2018-03-14_

#### Fix

- Fix: do not download callback error when the instance length of the task is zero, callback complete directly instead. closes #789
- Fix: fix the temp duplicate data in the database isn't removed when there is another running task with the same temp file path. closes #953
- Fix: the data lost when retry. closes #949
- Fix: fix the instance-length is always 1 when the Content-Range isn't provided but the Content-Length is provided on the trial connection.

#### Enhancement

- Improve Practicability: using the content length value on the Content-Range field when there isn't Content-Length field found in the response header. closes #967

## Version 1.7.1

_2018-02-05_

#### Fix

- Fix: fix download failed with 405 response code when backend can't support `HEAD` method. close #942

## Version 1.7.0

_2018-02-01_

#### Fix

- Fix: fix update status can't keep flow through making updating status synchronized with pause action. close #889
- Fix: fix the sofar-bytes carry back through pending state callback has already discarded. close #884
- Fix: fix can't find filename if filename value on content-disposition without around with ". close #908
- Fix: correct `setCallbackProgressTimes` method make `setCallbackProgressTimes` work correctly. close #901
- Fix: fix download useless data on tcp-window because of the first trial connection use `0-infinite` range. close #933
- Fix: close intput stream when connection ending avoid input-stream leak especially for the trial connection.

#### Enhancement

- Improve Practicability: do not remove the temp-file if rename it to the target path success to prevent raise some file-system problem. close #912
- Improve Practicability: discard range totally if range is right but backend response 416. close #921
- Improve Performance: using HEAD request method instead of GET method for trial connect. ref #933

#### Other

If you are using filedownloader-okhttp3-connection, please upgrade it to the `1.1.0` to adapter FileDownloader 1.7.0.

## Version 1.6.9

_2017-12-16_

#### Fix

- Fix(serial-queue): fix deadlock on `FileDownloadSerialQueue`. closes #858
- Fix: do not use j-unit on library non-unit-test env to fix the `no-static-method-found` issue on some mi-phones. closes #867
- Fix: fix decrease two times of retry-chance each time of retry. closes #838
- Fix: fix get status is pending when a task has been paused on pending status. closes #855

#### Enhancement

- Improve Practicability: public `SqliteDatabaseImpl`、`RemitDatabase`、`NoDatabaseImpl`, so you can overwrite them
- Improve Practicability: support downgrade version from newer version
- Improve Practicability: add the default `User-Agent` if upper layer does not add. closes #848
- Improve Performance: change the keepalive second(5s to 15s) for each executor, since when downloading multiple tasks thread release and recreate too frequently
- Improve Performance: using `RemitDatabase` instead of `DefaultFiledownloadDatabase` to avoid some small task start and finished on the very short time but consume too much time on sync status to database what is useless

![][RemitDatabase-png]

## Version 1.6.8

_2017-10-13_

#### Fix

- Fix: fix resume from breakpoint failed because of `isAlive` not guarantee on Network-thread. this closes #793
- Fix: fix resume from breakpoint failed, because of multi-thread update status very frequently and Messenger can't guarantee order. this refs #793, #764, #721, #769, #763, #761, #716
- Fix: do not crash user when a task has finished but the messenger still has messages, because it's fine for the user. this closes #562
- Fix: fix the callback error of 'it can't take a snapshot for the task xxx' when a user invokes pause very frequently.
- Fix: fix the case of process on the model is wrong which raise 416 each time when restarting it.

## Version 1.6.7

_2017-10-12_

#### Fix

- Fix: Avoid error/pause status is covered by other processing-status which will cause resume-failed, task-never-end. this closes #769, closes #764, closes #761, closes #763, closes #721, closes #716
- Fix: Fix request range value turn to negative when resuming a task which has a process more than 1.99G on its one block. Thanks to @hongbiangoal closes #791

## Version 1.6.6

_2017-09-29_

#### Fix

- Fix(file-integrality): update the process to database only if all buffers on output-stream or system has been flush and sync to device successfully to avoid resume on the wrong point raise complete file not integrality. Closes #745
- Fix(clear): fix `FileDownloader#clearAllTaskData` not clear connection table. Closes #754

#### Enhancement

- Import Performance: optimize the default output-stream with buffered-output-stream, now the VM buffers length is 8192 bytes.

## Version 1.6.5

_2017-09-11_

#### Fix

- Fix: fix `IllegalFormatConversionException` because of format `AtomicLong` with `%d` on `FileDownloadModel.toString`. Closes #743

## Version 1.6.4

_2017-08-21_

#### New Interfaces

- Add `NoDatabaseImpl` for the case of some users need a no-database FileDownloader. Refs #727

#### Enhancement

- Import Performance: Using the `AtomicLong` instead of lock to make better efficiency on increase progressing.

#### Fix

- Fix: Fix response 416 http status because of the last connection range is wrong when resume downloading with the last connection has been downloaded. Closes #737
- Fix(npe): Fix the small probability NPE crash when publish event with it has been removed on other thread. Closes #723

## Version 1.6.3

_2017-07-29_

#### Fix

- Fix: Fix the small probability occur npe when the task is calling back over status with user invoke pause simultaneously. Closes #680
- Fix: Fix `MissingFormatArgumentException` when you pause or resume the FileDownloadserialQueue with it has already done it. Closes #699

## Version 1.6.2

_2017-07-16_

#### Fix

- Fix: Fix raise 'offset < 0' exception when FileDownloader downloading file with the one split connection range begin with larger than 1.99G. Closes #669

## Version 1.6.1

_2017-07-13_

#### Enhancement

- Import Practicability: Throw `GiveUpException` directly when the response `content-length` isn't equal to the expect `content-length` calculated from range. Closes #636

#### Fix

- Fix: Fix sync twice when downloading paused/error.
- Fix: fix file is destroyed when you download chunked file from breakpoint.

## Version 1.6.0

_2017-07-07_

#### Fix

- Fix(no-response): Fix may occur no-respose when multiple connections complete fetch data simultaneously, more detail please move to [here](https://github.com/lingochamp/FileDownloader/issues/631#issuecomment-313451398). Closes #631

## Version 1.5.9

_2017-07-04_

#### Fix

- Fix(duplicate-permission): fix `INSTALL_FAILED_DUPLICATE_PERMISSION` when there are more than one application using FileDownloader lib 1.5.7 or more newer since Android 5.0. This problem is raised since v1.5.7, because of we declared permission for receiving completed status broadcast more secure, now we remove it to fix this problem. Closes #641

## Version 1.5.8

_2017-06-28_

#### Fix

- Fix(no-response): fix no-response when switch between pause and start for the same task very fast frequency. Closes #625

## Version 1.5.7

_2017-06-25_

#### New Interfaces

- Support the configuration `broadcast.completed` in `filedownloader.properties`: determine whether need post a broadcast when task is completed. Closes #605
- Support accepting 201 http status. Closes #545
- Support pause and resume for the `FileDownloadSerialQueue`. Closes #547
- Handle the case of redirect(300、301、302、303、307、308) on FileDownloader self. Closes #611
- Deprecated the `FileDownloader#init` and add the replacer `FileDownloader#setup` to let user invoke anytime before using `Filedownloader`. Closes #500

> - If you want to using `broadcast.completed` and receive completed broadcast, you also need to register receiver with `filedownloader.intent.action.completed` action name on `AndroidManifest.xml` and please using `FileDownloadBroadcastHandler` class to parse the received `Intent`.
> - Now, rather than using `FileDownloader#init`, if you want to register your own customize components for FileDownloader please invoking `FileDownloader.setupOnApplicationOnCreate(application):InitCustomMaker` on the `Application#onCreate`, otherwise you just need invoke `FileDownloader.setup(Context)` anytime before using `FileDownloader`.

#### Fix

- Fix: fix `FileDownloadQueueSet` can't handle the case of disable wifi-required. Thanks @qtstc
- Fix(output-stream): fix broken support for output-stream when it don't support seek. Closes #622

#### Enhancement

- Improve Practicability: Cover the case of reusing the downloaded processing with the different url( using with `idGenerator` ). Closes #617

## Version 1.5.6

_2017-06-18_

#### Fix

- Fix(crash): fix raise NPE crash when require paused a task and invoking `findRunningTaskIdBySameTempPath` at the same time. Closes #613
- Fix(crash): fix raise `IllegalArgumentException` when response code is 206 and its ETAG is changed. Closes #612
- Fix(crash): fix raise `FileDownloadNetworkPolicyException` unhandled exception, when user enable wifi-required but no wifi-state. Thanks @qtstc
- Fix(crash): fix raise `IllegalStateException` when user upgrades from `v1.4.3` or older version to `v1.5.2` or newer version directly and some more conditions, more detail please move to #610
- Fix(crash): fix some small probability case raise `IllegalStateException` when callback-flow has been final but occurring completed/error at the same time.
- Fix(no-response): fix no-response after start download and receive connected callback because the resource state has been changed during the connection of verification and connections of fetch data.

#### Enhancement

- Improve Practicability: callback `error` directly when create the parent directory failed. Closes #542
- Improve Practicability: handle the case of response code is `416`. Closes #612

## Version 1.5.5

_2017-06-12_

#### Fix

- Fix(max-network-thread-count): fix the `download.max-network-thread-count` not work and there are no restrictions on the number of tasks downloaded at the same time since v1.5.0 when tasks runs on the multi-connection Closes #607

## Version 1.5.4

_2017-06-11_

#### New Interfaces

- Support customizing the download task identify generator through `IdGenerator`. Closes #224

#### Enhancement

- Improve Practicability: Decoupling the filedownload-database with filedownload-model, let filedownload-database only care about database operation.
- Improve Practicability: Decoupling the database initial-maintain from the filedownload-database default implementation to let the customized database can be maintained.

## Version 1.5.3

_2017-06-08_

#### Fix

- Fix(crash): Fix divide by zero on calculating average speed when download completed and connected at the same time. Refs #601
- Fix(crash): Fix raise NPE crash when you require pause the task between executed the fetch-data-task and fetch-data-task has not yet started. Closes #601

## Version 1.5.2

_2017-06-07_

#### Fix

- Fix(crash): Fix raising NPE crash or ConcurrentModificationException when the Task is paused or error with the connection is completing at the same time. Closes #598
- Fix(crash): Fix raising NPE crash when pause the `FetchDataTask` and it still without any time to sync data to database or file-system. Refs #598
- Fix(crash): Fix raising NPE crash when using the multiple connections to download and connect failed or create `FetchDataTast` failed. Refs #598
- Fix(speed-calculate): Fix the speed result is `0` when ignore all processing callbacks and just using `FinishListener`.
- Fix(finish-listener): Fix there isn't `over` callback for the `FinishListener` when the file has already been downloaded in the past.

#### Enhancement

- Improve Performance: Enable the WAL for the default sqlite to speed up sql operation because the most of our case is concurrently accessed and modified by multiple threads at the same time.

## Version 1.5.1

_2017-06-05_

#### Fix

- Fix(crash): Fix the NPE crash when don't provided the `InitCustomMaker` on `FileDownloader#init`. Closes #592
- Fix(callback): Fix on the `pending` callback you can't get the right `sofarBytes` when there are several connections served for the task and the task is resuming from the breakpoint.
- Fix(speed-monitor): Correct the result of the total average speed when the task resume from a breakpoint on `IDownloadSpeed.Monitor`.

#### Enhancement

- Improve Robust: Sync all process on fetch task manually when it is paused to make the process can be persist.
- Improve Robust: Raise `IllegalArgumentException` when provide `context` is null on `FileDownloader.init` to expose the problem earlier.

## Version 1.5.0

_2017-06-05_

#### New Interfaces

- Support multiple-connection(multiple threads) for one downloading task.  Closes #102
- Support `ConnectionCountAdapter` to customize connection count for each task(you can set it through `FileDownloader#init`).

#### Enhancement

- Improve Performance: Refactor whole download logic and origin callback logic and remove 1000 line class `FileDownloadRunnable`.

The default connection count strategy for each task, you can customize it through `ConnectionCountAdapter`:

- one connection: file length [0, 1MB)
- two connections: file length [1MB, 5MB)
- three connections: file length [5MB, 50MB)
- four connections: file length [50MB, 100MB)
- five connections: file length [100MB, -]

## Version 1.4.3

_2017-05-07_

#### Fix

- Fix: Remove redundant deprecated method: `FileDownloader#init(Application)`, because `Application` is implement of `Context`.

## Version 1.4.2

_2017-03-15_

#### Fix

- Fix(Same File Path): Avoid two tasks writing to the same file simultaneously, Once there is an another running task with the same target path to the current task's, the current task will receive the `PathConflictException` to refused start downloading. Closes #471

#### New Interfaces

- Add `FileDownloadSerialQueue#getWaitingTaskCount`: Get the count of tasks which is waiting on the serial-queue instance. Refs #345

## Version 1.4.1

_2017-02-03_

#### Fix

- Fix(High concurrency): Fix occurring the NPE crash because of it still receiving message-snapshot in the messenger but the host task has been assigned to null since it has been received over-status message-snapshot. Closes #462
- Fix(`FileDownloadHttpException`): Fix occurring the `IllegalStateException` because of cannot access request header fields after connection is set when occurring http-exception. Closes #458

## Version 1.4.0

_2017-01-11_

#### Enhancement

- Improve Performance: Optimize the logic in `FileDownloader#init`, let it lighter(just do some action like assign `context` and `maker`)

#### Fix

- Fix(pause): fix can't stop the task when occurring the high concurrency event about pausing task after starting it in very close time. Closes #402
- Fix(init FileDownloader): fix the very low frequent crash when init FileDownloader on the process the `FileDownloadService` settled on. Closes #420  
- Fix(FileDownloadHttpException): fix params can't match the `formatter` when occur `FileDownloadHttpException` Closes #438

## Version 1.3.9

_2016-12-18_

### Important:

- Since this version you can customize you own [FileDownloadConnection][FileDownloadConnection-java-link] component, we use [this one][FileDownloadUrlConnection-java-link] as default.
- Since this version, FileDownloader don't dependency the okhttp as default. (If you still want to use the okhttp as your connection component, you can integrate [this repo](https://github.com/Jacksgong/filedownloader-okhttp3-connection) feel free)

> If you still need configure `timeout`、`proxy` for the connection component, but you don't want to implement your own one, don't worry, I implement it for the default connection component too, just move to : [DemoApplication](https://github.com/lingochamp/FileDownloader/blob/master/demo/src/main/java/com/liulishuo/filedownloader/demo/DemoApplication.java#L35), check the code if you want.

#### New Interfaces

- Add `FileDownloadQueueSet#reuseAndStart`: Add reuseAndStart function to the queue-set to reuse task instances before start them. Ref #383
- Add `FileDownloadConnection`: Support customize the connection component for FileDownloader and remove the dependency of the okhttp as default. Closes #158

## Version 1.3.0

_2016-10-31_

#### New Interfaces

- Add `FileDownloadSerialQueue`: Easy to dynamically manage tasks and tasks in the queue will automatically start download one by one. Closes #345.
- Remove the `callback` method in the `FileDownloadListener` class, besides adding the `FileDownloadListener#isInvalid` method to tell the FileDownloader whether the listener has already invalidated, which means it can't receive any messages.
- Add `FileDownloader#clearAllTaskData`: Clear all data in the `filedownloader` database. Closes #361

#### Enhancement

- Improve Practicability(`FileDownloadListener#blackCompleted`): Ensure the `blockCompleted` callback method can accept any `Exception`. Closes #369.
- Improve Practicability(service-not-connected): Print the tips with the cause in service-not-connected-helper, in this way, when you invoke some methods need the FileDownload service has already connected but not yet, FileDownloader will not only print causes in the `Logcat` but also print the tips.

#### Fix

- Fix(reuse): fix `BaseDownloadTask#reuse` is called shortly after the call to `BaseDownloadTask#pause` may raise an exception. Closes #329.

## Version 1.2.2

_2016-10-15_

#### Fix

- Fix(fatal-crash): fix when the task doesn't have `FileDownloadListener`, we can't receive the callback of `FileDownloadMonitor.IMonitor#onTaskOver` for it. Closes #348.

## Version 1.2.1

_2016-10-09_

#### Fix

- <s>Fix(fatal-crash): fix when the task doesn't have `FileDownloadListener`, we can't receive the callback of `FileDownloadMonitor.IMonitor#onTaskOver` for it. Closes #348. </s> Sorry for my mistake, this bug is still exist in 1.2.1 and finally fixed in 1.2.2.

## Version 1.2.0

_2016-10-04_

#### New Interfaces

- Add `FileDownloader#insureServiceBind()`: Easy to block the current thread, and start FileDownloader service, after the service started then executes the request which needs the service alive. Refs #324.
- Add `FileDownloader#insureServiceBindAsync()`: Easy to start FileDownloader service, and after the service started then executes the request which needs the service alive. Refs #324.
- Add `FileDownloader#bindService(runnable:Runnable)`: Easy to start FileDownloader service, and after the service started then executes the `runnable`. Refs #324.
- Add `FileDownloader#init(Context,InitCustomMaker)`: Easy to initialize the FileDownloader engine with various kinds of customized components.

#### Enhancement

- Improve Practicability(`InitCustomMaker#database`): Support customize the database component with the implementation of `FileDownloadDatabase`, and implements the default database component: `DefaultDatabaseImpl`.
- Improve Practicability(`InitCustomMaker#outputStreamCreator`): Support customize the output stream with the implementation of `FileDownloadOutputStream`, and implements the default output stream component `FileDownloadRandomAccessFile`, and some alternative components: `FileDownloadBufferedOutputStream`、`FileDownloadOkio`.

## Version 1.1.5

_2016-09-29_

#### New Interfaces

- Support the configuration `file.non-pre-allocation` in `filedownloader.properties`: Whether doesn't need to pre-allocates the 'content-length' space when to start downloading, default is `false`. Closes #313 .

#### Fix

- Fix(fatal-crash): fix occur the `StackOverflowError` when thread pool getActiveCount is not right because of it just an approximate number. Closes #321 .
- Fix(minor-crash): fix in some minor cases occur `IllegalStateException` which message is 'No reused downloaded file in this message'. Closes #316 .
- Fix(minor-crash): fix when there are several serial-queues started in case of the FileDownloader service doesn't connect yet and in minor cases that the same task in the queue will be started twice which lead to crash. Refs #282 .

#### Others

- Dependency: Cancel the dependence of thread-pool library. Refs #321 .
- MinSDKVersion: Upgrade `minSdkVersion` : 8->9. Refs #321 .

## Version 1.1.0

_2016-09-13_

#### New Interfaces

- Add `BaseDownloadTask#setWifiRequired`: Set whether the task only allows downloading on the wifi network type. Default `false`. Closes #281 .

#### Enhancement

- Improve Performance: Alternate all thread pools to exceed-wait-pool(more detail: docs in `FileDownloadExecutors`) and all threads in pools will be terminate after idle 5 second. Refs #303 .
- Improve Practicability: Handle any `Throwable`s thrown on `FileDownloadListener#blockComplete` method and callback to `FileDownloadListener#error` method instead of `FileDownloadListener#completed`. Closes #305 .

#### Fix

- Fix(lost-connect): Prevent the waiting-connect-list contains duplicate tasks in minor cases.

## Version 1.0.2

_2016-09-06_

#### Fix

- Fix: When the service didn't connected and now it is connected and FileDownloader try to restart the 'queue-task's which in the waiting-service-connect list but occur an `IllegalStateException`. Closes #307 .

## Version 1.0.1

_2016-09-05_

#### New Interfaces

> If you used `BaseDownloadTask#ready()` which is a deprecated method now, just migrate it to `BaseDownloadTask#asInQueueTask():InQueueTask` and `InQueueTask#enqueue()`.

- Add `BaseDownloadTask#asInQueueTask():InQueueTask` and Deprecated `BaseDownloadTask#ready()`: Declare the task is a queue task, what will be assembled by a queue which makes up of the same `listener` task and there is a method `InQueueTask#enqueue()` to enqueue this task to the global queue to ready for being assembled by the queue. The operation of method `InQueueTask#enqueue()` is the same to the Deprecated method `BaseDownloadTask#ready()`, we wrap the `ready()` method in this way just want you to know clearly: Only if the task belongs to a queue, you need to invoke this method otherwise if this task is an isolated task but you invoke this method, it's wrong and you will receive an exception(More detail reason please move to the exception thrown in `DownloadTask#start`).

#### Fix

- Fix: Maybe occur an IllegalStateException when there are several isolated tasks and queues with the same `listener` object, and they are started in the different thread simultaneously. Closes #282 .

## Version 1.0.0

_2016-08-21_

#### New Interfaces

- Add `BaseDownloadTask#cancel`: This method is used for explaining why the pause operation is the same as the cancel operation.

#### Enhancement

- Improve Performance: Hold the result of `isDownloaderProcess`.
- Improve Practicability: Refactor the visible layer of the code. Closes #283
- Improve Practicability: Perfect the java doc. Closes #284
- Improve Practicability: Add the java doc website: http://fd.dreamtobe.cn. Closes #285

## Version 0.3.5

_2016-08-16_

#### Enhancement

- Improve Practicability: Add thread name to all threads used in FileDownloader.
- Improve Performance: Change the count of core thread for block-completed-thread-pool: 5->2, reduce redundant resource waste.

#### Fix

- Fix(SQLiteFullException): Cover the case of SQLiteFullException during the entire downloading process, and ensure the exception can be carried back to `FileDownloadListener#error` . Closes #243
- Fix(directory-case): Fix in the case of the provided path is a directory, and the task already completed, if you start the task again you will receive `FileDownloadListener#completed` directly, but the `targetFilePath` may be null in the `FileDownloadListener#completed` callback method. Closes #237

## Version 0.3.4

_2016-07-31_

#### New Interfaces

- Add `FileDownloader#clear`: clear the data with the task id in the filedownloader database. Closes #218.

#### Enhancement

- Improve Practicability: Add return value to the method `FileDownloader#start(FileDownloadListener, boolean)` : Whether start tasks successfully. Closes #215.
- Improve Practicability: Pause tasks with the same download-id rather than just pause one task through there are more than one task in downloading.

#### Fix

- Fix(init-crash): Fix the crash about the list of running-app-process-info from `ActivityManager` is null when to init FileDownloader. Closes #210.
- Fix(minor-crash): Fix the NPE-crash when to execute receiving snapshot-message after FileDownloadService already onDestroy. Closes #213.
- Fix(message-keep-flow): Delete the target file before start downloading, ensure can't get the `completed` status when another same task is downloading. Closes #220
- Fix(start-serial): Assemble non-attached-tasks to start rather than assemble tasks just refer to FileDownloadListener, fix no possibility to start two queues with the same `FileDownloadListener`. Closes #223.
- Fix(free-messenger): Free the messenger of Task before call back 'over-message' to FileDownloadListener instead of after callback, ensure Task can be reused in FileDownloadListener callback method. Closes #229.

#### Others

- Upgrade dependency okhttp from `3.3.1` to `3.4.1`.


## Version 0.3.3

_2016-07-10_

#### New Interfaces

- Add `FileDownloadUtils#getTempPath`: Get the temp path is used for storing the temporary file not completed downloading yet(`filename.temp`). Refs #172.
- Add `FileDownloader#getStatusIgnoreCompleted(id:int)`:  Get the downloading status without cover the completed status(If completed you will receive `INVALID`).
- Add `FileDownloader#getStatus(id:int, path:String)`:  Get the downloading status.
- Add `FileDownloader#getStatus(url:String, path:String)`:  Get the downloading status.
- Add `FileDownloadUtils#isFilenameConverted(context:Context)`: Whether tasks from FileDownloader Database has converted all files' name from `filename`(in old architecture) to `filename.temp`, if it is not completed downloading yet.
- Add `FileDownloadUtils#generateId(url:String, path:String, pathAsDirectory:boolean)`: Generate a `Download Id` which can be recognized in FileDownloader.
- Add `BaseDownloadTask#setPath(path:String, pathAsDirectory:boolean)`: If `pathAsDirectory` is `true`, the `path` would be the absolute directory to store the downloading file, and the `filename` will be found in `contentDisposition` from the `response#header` as default.
- Add `BaseDownloadTask#isPathAsDirectory`: Whether the result of `BaseDownloadTask#getPath()` is a `directory` path or `directory/filename` path.
- Add `BaseDownloadTask#getTargetFilePath`: Get the target file path to store the downloading file.
- Add `FileDownloadQueueSet#setDirectory`: Set the `directory` to store files in this queue.

#### Enhancement

- Improve Practicability: Support the `path` of the task as the directory to store the file, and in this case, the `filename` will be found in `contentDisposition` from the `response#header` as default. Refs #200.
- Improve Practicability: Using the temp path to store the file not completed downloading yet(`filename.temp`). Refs #172.
- Improve Performance: FileDownloader doesn't store completed tasks in Database anymore, and check whether the task has completed downloading with `File#exists()` directly. Refs #176, #172.
- Improve Robust: Choosing the task which status is `INVALID` or `progress` to receive `completed` message preferentially, to ensure the callback of `progress` can be handled. Refs #123
- Improve Robust: Expanding task-sync-lock to the outside of getting-same-id-downloading-task, to fix some messages can't be consumed because status changed during getting-same-id-downloading-task and waiting for task-sync-lock.

#### Fix

- Fix(DB-maintain): Keeping models, whose status is `pending` and downloaded so far bytes is more than 0 because it can be used for resuming from the breakpoint. Closes #176.
- Fix(crash-NPE): FileDownloader might occur NPE when the download-listener was removed, but the task is still running in FileDownloader. Closes #171.

## Version 0.3.2

_2016-06-12_

#### New Interfaces

- Add `BaseDownloadTask#setCallbackProgressMinInterval`: Set the minimum time interval between each callback of 'progress'. Closes #167.
- Add `FileDownloader#setMaxNetworkThreadCount`: Change the number of simultaneous downloads(the number of the simultaneously running network threads) at the code side. Closes #168.
- Add `FileDownloader#init(Context,OkHttpClientCustomMaker,int)`: Accept initializing the number of simultaneous downloads(the number of the simultaneously running network threads) with the FileDownloadService initializes. Closes #168.

#### Enhancement

- Improve Robust: Ensure the minimum time interval between each callback of 'progress' is 5ms, To prevent internal callback of 'progress' too frequent happening. Closes #167.
- Improve Practicability: Print the 'warn' priority log when a request does something in the FileDownloadService but it isn't connected yet.
- Improve Performance: Using the `SparseArray` instead of `HashMap` for mapping all `FileDownloadModel`.

#### Fix

- Fix(crash): Fix provided wrong params in formatting character string when to starting download runnable occur the unexpected downloading status.
- Fix(force-re-download): Fix the wrong logic: In the case of `BaseDownloadTask#setForceReDownload(true)` and the task has already downloaded will trigger 'warn' callback. Closes #169 .
- Fix(class-type): Keep the class type of `SocketTimeOutException`, and no longer care about whether the message of Throwable is empty, this is very redundant.

#### Others

- Upgrade dependency okhttp from `3.2.0` to `3.3.1`.

## Version 0.3.1

_2016-05-19_

#### Enhancement

- Improve Robust: Ensuring buffer is written out to the device when at the end of fetching data.

## Version 0.3.0

_2016-05-13_

#### Fix

> Why FileDownload can run in UI process? Ref [filedownloader.properties](https://github.com/lingochamp/FileDownloader/wiki/filedownloader.properties).

- Fix(shared-UI-process): fix the addition header does not attach to Http-request when the FileDownload service isn't running in the separate process to UI process. Closes #149.


## Version 0.2.9

_2016-05-10_

#### New Interfaces

- Add `BaseDownloadTask#isUsing():boolean`: Whether this task object has already started and used in FileDownload Engine. Closes #137 .

#### Fix

- Fix(high-concurrency-npe): Providing the default snapshot when a task's status is unexpected, preventing the npe is occurred in this case.
- Fix(response-416): Covering the response status code is 416 or still resume from breakpoint when its so far bytes more than or equal to total bytes.

## Version 0.2.8

_2016-05-02_

#### New Interfaces

- Add `BaseDownloadTask#getId():int`: deprecate `getDownloadId()`, and using the `getId()` instead, for `BaseDownloadTask`.

#### Enhancement

- Improve Robust: Refactor the launcher for launching tasks more make sense, and expire tasks with listener or expire all waiting-tasks more stable.
- Improve Robust: Refactor the architecture which is used to handle the event send to `FileDownloadListener`, the new architecture just like a messenger and message-station, each tasks would write snapshot messages to message-station.
- Improve Robust: Cover all high concurrent situations about pausing a task, remove some expected warn logs about it.
- Improve Performance: Reduce the FileDownloader database I/O.
- Improve Performance: Reduce creating object(less allocating memory request, friendly to GC) for each call-back, Taking a message snapshot for a status updating, and through whole communication architecture just use it.

#### Fix

- Fix: Provide the definite locale for formatting strings, prevent unexpected-locale as Default happening. Closes #127

## Version 0.2.7

_2016-04-22_

#### New Interfaces

- Add `FileDownloader#setTaskCompleted(taskAtomList:List<FileDownloadTaskAtom>)`: Used to telling the FileDownloader Engine that a bulk of tasks have already downloaded by other ways.

#### Enhancement

- Improve Robust: Throw the Fatal-Exception directly when request to bind the FileDownloadService in the `:filedownloader` process. Closes #119 .

## Version 0.2.6

_2016-04-20_

#### New Interfaces

- Adjust: Change the location of the `filedownloader.properties` ,no more in the root directory of project, instead below the `assets` of a module, for example `/demo/src/main/assets/filedownloader.properties`.

#### Fix

- Fix: `filedownloader.properties` not work. Closes #117.

## Version 0.2.5

_2016-04-19_

#### New Interfaces

- Add `FileDownloader#setTaskCompleted`: Used to telling the FileDownloader Engine that the task with the url and the path has already completed downloading by other ways(not by FileDownloader Engine).
- Support the configuration `download.max-network-thread-count` in `filedownloader.properties`: The maximum network thread count for downloading simultaneously, default is 3. Closes #116.

## Version 0.2.4

_2016-04-18_

#### New Interfaces

- Add `BaseDownloadTask#getSpeed` and `BaseDownloadTask#setMinIntervalUpdateSpeed`: Get the download speed for a task. If it is in processing, the speed would be real-time speed; If finished, the speed would be average speed. Closes #95
- Add the `FileDownloader#startForeground` and `FileDownloader#stopForeground` for supporting the Foreground mode([Service#startForeground](https://github.com/lingochamp/FileDownloader/wiki/filedownloader.properties)); For ensure the FileDownloadService would keep alive when user removed the App from the recent apps. Closes #110 .
- Support configurations `download.min-progress-step` and `download.min-progress-time`: The min buffered so far bytes and millisecond, used for adjudging whether is time to sync the download so far bytes to database and make sure sync the downloaded buffers to the local file. More small more frequent, then download more slowly, but will safer in the scene of the process is killed unexpectedly. Default 65536(MinProgressStep) and 2000(MinProgressTime), which follow the value in `com.android.providers.downloads.Constants`.
- Support the configuration `process.non-separate` in `filedownloader.properties`: The FileDownloadService runs in the separate process ':filedownloader' as default, if you want to run the FileDownloadService in the main process, set this configuration as `true`. Closes #106 .

#### Enhancement

- Improve Performance: Download more quickly, Optimize the strategy about sync the buffered datum to database and local file when processing. Closes #112 .

#### Fix

- Fix: Can't restart the task which in paused but is still settling in the download-pool. Closes #111

## Version 0.2.3

_2016-04-11_

#### New Interfaces

- Add `FileDownloadOutOfSpaceException`, Throw this exception, when the file will be downloaded is too large to store.
- Add new call-back method in `FileDownloadListener`: `started` which will be invoked when finish pending, and start the download runnable.
- Add new call-back method in `FileDownloadMonitor.IMonitor`: `onTaskStarted` which will be invoked when finish pending, and start the download runnable.

#### Enhancement

- Improve Practicability: Provide the current task to the method `over` in `FinishListener`, for recognizing target task in case of one-FinishListener for more than one task. Closes #69 .
- Improve Robust: Throw the exception directly when invoke `BaseDownloadTask#start` for a running-task object, add provide 'reuse' method to reuse a used and already finished task object. Closes #91 .
- Improve Performance: Intercept the enqueue operate for the otiose event which is no listener for handling it.

#### Fix

- Fix: In handful cases the task-call-back flow not follow the expect.
- Fix: `progress` call-back included the ending frame ( `sofarBytes == totalBytes` ).
- Fix: Carry back the total bytes in the status of warn, for covering the case of UI-process had killed but has restarted App with restarting the task and download-process is alive still, the total bytes is 0 in UI-process. Closes #90 .
- Fix: Can't call-back 'retry' in expect, the case of the call-back method 'retry' one-by-one. Refs: #91 .
- Fix: The wrong sofar bytes will cover the right one, when occur error in no-network and has chance to retry. Closes #92 .
- Fix: Handle the case of the downloading is finished during the 'check-reuse' to 'check-downloading' in filedownloader-process.
- Fix: The serial-queue converts to The parallel-queue in restoring from filedownloader-process has killed and restarting.

## Version 0.2.2

_2016-04-06_

#### New Interfaces

- Add `FileDownloadHttpException` and `FileDownloadGiveUpRetryException`, and optimize the mechanism of exception. Closes #67 .
- Init the `FileDownloader` use `Context` instead of `Application` ( `FileDownloader#init(Context)` ) , for more make sense and unit-test. Closes #54 .

#### Enhancement

- Improve Robust: Check whether free space is enough, and throw IOException directly when not enough; And pre-allocate need-available-space before fetching datum when the free space more than need-available-space. Closes #46 .
- Improve Practicability: Support resume from breakpoint without ETag. Just need the server support the request-header param 'Range'. Close #35 , #66 .


#### Fix

- Fix: The `IllegalFormatConversionException` on `EventPool` when publishing the event which does not in effect and `FileDownloadLog.NEED_LOG` is `true`. Closes #30 .
- Fix: The non-fatal-crash in `IFileDownloadIPCService.java` , when lost connection from filedownloader process. because the IBinder's hosting process(filedownloader process) has been killed/cancelled. Closes #38 .
- Fix: The leak of response-body: 'WARNING: A connection to https://... was leaked. Did you forget to close a response body?' Closes #68 .
- Fix: Using the internal-string as synchronized lock-object instead of string-original.
- Fix: The number of the Ing-call-back is not correct in some cases.

#### Others

- Upgrade dependency okhttp from `3.1.2` to `3.2.0`.

## Version 0.2.0

_2016-02-15_

#### New Interfaces

- `filedownloader.properties-http.lenient`: Add 'filedownloader.properties' for some special global configs, and add 'http.lenient' keyword to 'filedownloader.properties' to handle the case of want to ignore HTTP response header from download file server isn't legal.
- `FileDownloadNotificationHelper`: Refashioning NotificationHelper, let handle notifications with FileDownloader more make sense. #25
- `FileDownloader#init(Application,OkHttpClientCustomMaker)`: Support customize OkHttpClient which will be used for downloading files.

#### Fix

- Fix: Occur 'Concurrent Modification Exception' when Downloader service is unbound or lost connection to service and NeedRestart list not empty. #23
- Fix: The case of re-connect from lost connection to service but all auto restart tasks' call-back do not effect.
- Fix: In some cases of high concurrency, the Pause on some tasks is no effect.

## Version 0.1.9

_2016-01-23_

> FileDownloader is enable Avoid Missing Screen Frames as default, if you want to disable it, please invoke `FileDownloader.getImpl().disableAvoidDropFrame()`.

#### New Interfaces

> We default open Avoid Missing Screen Frames, if you want to disable it(will post to ui thread for each FileDownloadListener event achieved as pre version), please invoke: `FileDownloader.getImpl().disableAvoidDropFrame()`.

- `FileDownloadMonitor`: You can add the global monitor for Statistic/Debugging now.
- `FileDownloader#enableAvoidDropFrame(void)`: Avoid missing screen frames, but this leads to all callbacks of FileDownloadListener do not be invoked at once when it has already achieved.
- `FileDownloader#disableAvoidDropFrame(void)`: Disable avoid missing screen frames, let all callbacks of FileDownloadListener be invoked at once when it achieve.
- `FileDownloader#isEnabledAvoidDropFrame(void)`: Has already enabled Avoid Missing Screen Frames. Default: true
- `FileDownloader#setGlobalPost2UIInterval(intervalMillisecond:int)`: For Avoid Missing Screen Frames. Each intervalMillisecond post 1 message to ui thread at most. if the value is less than 0, each callback will always post a message to ui thread immediately, may will cause missing screen frames and produce great pressure on the ui thread Looper. Default: 10ms.
- `FileDownloader#setGlobalHandleSubPackageSize(packageSize:int)`: For Avoid Missing Screen Frames. {packageSize}: The number of FileDownloadListener's callback contained in each message. value completely dependent on the intervalMillisecond of setGlobalPost2UIInterval, describe will handle up to {packageSize} callbacks on the each message posted to ui thread. Default: 5.
- `BaseDownloadTask#setSyncCallback(syncCallback:boolean)`: if true will invoke callbacks of FileDownloadListener directly on the download thread(do not post the message to the ui thread), default false.
- `BaseDownloadTask#isSyncCallback(void):boolean`: Whether sync invoke callbacks of FileDownloadListener directly on the download thread.
- `FileDownloadUtils#setDefaultSaveRootPath`: The path is used as Root Path in the case of task without setting path in the entire Download Engine.
- `FileDownloadQueueSet`: In order to be more convenient to bind multiple tasks to a queue, and to the overall set.

#### Enhancement

- Improve Debugging: Provide the `FileDownloadMonitor` to monitor entire Download Engine.
- Improve Performance: Optimize EventPool lock & do not handle listener priority any more(no use internal).
- Improve Performance: Call `FileDownloadListener` methods do not through EventPool, instead, invoke directly.

#### Fix

- Fix: EventPool listener unlimited increased bug.

## Version 0.1.5

_2016-01-17_

#### New Interfaces

- `BaseDownloadTask#setTag(key:int, tag:Object)`: Set a tag associated with this task. If the key already existed, the old tag will be replaced.
- `BaseDownloadTask#getTag(key:int)`: Get the object stored in the task as a tag, or null if not set.
- `BaseDownloadTask#addHeader(name:String, values:String)`: Add custom request header to the task. Attention: We have already handled ETag, and will add `If-Match` & `Range` value if it works.
- `BaseDownloadTask#addHeader(line:String)`: Add custom request header to the task. Attention: We have already handled ETag, and will add `If-Match` & `Range` value if it works.
- `BaseDownloadTask#removeAllHeaders(name:String)`: Remove all custom request header bind with the `{name}`.

#### Enhancement

- Improve Performance: Reduce the consumption of the generated log.
- Improve Debugging: To filter all the log level, reduce the high level of log output, and by default, will output `Warn`、`Error`、`Assert` level of log in order to debugging in the case of the value of `FileDownloadLog.NEED_LOG` is false(default).

#### Fix

- Fix can't resume from the break point naturally in case of the download status of the task is Error.
- Fix the size of the queue may not match the number of actual active tasks in case of high concurrency. This bug may would caused some callbacks to be consumed by the old tasks.

#### Others

- Upgrade dependency okhttp from `2.7.1` to `3.0.1`.

## Version 0.1.4

_2016-01-13_

#### New Interfaces

- `FileDownloader#unBindServiceIfIdle(void)`: If there is no active task in the `:filedownloader` progress currently , then unbind & stop `:filedownloader` process
- `FileDownloader#getStatus(downloadId)`: Get download status by the downloadId(ps: Please refer to [Tasks Manager demo](https://github.com/lingochamp/FileDownloader/blob/master/demo/src/main/java/com/liulishuo/filedownloader/demo/TasksManagerDemoActivity.java)
- `FileDownloader#isServiceConnected(void)`: Whether started and connected to the `:filedownloader` progress(ps: Please refer to [Tasks Manager demo](https://github.com/lingochamp/FileDownloader/blob/master/demo/src/main/java/com/liulishuo/filedownloader/demo/TasksManagerDemoActivity.java))

#### Enhancement

- Supported [Chunked transfer encoding](https://en.wikipedia.org/wiki/Chunked_transfer_encoding) data download(Recommend to glance at demo on [Single Task Test](https://github.com/lingochamp/FileDownloader/blob/master/demo/src/main/java/com/liulishuo/filedownloader/demo/SingleTaskTestActivity.java)).
- Improve Performance: Reduce IPC.
- Improve Performance: Reduce lock.
- Improve Performance: Delete invalid datum in db with the `:filedownloader` progress start.
- Improve Performance: Ignore the `callbackProgressTimes` column in db.

#### Fix

- Fix `FileDownloader#pauseAll` not effect in case of low memory and ui progress is Background Progress situation and the `:filedownloader` progress(Service Progress) alive and still have running tasks in the `filedownloader` progress but ui progress has died and relived.
- Fix not release connect resources when invoke `FileDownloader#unBinderService` manually.
- Handle case of ui progress be killed by sys and download progress not be killed, and ui progress relives and re-executes same tasks queue.


## Version 0.1.3

_2016-01-04_

- Enhancement: no longer subject to the upper bound of 1.99G, add `FileDownloadLargeFileListener`, `getLargeFileSoFarBytes()`,`getLargeFileTotalBytes()`.
- Performance optimization: some ipc transaction just need one-way call(async), not block(sync).
- Upgrade dependency okhttp from `2.7.0` to `2.7.1`.

## Version 0.1.2

_2015-12-27_

- Optimize thread digestion([map](https://github.com/lingochamp/FileDownloader/raw/master/art/filedownload_sample_description.png).
- Fix: may `pause()` invalid in large queue task.
- Fix: large queue task parallel download, may download has been completed but the callback

## Version 0.1.1

_2015-12-25_

- Optimization of internal performance, according to the time split thread pool.
- Add auto retry feature.

## Version 0.1.0

_2015-12-24_

- The `FileDownloadStatus` parameter type is changed from `int` to `byte`, which is frequently copied in IPC.
- Optimization of multi task queue filtering time.
- Optimizing serial task execution mechanism.

## Version 0.0.9

_2015-12-23_

- The start operation into independent thread processing, sharing thread pool in EventPool.

## Version 0.0.8

_2015-12-22_

- initial release

[RemitDatabase-png]: https://github.com/lingochamp/FileDownloader/raw/master/art/remit-database.png
[FileDownloadConnection-java-link]: https://github.com/lingochamp/FileDownloader/blob/master/library/src/main/java/com/liulishuo/filedownloader/connection/FileDownloadConnection.java
[FileDownloadUrlConnection-java-link]: https://github.com/lingochamp/FileDownloader/blob/master/library/src/main/java/com/liulishuo/filedownloader/connection/FileDownloadUrlConnection.java


================================================
FILE: LICENSE.txt
================================================

                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

 Copyright (c) 2015 LingoChamp Inc.

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.


================================================
FILE: README-zh.md
================================================
# FileDownloader
Android 文件下载引擎,稳定、高效、灵活、简单易用

[![Gitter][gitter_svg]][gitter_url]
[![Download][bintray_svg]][bintray_url]
![][file_downloader_svg]
[![Build Status][build_status_svg]][build_status_link]
[![][filedownloader_snapshot_svg]](https://oss.sonatype.org/content/repositories/snapshots/com/liulishuo/filedownloader/)


> [README DOC](https://github.com/lingochamp/FileDownloader/blob/master/README.md)

---

#### 版本迭代日志: [Change Log](https://github.com/lingochamp/FileDownloader/blob/master/CHANGELOG.md)

#### 英文文档: [Wiki](https://github.com/lingochamp/FileDownloader/wiki)、[优化建议](https://github.com/lingochamp/FileDownloader/wiki/Optimize-Tutorial)

---

### FileDownloader2 

现在, [FileDownloader2-OkDownload](https://github.com/lingochamp/okdownload) 已经正式发布, okdownload继承了所有FileDownloader的优点,甚至做了更多的优化以及更多的特性。

由于FileDownloader的单元测试覆盖太低,因此所有的进一步的需求以及提高都将会在okdownload上进行实现而非FileDownloader,而FileDownloader本身将只会关注于修复Bug。

---

### 特点

- 简单易用
- 单任务多线程/多连接/分块下载(并支持通过`ConnectionCountAdapter`定制)
- 高并发
- 灵活
- 可选择性支持: 独立/非独立进程
- 自动断点续传

#### 需要注意

- 当下载的文件大小可能大于1.99GB(2^31-1`=2_147_483_647 = 1.99GB`)的时候, 请使用`FileDownloadLargeFileListener`而不是`FileDownloadListener`(同理使用`getLargeFileSofarBytes()`与`getLargeFileTotalBytes()`)
- 暂停: paused, 恢复: 直接调用start,默认就是断点续传
- 引擎默认会打开避免掉帧的处理(使得在有些情况下回调(FileDownloadListener)不至于太频繁导致ui线程被ddos), 如果你希望关闭这个功能(关闭以后,所有回调会与0.1.9之前的版本一样,所有的回调会立马抛一个消息ui线程(Handler))
- 如果没有特殊需要,直接通过配置`filedownloader.properties`将`process.non-separate`置为`true`,可以有效减少每次回调IPC带来的I/O。

---

## Android 系统适配

### 适配 Android 8.0

从 Android 8.0 开发,后台服务的限制增强了,可以参考[这里](https://developer.android.com/about/versions/oreo/background)了解更多信息。
因此,自 FileDownloader 1.7.6 版本开始, Android 8.0 及之后的系统上,如果在后台启动下载服务,这个服务将会是一个前台服务,同时你会看到一个标题为 "FileDownloader" 的通知。
你可以参考[这里](https://github.com/lingochamp/FileDownloader/wiki/Compatibility-of-Android-O-Servic)去自定义通知的内容。

### 适配 Android 9.0

从 Android 9.0 (API level 28) 开始,明文请求默认被禁止,你可以在[这里](https://stackoverflow.com/questions/45940861/android-8-cleartext-http-traffic-not-permitted)了解详细信息。
FileDownloader 1.7.6 已经在 demo 中处理了此问题。

根据[迁移笔记](https://developer.android.com/about/versions/pie/android-9.0-migration#tya),`FOREGROUND_SERVICE` 这个权限已经在 1.7.6 版本添加到 library 的 manifest 里面了。

---

## 欢迎提交 Pull requests

- 尽量多的英文注解。
- 每个提交尽量的细而精准。
- Commit message 遵循: [AngularJS's commit message convention](https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md#-git-commit-guidelines)。

---

## I. 效果

![][single_demo_gif]
![][chunked_demo_gif]
![][serial_tasks_demo_gif]
![][parallel_tasks_demo_gif]
![][tasks_manager_demo_gif]
![][mix_tasks_demo_gif]
![][avoid_drop_frames_1_gif]
![][avoid_drop_frames_2_gif]


## II. 使用

在项目中引用:

```groovy
implementation 'com.liulishuo.filedownloader:library:1.7.7'
```

> 如果是eclipse引入jar包参考: [这里](https://github.com/lingochamp/FileDownloader/issues/212#issuecomment-232240415)

如果需要引入snapshot版本,请添加sonatype的仓库:

```groovy
repositories {
    maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
}
```

#### 全局初始化

如果你需要注册你的定制组件,你需要在`Application#onCreate`中调用`FileDownloader.setupOnApplicationOnCreate(application):InitCustomMaker`, 否则你只需要在使用FileDownloader之前的任意时候调用`FileDownloader.setup(Context)`即可。

这些初始化方法都十分的简单,不会启动下载服务,一般都是在10ms内完成。

#### 启动单任务下载

```java
FileDownloader.getImpl().create(url)
        .setPath(path)
        .setListener(new FileDownloadListener() {
            @Override
            protected void pending(BaseDownloadTask task, int soFarBytes, int totalBytes) {
            }

            @Override
            protected void connected(BaseDownloadTask task, String etag, boolean isContinue, int soFarBytes, int totalBytes) {
            }

            @Override
            protected void progress(BaseDownloadTask task, int soFarBytes, int totalBytes) {
            }

            @Override
            protected void blockComplete(BaseDownloadTask task) {
            }

            @Override
            protected void retry(final BaseDownloadTask task, final Throwable ex, final int retryingTimes, final int soFarBytes) {
            }

            @Override
            protected void completed(BaseDownloadTask task) {
            }

            @Override
            protected void paused(BaseDownloadTask task, int soFarBytes, int totalBytes) {
            }

            @Override
            protected void error(BaseDownloadTask task, Throwable e) {
            }

            @Override
            protected void warn(BaseDownloadTask task) {
            }
        }).start();
```

#### 启动多任务下载

```java
final FileDownloadListener queueTarget = new FileDownloadListener() {
    @Override
    protected void pending(BaseDownloadTask task, int soFarBytes, int totalBytes) {
    }

    @Override
    protected void connected(BaseDownloadTask task, String etag, boolean isContinue, int soFarBytes, int totalBytes) {
    }

    @Override
    protected void progress(BaseDownloadTask task, int soFarBytes, int totalBytes) {
    }

    @Override
    protected void blockComplete(BaseDownloadTask task) {
    }

    @Override
    protected void retry(final BaseDownloadTask task, final Throwable ex, final int retryingTimes, final int soFarBytes) {
    }

    @Override
    protected void completed(BaseDownloadTask task) {
    }

    @Override
    protected void paused(BaseDownloadTask task, int soFarBytes, int totalBytes) {
    }

    @Override
    protected void error(BaseDownloadTask task, Throwable e) {
    }

    @Override
    protected void warn(BaseDownloadTask task) {
    }
};

// 第一种方式 :

//for (String url : URLS) {
//    FileDownloader.getImpl().create(url)
//            .setCallbackProgressTimes(0) // 由于是队列任务, 这里是我们假设了现在不需要每个任务都回调`FileDownloadListener#progress`, 我们只关系每个任务是否完成, 所以这里这样设置可以很有效的减少ipc.
//            .setListener(queueTarget)
//            .asInQueueTask()
//            .enqueue();
//}

//if(serial){
    // 串行执行该队列
//    FileDownloader.getImpl().start(queueTarget, true);
// }

// if(parallel){
    // 并行执行该队列
//    FileDownloader.getImpl().start(queueTarget, false);
//}

// 第二种方式:

final FileDownloadQueueSet queueSet = new FileDownloadQueueSet(downloadListener);

final List<BaseDownloadTask> tasks = new ArrayList<>();
for (int i = 0; i < count; i++) {
     tasks.add(FileDownloader.getImpl().create(Constant.URLS[i]).setTag(i + 1));
}

queueSet.disableCallbackProgressTimes(); // 由于是队列任务, 这里是我们假设了现在不需要每个任务都回调`FileDownloadListener#progress`, 我们只关系每个任务是否完成, 所以这里这样设置可以很有效的减少ipc.

// 所有任务在下载失败的时候都自动重试一次
queueSet.setAutoRetryTimes(1);

if (serial) {
  // 串行执行该任务队列
     queueSet.downloadSequentially(tasks);
     // 如果你的任务不是一个List,可以考虑使用下面的方式,可读性更强
//      queueSet.downloadSequentially(
//              FileDownloader.getImpl().create(url).setPath(...),
//              FileDownloader.getImpl().create(url).addHeader(...,...),
//              FileDownloader.getImpl().create(url).setPath(...)
//      );
}

if (parallel) {
  // 并行执行该任务队列
   queueSet.downloadTogether(tasks);
   // 如果你的任务不是一个List,可以考虑使用下面的方式,可读性更强
//    queueSet.downloadTogether(
//            FileDownloader.getImpl().create(url).setPath(...),
//            FileDownloader.getImpl().create(url).setPath(...),
//            FileDownloader.getImpl().create(url).setSyncCallback(true)
//    );
}

// 最后你需要主动调用start方法来启动该Queue
queueSet.start()

// 串行任务动态管理也可以使用FileDownloadSerialQueue。
```

#### 全局接口说明(`FileDownloader`)

> 所有的暂停,就是停止,会释放所有资源并且停到所有相关线程,下次启动的时候默认会断点续传

| 方法名 | 备注
| --- | ---
| setup(Context) | 如果不需要注册定制组件,就使用该方法在使用下载引擎前调用,该方法只会缓存Context
| setupOnApplicationOnCreate(application):InitCustomMaker | 如果需要注册定制组件,就在Application#onCreate中调用该方法来注册定制组件以及初始化下载引擎,该方法不会启动下载服务
| create(url:String) | 创建一个下载任务
| start(listener:FileDownloadListener, isSerial:boolean) | 启动是相同监听器的任务,串行/并行启动
| pause(listener:FileDownloadListener) | 暂停启动相同监听器的任务
| pauseAll(void) | 暂停所有任务
| pause(downloadId) | 暂停downloadId的任务
| clear(downloadId, targetFilePath) | 强制清理ID为downloadId的任务在filedownloader中的数据
| getSoFar(downloadId) | 获得下载Id为downloadId的soFarBytes
| getTotal(downloadId) | 获得下载Id为downloadId的totalBytes
| bindService(void) | 主动启动下载进程(可事先调用该方法(可以不调用),保证第一次下载的时候没有启动进程的速度消耗)
| unBindService(void) | 主动关停下载进程
| unBindServiceIfIdle(void) | 如果目前下载进程没有任务正在执行,则关停下载进程
| isServiceConnected(void) | 是否已经启动并且连接上下载进程(可参考任务管理demo中的使用)
| getStatusIgnoreCompleted(downloadId) | 获取不包含已完成状态的下载状态(如果任务已经下载完成,将收到`INVALID`)
| getStatus(id:int, path:String) | 获取下载状态
| getStatus(url:String, path:String) | 获取下载状态
| setGlobalPost2UIInterval(intervalMillisecond:int) | 为了避免掉帧,这里是设置了最多每interval毫秒抛一个消息到ui线程(使用Handler),防止由于回调的过于频繁导致ui线程被ddos导致掉帧。 默认值: 10ms. 如果设置小于0,将会失效,也就是说每个回调都直接抛一个消息到ui线程
| setGlobalHandleSubPackageSize(packageSize:int) | 为了避免掉帧, 如果上面的方法设置的间隔是一个小于0的数,这个packageSize将不会生效。packageSize这个值是为了避免在ui线程中一次处理过多回调,结合上面的间隔,就是每个interval毫秒间隔抛一个消息到ui线程,而每个消息在ui线程中处理packageSize个回调。默认值: 5
| enableAvoidDropFrame(void) | 开启 避免掉帧处理。就是将抛消息到ui线程的间隔设为默认值10ms, 很明显会影响的是回调不会立马通知到监听器(FileDownloadListener)中,默认值是: 最多10ms处理5个回调到监听器中
| disableAvoidDropFrame(void) | 关闭 避免掉帧处理。就是将抛消息到ui线程的间隔设置-1(无效值),这个就是让每个回调都会抛一个消息ui线程中,可能引起掉帧
| isEnabledAvoidDropFrame(void) | 是否开启了 避免掉帧处理。默认是开启的
| startForeground(id:int, notification:Notification) | 设置FileDownloadService为前台模式,保证用户从最近应用列表移除应用以后下载服务不会被杀
| stopForeground(removeNotification:boolean) | 取消FileDownloadService的前台模式
| setTaskCompleted(url:String, path:String, totalBytes:long) | 用于告诉FileDownloader引擎,以指定Url与Path的任务已经通过其他方式(非FileDownloader)下载完成
| setTaskCompleted(taskAtomList:List<FileDownloadTaskAtom>) | 用于告诉FileDownloader引擎,指定的一系列的任务都已经通过其他方式(非FileDownloader)下载完成
| setMaxNetworkThreadCount(int) | 设置最大并行下载的数目(网络下载线程数), [1,12]
| clearAllTaskData() | 清空`filedownloader`数据库中的所有数据

#### 定制化组件接口说明(`InitCustomMaker`)

| 方法名 | 需实现接口 | 已有组件 | 默认组件 | 说明
| --- | --- | --- | --- | ---
| database | FileDownloadDatabase | RemitDatabase、SqliteDatabaseImpl、NoDatabaseImpl | RemitDatabase | 传入定制化数据库组件,用于存储用于断点续传的数据
| connection | FileDownloadConnection | FileDownloadUrlConnection | FileDownloadUrlConnection | 传入定制化的网络连接组件,用于下载时建立网络连接
| outputStreamCreator | FileDownloadOutputStream | FileDownloadRandomAccessFile | FileDownloadRandomAccessFile | 传入输出流组件,用于下载时写文件使用
| maxNetworkThreadCount | - | - | 3 | 传入创建下载引擎时,指定可用的下载线程个数
| ConnectionCountAdapter | ConnectionCountAdapter | DefaultConnectionCountAdapter | DefaultConnectionCountAdapter | 根据任务指定其线程数
| IdGenerator | IdGenerator | DefaultIdGenerator | DefaultIdGenerator | 自定义任务Id生成器

> - 如果你希望Okhttp作为你的网络连接组件,可以使用[这个库](https://github.com/Jacksgong/filedownloader-okhttp3-connection)。
> - 如果你不希望FileDownloader用到任何的数据库(是用于存储任务的断点续成信息的),只需要使用[NoDatabaseImpl.java](https://github.com/lingochamp/FileDownloader/blob/master/library/src/main/java/com/liulishuo/filedownloader/services/NoDatabaseImpl.java)即可。

#### Task接口说明

| 方法名 | 备注
| --- | ---
| setPath(path:String) | 下载文件的存储绝对路径
| setPath(path:String, pathAsDirectory:boolean) | 如果`pathAsDirectory`是`true`,`path`就是存储下载文件的文件目录(而不是路径),此时默认情况下文件名`filename`将会默认从`response#header`中的`contentDisposition`中获得
| setListener(listener:FileDownloadListener) | 设置监听,可以以相同监听组成队列
| setCallbackProgressTimes(times:int) | 设置整个下载过程中`FileDownloadListener#progress`最大回调次数
| setCallbackProgressIgnored() | 忽略所有的`FileDownloadListener#progress`的回调
| setCallbackProgressMinInterval(minIntervalMillis:int) | 设置每个`FileDownloadListener#progress`之间回调间隔(ms)
| setTag(tag:Object) | 内部不会使用,在回调的时候用户自己使用
| setTag(key:int, tag:Object) | 用于存储任意的变量方便回调中使用,以key作为索引
| setForceReDownload(isForceReDownload:boolean) | 强制重新下载,将会忽略检测文件是否健在
| setFinishListener(listener:FinishListener) | 结束监听,仅包含结束(over(void))的监听
| setAutoRetryTimes(autoRetryTimes:int) | 当请求或下载或写文件过程中存在错误时,自动重试次数,默认为0次
| setSyncCallback(syncCallback:boolean)  | 如果设为true, 所有FileDownloadListener中的回调都会直接在下载线程中回调而不抛到ui线程, 默认为false
| addHeader(name:String, value:String) | 添加自定义的请求头参数,需要注意的是内部为了断点续传,在判断断点续传有效时会自动添加上(`If-Match`与`Range`参数),请勿重复添加导致400或其他错误
| addHeader(line:String) | 添加自定义的请求头参数,需要注意的是内部为了断点续传,在判断断点续传有效时会自动添加上(`If-Match`与`Range`参数),请勿重复添加导致400或其他错误
| setMinIntervalUpdateSpeed(minIntervalUpdateSpeedMs:int) | 设置下载中刷新下载速度的最小间隔
| removeAllHeaders(name:String) | 删除由自定义添加上去请求参数为`{name}`的所有键对
| setWifiRequired(isWifiRequired:boolean) | 设置任务是否只允许在Wifi网络环境下进行下载。 默认值 `false`
| asInQueueTask(void):InQueueTask | 申明该任务将会是队列任务中的一个任务,并且转化为`InQueueTask`,之后可以调用`InQueueTask#enqueue`将该任务入队以便于接下来启动队列任务时,可以将该任务收编到队列中
| start(void) | 启动孤立的下载任务
| pause(void) | 暂停下载任务(也可以理解为停止下载,但是在start的时候默认会断点续传)
| getId(void):int | 获取唯一Id(内部通过url与path生成)
| getUrl(void):String | 获取下载连接
| getCallbackProgressTimes(void):int | 获得progress最大回调次数
| getCallbackProgressMinInterval(void):int | 获得每个progress之间的回调间隔(ms)
| getPath(void):String | 获取文件路径 或 文件目录
| isPathAsDirectory | 判断`getPath()`返回的路径是文件存储目录(`directory`),还是文件存储路径(`directory/filename`)
| getTargetFilePath | 获取目标文件的存储路径
| getListener(void):FileDownloadListener | 获取监听器
| getSoFarBytes(void):int | 获取已经下载的字节数
| getTotalBytes(void):int | 获取下载文件总大小
| getStatus(void):int | 获取当前的状态
| isForceReDownload(void):boolean | 是否强制重新下载
| getEx(void):Throwable | 获取下载过程抛出的Throwable
| isReusedOldFile(void):boolean | 判断是否是直接使用了旧文件(检测是有效文件),没有启动下载
| getTag(void):Object | 获取用户setTag进来的Object
| getTag(key:int):Object | 根据key获取存储在task中的变量
| isContinue(void):boolean | 是否成功断点续传
| getEtag(void):String | 获取当前下载获取到的ETag
| getAutoRetryTimes(void):int | 自动重试次数
| getRetryingTimes(void):int | 当前重试次数。将要开始重试的时候,会将接下来是第几次
| isSyncCallback(void):boolean | 是否是设置了所有FileDownloadListener中的回调都直接在下载线程直接回调而不抛到ui线程
| getSpeed():int | 获取任务的下载速度, 下载过程中为实时速度,下载结束状态为平均速度
| isUsing():boolean | 判断当前的Task对象是否在引擎中启动过
| isWifiRequired():boolean | 获取当前任务是否被设置过只允许在Wifi网络环境下下载

#### 监听器(`FileDownloadListener`)说明

##### 一般的下载回调流程:

```
pending -> started -> connected -> (progress <->progress) -> blockComplete -> completed
```

##### 可能会遇到以下回调而直接终止整个下载过程:

```
paused / completed / error / warn
```

##### 如果检测存在已经下载完成的文件(可以通过`isReusedOldFile`进行决策是否是该情况)(也可以通过`setForceReDownload(true)`来避免该情况):

```
blockComplete -> completed
```

##### 方法说明

| 回调方法 | 备注 | 带回数据
| --- | --- | ---
| pending | 等待,已经进入下载队列 | 数据库中的soFarBytes与totalBytes
| started | 结束了pending,并且开始当前任务的Runnable | -
| connected | 已经连接上 | ETag, 是否断点续传, soFarBytes, totalBytes
| progress | 下载进度回调 | soFarBytes
| blockComplete | 在完成前同步调用该方法,此时已经下载完成 | -
| retry | 重试之前把将要重试是第几次回调回来 | 之所以重试遇到Throwable, 将要重试是第几次, soFarBytes
| completed | 完成整个下载过程 | -
| paused | 暂停下载 | soFarBytes
| error | 下载出现错误 | 抛出的Throwable
| warn | 在下载队列中(正在等待/正在下载)已经存在相同下载连接与相同存储路径的任务 | -


![][file_download_listener_callback_flow_png]

##### 由于`FileDownloadListener`中的方法回调过快,导致掉帧?

> 你有两种方法可以解决这个问题

1. `FileDownloader#enableAvoidDropFrame`, 默认 就是开启的
2. `BaseDownloadTask#setSyncCallback`, 默认是false, 如果设置为true,所有的回调都会在下载线程直接同步调用而不会抛到ui线程。

#### `FileDownloadMonitor`

> 你可以添加一个全局监听器来进行打点或者是调试

| 方法名 | 备注
| --- | ---
| setGlobalMonitor(monitor:IMonitor) | 设置与替换一个全局监听器到下载引擎中
| releaseGlobalMonitor(void) | 释放已经设置到下载引擎中的全局监听器
| getMonitor(void) | 获取已经设置到下载引擎中的全局监听器


##### `FileDownloadMonitor.IMonitor`

> 监听器接口类

|  接口 | 备注
| --- | ---
| onRequestStart(count:int, serial:boolean, lis:FileDownloadListener) | 将会在启动队列任务是回调这个方法
| onRequestStart(task:BaseDownloadTask) | 将会在启动单一任务时回调这个方法
| onTaskBegin(task:BaseDownloadTask) | 将会在内部接收并开始task的时候回调这个方法(会在`pending`回调之前)
| onTaskStarted(task:BaseDownloadTask) | 将会在task结束pending开始task的runnable的时候回调该方法
| onTaskOver(task:BaseDownloadTask) | 将会在task走完所有生命周期是回调这个方法

#### `FileDownloadUtils`

| 方法名 | 备注
| --- | ---
| setDefaultSaveRootPath(path:String) | 在整个引擎中没有设置路径时`BaseDownloadTask#setPath`这个路径将会作为它的Root path
| getTempPath | 获取用于存储还未下载完成文件的临时存储路径: `filename.temp`
| isFilenameConverted(context:Context) | 判断是否所有数据库中下载中的任务的文件名都已经从`filename`(在旧架构中)转为`filename.temp`

#### `FileDownloadNotificationHelper`

> 如何快速集成Notification呢? 建议参考[NotificationMinSetActivity](https://github.com/lingochamp/FileDownloader/blob/master/demo/src/main/java/com/liulishuo/filedownloader/demo/NotificationMinSetActivity.java)、[NotificationSampleActivity](https://github.com/lingochamp/FileDownloader/blob/master/demo/src/main/java/com/liulishuo/filedownloader/demo/NotificationSampleActivity.java)。

#### `filedownloader.properties`

> 如果你需要定制化FileDownloader,可以在你的项目模块的`assets` 目录下添加 'filedownloader.properties' 文件(如 `/demo/src/main/assets/filedownloader.properties`),然后添加以下可选相关配置。

> 格式: `keyword=value`

| 关键字 | 描述 | 默认值
| --- | --- | ---
| http.lenient | 如果你遇到了: 'can't know the size of the download file, and its Transfer-Encoding is not Chunked either', 但是你想要忽略类似的返回头不规范的错误,直接将该关键字参数设置为`true`即可,我们将会将其作为`chunck`进行处理 | false
| process.non-separate | FileDownloadService 默认是运行在独立进程':filedownloader'上的, 如果你想要FileDownloadService共享并运行在主进程上, 将该关键字参数设置为`true`,可以有效减少IPC产生的I/O | false
| download.min-progress-step | 最小缓冲大小,用于判定是否是时候将缓冲区中进度同步到数据库,以及是否是时候要确保下缓存区的数据都已经写文件。值越小,更新会越频繁,下载速度会越慢,但是应对进程被无法预料的情况杀死时会更加安全 | 65536
| download.min-progress-time | 最小缓冲时间,用于判定是否是时候将缓冲区中进度同步到数据库,以及是否是时候要确保下缓存区的数据都已经写文件。值越小,更新会越频繁,下载速度会越慢,但是应对进程被无法预料的情况杀死时会更加安全 | 2000
| download.max-network-thread-count | 用于同时下载的最大网络线程数, 区间[1, 12] | 3
| file.non-pre-allocation | 是否不需要在开始下载的时候,预申请整个文件的大小(`content-length`) | false
| broadcast.completed | 是否需要在任务下载完成后发送一个完成的广播 | false

> 如果你使用`broadcast.completed`并且接收任务完成的广播,你需要注册Action为`filedownloader.intent.action.completed`的广播并且使用`FileDownloadBroadcastHandler`来处理接收到的`Intent`。

III. 异常处理

> 所有的异常,都将在 `FileDownloadListener#error(BaseDownloadTask, Throwable)` 中获知。

| Exception | 原因
| --- | ---
| `FileDownloadHttpException`| 在发出请求以后,response-code不是200(HTTP_OK),也不是206(HTTP_PARTIAL)的情况下会抛出该异常; 在这个异常对象会带上 response-code、response-header、request-header。
| `FileDownloadGiveUpRetryException` | 在请求返回的 response-header 中没有带有文件大小(content-length),并且不是流媒体(transfer-encoding)的情况下会抛出该异常;出现这个异常,将会忽略所有重试的机会(`BaseDownloadTask#setAutoRetryTimes`). 你可以通过在 `filedownloader.properties`中添加 `http.lenient=true` 来忽略这个异常,并且在该情况下,直接作为流媒体进行下载。
| `FileDownloadOutOfSpaceException` | 当将要下载的文件大小大于剩余磁盘大小时,会抛出这个异常。
| 其他 | 程序错误。
| `FileDownloadNetworkPolicyException` | 设置了`BaseDownloadTask#setWifiRequired(true)`,在下载过程中,一旦发现网络情况转为非Wifi环境,便会抛回这个异常
| `PathConflictException` | 当有一个正在下载的任务,它的存储路径与当前任务的存储路径完全一致,为了避免多个任务对同一个文件进行写入,当前任务便会抛回这个异常



## III. 低内存情况

### 非下载进程(一般是UI进程):

> 这边的数据并不多,只是一些队列数据,用不了多少内存。

#### [前台进程](http://developer.android.com/intl/zh-cn/guide/components/processes-and-threads.html)数据被回收:

如果在前台的时候这个数据都被回收了, 你的应用应该也挂了。极低概率事件。

#### [后台进程](http://developer.android.com/intl/zh-cn/guide/components/processes-and-threads.html)数据被回收:

一般事件, 如果是你的下载是UI进程启动的,如果你的UI进程处于`后台进程`(可以理解为应用被退到后台)状态,在内存不足的情况下会被回收(回收优先级高于`服务进程`),此时分两种情况:

1. 是串行队列任务,在回收掉UI进程内存以后,下载进程会继续下载完已经pending到下载进程的那个任务,而还未pending到下载进程的任务会中断下载(由于任务驱动线性执行的是在UI进程); 有损体验: 下次进入应用重启启动整个队列,会继续上次的下载。

2. 是并行队列任务,在回收掉UI进程内存以后,下载进程会继续下载所有任务(所有已经pending到下载进程的任务,由于这里的pending速度是很快的,因此几乎是点击并行下载,所有任务在很短的时间内都已经pending到下载进程了),而UI进程由于被回收,将不会收到所有的监听; 有损体验: 下次进入应用重新启动整个队列,就会和正常的下载启动一致,收到所有情况的监听。

### 下载进程:

> 对内存有一定的占用,但是并不多,每次启动进程会根据数据的有效性进行清理冗余数据,被回收是低概率事件

由于下载不断有不同的buffer占用内存,但是由于在下载时,是活跃的`服务进程`,因此被回收是低概率事件(会先回收完所有`空进程`、`后台进程`(后台应用)以后,如果内存还不够,才会回收该进程)。

即使被回收,也不会有任何问题。由于我们使用的是`START_STICKY`(如果不希望被重启可主动调用`FileDownloader#unBindService`/`FileDownloader#unBindServiceIfIdle`),因此在内存足够的时候,下载进程会尝试重启(系统调度),非下载进程(一般是UI进程) 接收到下载进程的连接,会继续下载与继续接收回调,下载进程也会断点续传没有下载完的所有任务(无论并行与串行),不会影响体验。

## IV. LICENSE

```
Copyright (c) 2015 LingoChamp Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
```

[gitter_url]: https://gitter.im/lingochamp/FileDownloader?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge
[gitter_svg]: https://badges.gitter.im/lingochamp/FileDownloader.svg
[license_2_svg]: https://img.shields.io/hexpm/l/plug.svg
[android_platform_svg]: https://img.shields.io/badge/Platform-Android-brightgreen.svg
[file_downloader_svg]: https://img.shields.io/badge/Android-FileDownloader-orange.svg
[mix_tasks_demo_gif]: https://github.com/lingochamp/FileDownloader/raw/master/art/mix_tasks_demo.gif
[parallel_tasks_demo_gif]: https://github.com/lingochamp/FileDownloader/raw/master/art/parallel_tasks_demo.gif
[serial_tasks_demo_gif]: https://github.com/lingochamp/FileDownloader/raw/master/art/serial_tasks_demo.gif
[tasks_manager_demo_gif]: https://github.com/lingochamp/FileDownloader/raw/master/art/tasks_manager_demo.gif
[avoid_drop_frames_1_gif]: https://github.com/lingochamp/FileDownloader/raw/master/art/avoid_drop_frames1.gif
[avoid_drop_frames_2_gif]: https://github.com/lingochamp/FileDownloader/raw/master/art/avoid_drop_frames2.gif
[single_demo_gif]: https://github.com/lingochamp/FileDownloader/raw/master/art/single_demo.gif
[chunked_demo_gif]: https://github.com/lingochamp/FileDownloader/raw/master/art/chunked_demo.gif
[bintray_svg]: https://api.bintray.com/packages/jacksgong/maven/FileDownloader/images/download.svg
[bintray_url]: https://bintray.com/jacksgong/maven/FileDownloader/_latestVersion
[file_download_listener_callback_flow_png]: https://github.com/lingochamp/FileDownloader/raw/master/art/filedownloadlistener_callback_flow.png
[build_status_svg]: https://travis-ci.org/lingochamp/FileDownloader.svg?branch=master
[filedownloader_snapshot_svg]: https://img.shields.io/badge/SnapShot-1.7.8-yellow.svg
[build_status_link]: https://travis-ci.org/lingochamp/FileDownloader


================================================
FILE: README.md
================================================
# FileDownloader
Android multi-task file download engine.


[![Download][bintray_svg]][bintray_url]
![][file_downloader_svg]
[![Build Status][build_status_svg]][build_status_link]
[![][filedownloader_snapshot_svg]](https://oss.sonatype.org/content/repositories/snapshots/com/liulishuo/filedownloader/)

> [中文文档](https://github.com/lingochamp/FileDownloader/blob/master/README-zh.md)

## FileDownloader2

Now, [FileDownloader2-OkDownload](https://github.com/lingochamp/okdownload) is released, okdownload will contain all advantage on the FileDownloader and beyond.

Because of FileDownloader unit-test coverage is very low, so all farther features and enhances will be achieved on the okdownload instead of FileDownloader, and FileDownloader will only focuses on bug fixes.

## DEMO

![][single_demo_gif]
![][chunked_demo_gif]
![][serial_tasks_demo_gif]
![][parallel_tasks_demo_gif]
![][tasks_manager_demo_gif]
![][hybrid_test_demo_gif]
![][avoid_drop_frames_1_gif]
![][avoid_drop_frames_2_gif]

## Installation

FileDownloader is installed by adding the following dependency to your `build.gradle` file:

```groovy
dependencies {
    implementation 'com.liulishuo.filedownloader:library:1.7.7'
}
```

Snapshots of the development version are available in [Sonatype's `snapshots` repository](https://oss.sonatype.org/content/repositories/snapshots/), you can include on your gradle project through:

```groovy
repositories {
    maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
}
```

## Open customize component

From now on, FileDownloader support following components to be customized by yourself:

| Name | Interface | Default Impl
| --- | --- | ---
| Connection | [FileDownloadConnection][FileDownloadConnection-java-link] | [FileDownloadUrlConnection][FileDownloadUrlConnection-java-link]
| OutputStream | [FileDownloadOutputStream][FileDownloadOutputStream-java-link] | [FileDownloadRandomAccessFile][FileDownloadRandomAccessFile-java-link]
| Database | [FileDownloadDatabase][FileDownloadDatabase-java-link] | [RemitDatabase][RemitDatabase-java-link]
| ConnectionCountAdapter | [ConnectionCountAdapter][ConnectionCountAdapter-java-link] | [DefaultConnectionCountAdapter][DefaultConnectionCountAdapter-java-link]
| IdGenerator | [IdGenerator][IdGenerator-java-link] | [DefaultIdGenerator][DefaultIdGenerator-java-link]
| ForegroundServiceConfig | [ForegroundServiceConfig][ForegroundServiceConfig-java-link] | [ForegroundServiceConfig][ForegroundServiceConfig-java-link]

> - If you want to use okhttp as your connection component, the simplest way is [this repo](https://github.com/Jacksgong/filedownloader-okhttp3-connection).
> - If you don't want to use any database on FileDownloader(the database on FileDownloader is used for persist tasks' breakpoint info) just using [NoDatabaseImpl.java](https://github.com/lingochamp/FileDownloader/blob/master/library/src/main/java/com/liulishuo/filedownloader/services/NoDatabaseImpl.java)

### How to valid it?

Just create your own `DownloadMgrInitialParams.InitCustomMaker` and put those customized component to it, finally init the FileDownloader with it: [FileDownloader#init](https://github.com/lingochamp/FileDownloader/blob/master/library/src/main/java/com/liulishuo/filedownloader/FileDownloader.java#L62)

## Adaptation

### Adapt to Android 8.0

The restriction of background service has been tightened since Android 8.0, for more details, please refer to [here](https://developer.android.com/about/versions/oreo/background).
So, after Android 8.0, the download service will be a foreground service when start downloading during app is in background and you will see a notification with a title named "FileDownloader" start from FileDownloader 1.7.6.
You can refer to [here](https://github.com/lingochamp/FileDownloader/wiki/Compatibility-of-Android-O-Service) to custom the notification.

### Adapt to Android 9.0

Starting with Android 9.0 (API level 28), cleartext support is disabled by default, you can have a look at [here](https://stackoverflow.com/questions/45940861/android-8-cleartext-http-traffic-not-permitted) to know about more details.
FileDownloader demo has handled this problem start with 1.7.6.

According to the [migration notes](https://developer.android.com/about/versions/pie/android-9.0-migration#tya), the FOREGROUND_SERVICE permission has been added to the library manifest since FileDownloader 1.7.6.

## Welcome PR

> If you can improve the unit test for this project would be great.

- Comments as much as possible.
- Commit message format follow: [AngularJS's commit message convention](https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md#-git-commit-guidelines) .
- The change of each commit as small as possible.

![][structure-img]
![][message-system-img]

## Usage

By default, the FileDownloadService runs on the separate process, if you want to run it on the main process, just configure on the [filedownloader.properties](https://github.com/lingochamp/FileDownloader/wiki/filedownloader.properties), and you can use `FileDownloadUtils.isDownloaderProcess(Context)` to check whether the FileDownloadService can run on the current process.

For more readable, Moved to [Wiki](https://github.com/lingochamp/FileDownloader/wiki).

## LICENSE

```
Copyright (c) 2015 LingoChamp Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
```

[license_2_svg]: https://img.shields.io/hexpm/l/plug.svg
[android_platform_svg]: https://img.shields.io/badge/Platform-Android-brightgreen.svg
[file_downloader_svg]: https://img.shields.io/badge/Android-FileDownloader-orange.svg
[structure-img]: https://github.com/lingochamp/FileDownloader/raw/master/art/structure.png
[message-system-img]: https://github.com/lingochamp/FileDownloader/raw/master/art/message-system.png
[hybrid_test_demo_gif]: https://github.com/lingochamp/FileDownloader/raw/master/art/hybrid_test_demo.gif
[parallel_tasks_demo_gif]: https://github.com/lingochamp/FileDownloader/raw/master/art/parallel_tasks_demo.gif
[serial_tasks_demo_gif]: https://github.com/lingochamp/FileDownloader/raw/master/art/serial_tasks_demo.gif
[tasks_manager_demo_gif]: https://github.com/lingochamp/FileDownloader/raw/master/art/tasks_manager_demo.gif
[avoid_drop_frames_1_gif]: https://github.com/lingochamp/FileDownloader/raw/master/art/avoid_drop_frames1.gif
[avoid_drop_frames_2_gif]: https://github.com/lingochamp/FileDownloader/raw/master/art/avoid_drop_frames2.gif
[single_demo_gif]: https://github.com/lingochamp/FileDownloader/raw/master/art/single_demo.gif
[chunked_demo_gif]: https://github.com/lingochamp/FileDownloader/raw/master/art/chunked_demo.gif
[bintray_svg]: https://api.bintray.com/packages/jacksgong/maven/FileDownloader/images/download.svg
[bintray_url]: https://bintray.com/jacksgong/maven/FileDownloader/_latestVersion
[file_download_listener_callback_flow_png]: https://github.com/lingochamp/FileDownloader/raw/master/art/filedownloadlistener_callback_flow.png
[build_status_svg]: https://travis-ci.org/lingochamp/FileDownloader.svg?branch=master
[filedownloader_snapshot_svg]: https://img.shields.io/badge/SnapShot-1.7.8-yellow.svg
[build_status_link]: https://travis-ci.org/lingochamp/FileDownloader
[FileDownloadConnection-java-link]: https://github.com/lingochamp/FileDownloader/blob/master/library/src/main/java/com/liulishuo/filedownloader/connection/FileDownloadConnection.java
[FileDownloadUrlConnection-java-link]: https://github.com/lingochamp/FileDownloader/blob/master/library/src/main/java/com/liulishuo/filedownloader/connection/FileDownloadUrlConnection.java
[FileDownloadDatabase-java-link]: https://github.com/lingochamp/FileDownloader/blob/master/library/src/main/java/com/liulishuo/filedownloader/database/RemitDatabase.java
[RemitDatabase-java-link]: https://github.com/lingochamp/FileDownloader/blob/master/library/src/main/java/com/liulishuo/filedownloader/database/RemitDatabase.java
[FileDownloadOutputStream-java-link]: https://github.com/lingochamp/FileDownloader/blob/master/library/src/main/java/com/liulishuo/filedownloader/stream/FileDownloadOutputStream.java
[FileDownloadRandomAccessFile-java-link]: https://github.com/lingochamp/FileDownloader/blob/master/library/src/main/java/com/liulishuo/filedownloader/stream/FileDownloadRandomAccessFile.java
[ConnectionCountAdapter-java-link]: https://github.com/lingochamp/FileDownloader/blob/master/library/src/main/java/com/liulishuo/filedownloader/util/FileDownloadHelper.java#L100
[DefaultConnectionCountAdapter-java-link]: https://github.com/lingochamp/FileDownloader/blob/master/library/src/main/java/com/liulishuo/filedownloader/connection/DefaultConnectionCountAdapter.java
[IdGenerator-java-link]: https://github.com/lingochamp/FileDownloader/blob/master/library/src/main/java/com/liulishuo/filedownloader/util/FileDownloadHelper.java#L55
[DefaultIdGenerator-java-link]: https://github.com/lingochamp/FileDownloader/blob/master/library/src/main/java/com/liulishuo/filedownloader/services/DefaultIdGenerator.java
[ForegroundServiceConfig-java-link]:https://github.com/lingochamp/FileDownloader/blob/master/library/src/main/java/com/liulishuo/filedownloader/services/ForegroundServiceConfig.java


================================================
FILE: build.gradle
================================================
buildscript {
    repositories {
        jcenter()
        google()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.3.1'
        classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3'
    }
}

allprojects {
    repositories {
        jcenter()
        google()
    }
}

subprojects {
    group = GROUP
    version = VERSION_NAME
}

task clean(type: Delete) {
    delete rootProject.buildDir
}


================================================
FILE: checkstyle.xml
================================================
<?xml version="1.0"?>
<!DOCTYPE module PUBLIC
    "-//Puppy Crawl//DTD Check Configuration 1.3//EN"
    "http://checkstyle.sourceforge.net/dtds/configuration_1_3.dtd">

<module name="Checker">

    <module name="SuppressWarningsFilter" />

    <!--module name="NewlineAtEndOfFile"/-->
    <module name="FileLength"/>
    <module name="FileTabCharacter"/>

    <!-- Trailing spaces -->
    <module name="RegexpSingleline">
        <property name="format" value="\s+$"/>
        <property name="message" value="Line has trailing spaces."/>
    </module>

    <!-- Space after 'for' and 'if' -->
    <module name="RegexpSingleline">
        <property name="format" value="^\s*(for|if)[^ ]\("/>
        <property name="message" value="Space needed before opening parenthesis."/>
    </module>

    <!-- For each spacing -->
    <module name="RegexpSingleline">
        <property name="format" value="^\s*for \(.*?([^ ]:|:[^ ])"/>
        <property name="message" value="Space needed around ':' character."/>
    </module>

    <module name="TreeWalker">
        <!--<property name="cacheFile" value="${checkstyle.cache.file}"/>-->

        <!-- Checks for Javadoc comments.                     -->
        <!-- See http://checkstyle.sf.net/config_javadoc.html -->
        <!--module name="JavadocMethod"/-->
        <!--module name="JavadocType"/-->
        <!--module name="JavadocVariable"/-->
        <!--module name="JavadocStyle"/-->

        <module name="SuppressWarningsHolder" />

        <!-- Checks for Naming Conventions.                  -->
        <!-- See http://checkstyle.sf.net/config_naming.html -->
        <module name="ConstantName"/>
        <module name="LocalFinalVariableName"/>
        <module name="LocalVariableName"/>
        <module name="MemberName"/>
        <module name="MethodName">
            <property name="format" value="^[a-z][a-zA-Z0-9_]*$"/>
        </module>
        <module name="PackageName"/>
        <module name="ParameterName"/>
        <!--<module name="StaticVariableName"/>-->
        <module name="TypeName"/>


        <!-- Checks for imports                              -->
        <!-- See http://checkstyle.sf.net/config_import.html -->
        <module name="AvoidStarImport"/>
        <module name="IllegalImport"/>
        <module name="RedundantImport"/>
        <module name="UnusedImports">
            <property name="processJavadoc" value="true"/>
        </module>


        <!-- Checks for Size Violations.                    -->
        <!-- See http://checkstyle.sf.net/config_sizes.html -->
        <module name="LineLength">
            <property name="max" value="100"/>
        </module>
        <module name="MethodLength">
            <property name="max" value="200"/>
        </module>
        <!--<module name="ParameterNumber">-->
            <!--<property name="max" value="10"/>-->
        <!--</module>-->


        <!-- Checks for whitespace                               -->
        <!-- See http://checkstyle.sf.net/config_whitespace.html -->
        <module name="GenericWhitespace"/>
        <!--<module name="EmptyForIteratorPad"/>-->
        <module name="MethodParamPad"/>
        <module name="NoWhitespaceAfter"/>
        <module name="NoWhitespaceBefore"/>
        <module name="OperatorWrap"/>
        <module name="ParenPad"/>
        <module name="TypecastParenPad"/>
        <module name="WhitespaceAfter"/>
        <module name="WhitespaceAround"/>


        <!-- Modifier Checks                                    -->
        <!-- See http://checkstyle.sf.net/config_modifiers.html -->
        <module name="ModifierOrder"/>
        <module name="RedundantModifier"/>


        <!-- Checks for blocks. You know, those {}'s         -->
        <!-- See http://checkstyle.sf.net/config_blocks.html -->
        <module name="AvoidNestedBlocks"/>
        <module name="EmptyBlock"/>
        <module name="EmptyCatchBlock">
            <property name="exceptionVariableName" value="expected|ignore"/>
        </module>
        <module name="LeftCurly">
            <!-- No METHOD_DEF, because I think simple method can be one line -->
            <property name="tokens" value="INTERFACE_DEF, CLASS_DEF, ANNOTATION_DEF, ENUM_DEF,
            CTOR_DEF, ENUM_CONSTANT_DEF, LITERAL_WHILE, LITERAL_TRY, LITERAL_CATCH,
            LITERAL_FINALLY, LITERAL_SYNCHRONIZED, LITERAL_SWITCH, LITERAL_DO, LITERAL_IF,
            LITERAL_ELSE, LITERAL_FOR, STATIC_INIT, OBJBLOCK, LAMBDA"/>
        </module>
        <module name="NeedBraces">
            <property name="allowSingleLineStatement" value="true"/>
        </module>
        <module name="RightCurly"/>


        <!-- Checks for common coding problems               -->
        <!-- See http://checkstyle.sf.net/config_coding.html -->
        <!--module name="AvoidInlineConditionals"/-->
        <module name="CovariantEquals"/>
        <module name="EmptyStatement"/>
        <!--<module name="EqualsAvoidNull"/>-->
        <module name="EqualsHashCode"/>
        <!--module name="HiddenField"/-->
        <module name="IllegalInstantiation"/>
        <!--<module name="InnerAssignment"/>-->
        <!--module name="MagicNumber"/-->
        <module name="MissingSwitchDefault"/>
        <!--<module name="RedundantThrows"/>-->
        <module name="SimplifyBooleanExpression"/>
        <module name="SimplifyBooleanReturn"/>

        <!-- Checks for class design                         -->
        <!-- See http://checkstyle.sf.net/config_design.html -->
        <!--module name="DesignForExtension"/-->
        <!--module name="FinalClass"/-->
        <!--module name="HideUtilityClassConstructor"/-->
        <!--module name="InterfaceIsType"/-->
        <!--module name="VisibilityModifier"/-->


        <!-- Miscellaneous other checks.                   -->
        <!-- See http://checkstyle.sf.net/config_misc.html -->
        <!--module name="ArrayTypeStyle"/-->
        <!--module name="FinalParameters"/-->
        <!--module name="TodoComment"/-->
        <module name="UpperEll"/>
    </module>
</module>

================================================
FILE: demo/.gitignore
================================================
/build


================================================
FILE: demo/build.gradle
================================================
apply plugin: 'com.android.application'

android {
    signingConfigs {
        release {
            keyAlias 'FileDownloaderDemoKey'
            keyPassword 'liulishuo'
            storeFile file('filedownloaderdemo.jks')
            storePassword 'liulishuo'
        }
    }
    compileSdkVersion COMPILE_SDK_VERSION as int
    buildToolsVersion BUILD_TOOLS_VERSION as String

    defaultConfig {
        minSdkVersion 14
        targetSdkVersion COMPILE_SDK_VERSION as int

        File file = project.rootProject.file('local.properties');
        def needLog = null
        if (file.exists()) {
            Properties p = new Properties()
            p.load(file.newDataInputStream())
            needLog = p.getProperty("needLog")
        }
        buildConfigField "boolean", "DOWNLOAD_NEED_LOG", needLog == "true" ? "true" : "false"
    }
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.release
        }

        debug {
            minifyEnabled false
        }
    }
    lintOptions {
        // This seems to be firing due to okio referencing java.nio.File
        // which is harmless for us.
        warning 'InvalidPackage'
    }
}

dependencies {
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support:recyclerview-v7:28.0.0'
    implementation 'com.android.support:design:28.0.0'
    debugImplementation 'cn.dreamtobe.threaddebugger:threaddebugger:1.3.3'
    releaseImplementation 'cn.dreamtobe.threaddebugger:threaddebugger-no-op:1.3.3'
    implementation project(':library')
    // for testing
    implementation 'com.squareup.okio:okio:1.14.0'
}


================================================
FILE: demo/proguard-rules.pro
================================================
# filedownloader uses okhttp3-lib, so need add below proguard rules.
-dontwarn okhttp3.*
-dontwarn okio.**

================================================
FILE: demo/src/main/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.liulishuo.filedownloader.demo">

    <uses-permission android:name="android.permission.INTERNET" />
    <!-- When you invoke BaseDownloadTask#setWifiRequired(true), you need declare ACCESS_NETWORK_STATE permission -->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission
        android:name="android.permission.READ_EXTERNAL_STORAGE"
        android:maxSdkVersion="18" />
    <uses-permission
        android:name="android.permission.WRITE_EXTERNAL_STORAGE"
        android:maxSdkVersion="18" />

    <application
        android:name=".DemoApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:networkSecurityConfig="@xml/network_security_config"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".HybridTestActivity"
            android:label="@string/hybrid_test_title" />
        <activity
            android:name=".SingleTaskTestActivity"
            android:label="@string/single_task_test_title" />
        <activity
            android:name=".MultitaskTestActivity"
            android:label="@string/multitask_test_title" />
        <activity
            android:name=".performance.PerformanceTestActivity"
            android:label="@string/performance_test_title" />
        <activity
            android:name=".TasksManagerDemoActivity"
            android:label="@string/tasks_manager_demo_title" />
        <activity
            android:name=".NotificationSampleActivity"
            android:label="@string/notification_sample_title" />
    </application>

</manifest>

================================================
FILE: demo/src/main/assets/filedownloader.properties
================================================
# If you occur exception: 'can't know the size of the download file, and its Transfer-Encoding is not Chunked either',
# but you want to ignore such exception, set true, will deal with it as the case of transfer encoding chunk. default false
#
# If true, will ignore HTTP response header does not has content-length either not chunk transfer
# encoding.
#
# Default false.
http.lenient=false

# The FileDownloadService runs in the separate process ':filedownloader' as default, if you want to
# run the FileDownloadService in the main process, just set true. default false.
process.non-separate=false

# The min buffered so far bytes.
#
# Used for adjudging whether is time to sync the downloaded so far bytes to database and make sure
# sync the downloaded buffer to local file.
#
# More smaller more frequently, then download more slowly, but will more safer in scene of the
# process is killed unexpectedly.
#
# Default 65536, which follow the value in com.android.providers.downloads.Constants.
download.min-progress-step=65536

# The min buffered millisecond.
#
# Used for adjudging whether is time to sync the downloaded so far bytes to database and make sure
# sync the downloaded buffer to local file.
#
# More smaller more frequently, then download more slowly, but will more safer in scene of the
# process is killed unexpectedly.
#
# Default 2000, which follow the value in com.android.providers.downloads.Constants.
download.min-progress-time=2000

# The maximum network thread count for downloading simultaneously.
#
# FileDownloader is designed to download 3 files simultaneously as maximum size as default, and the
# rest of the task is in the FIFO(First In First Out) pending queue.
#
# Because the network resource is limited to one device, it means if FileDownloader start
# downloading tasks unlimited simultaneously, it will be blocked by lack of the network resource,
# and more useless CPU occupy.
#
# The relative efficiency of 3 is higher than others(As Fresco or Picasso do), But for case by case
# FileDownloader is support to configure for this.
#
# Default 3.
# max 12, min 1. If the value more than {@code max} will be replaced with {@code max}; If the value
# less than {@code min} will be replaced with {@code min}.
download.max-network-thread-count=3

# Whether need to pre-allocates the 'content-length' space when start downloading.
#
# FileDownloader is designed to create the file and pre-allocates the 'content-length' space for it
# when start downloading.
#
# Because FileDownloader want to prevent the space is not enough to store coming data in downloading
# state as default.
#
# Default false.
#
file.non-pre-allocation=false

# Whether need to post an broadcast when downloading is completed.
#
# This option is very useful when you download something silent on the background on the filedownloader
# process, and the main process is killed, but you want to do something on the main process when tasks
# are completed downloading on the filedownloader process, so you can set this one to `true`, then
# when a task is completed task, you will receive the broadcast, and the main process will be relaunched
# to handle the broadcast.
#
# If you want to receive such broadcast, you also need to register receiver with
# 'filedownloader.intent.action.completed' action name on 'AndroidManifest.xml'.
#
# You can use FileDownloadBroadcastHandler class to parse the received intent.
#
# Default false.
#
broadcast.completed=false

# Whether you want the first trial connection with HEAD method to request to backend or not.
#
# if this value is true, the first trial connection will with HEAD method instead of GET method and
# then you will reduce 1 byte cost on the response body, but if the backend can't support HEAD
# method you will receive 405 response code and failed to download.
#
# Default false.
#
download.trial-connection-head-method=false


================================================
FILE: demo/src/main/java/com/liulishuo/filedownloader/demo/Constant.java
================================================
package com.liulishuo.filedownloader.demo;

/**
 * Created by Jacksgong on 12/19/15.
 */
public interface Constant {

    String[] CHUNKED_TRANSFER_ENCODING_DATA_URLS = {
            "http://www.httpwatch.com/httpgallery/chunked/chunkedimage.aspx?0.04400023248109086",
    };

    String LIULISHUO_APK_URL = "http://cdn.llsapp.com/android/LLS-v4.0-595-20160908-143200.apk";
    String LIULISHUO_CONTENT_DISPOSITION_FILENAME = "LLS-v4.0-595-20160908-143200.apk";

    String[] BIG_FILE_URLS = {
            // 5m
            "http://mirror.internode.on.net/pub/test/5meg.test5",
            // 6m
            "http://download.chinaunix.net/down.php?id=10608&ResourceID=5267&site=1",
            // 8m
            "http://7xjww9.com1.z0.glb.clouddn.com/Hopetoun_falls.jpg",
            // 10m
            "http://dg.101.hk/1.rar",
            // 342m
            "http://180.153.105.144/dd.myapp.com/16891/E2F3DEBB12A049ED921C6257C5E9FB11.apk",
//            "http://mirror.internode.on.net/pub/test/5meg.test4",
//            "http://mirror.internode.on.net/pub/test/5meg.test3",
//            "http://mirror.internode.on.net/pub/test/5meg.test2",
//            "http://mirror.internode.on.net/pub/test/5meg.test1",
            // 6.8m
//            "http://dlsw.baidu.com/sw-search-sp/soft/7b/33461/freeime.1406862029.exe",
            // 10m
//            "http://mirror.internode.on.net/pub/test/10meg.test",
//            "http://mirror.internode.on.net/pub/test/10meg.test1",
//            "http://mirror.internode.on.net/pub/test/10meg.test2",
//            "http://mirror.internode.on.net/pub/test/10meg.test3",
            // 10m
            "http://mirror.internode.on.net/pub/test/10meg.test4",
//            "http://mirror.internode.on.net/pub/test/10meg.test5",
            // 20m
            "http://www.pc6.com/down.asp?id=72873",
            // 22m
            "http://113.207.16.84/dd.myapp.com/16891/2E53C25B6BC55D3330AB85A1B7B57485.apk?mkey=5630b43973f537cf&f=cf87&fsname=com.htshuo.htsg_3.0.1_49.apk&asr=02f1&p=.apk",
            // 206m
            "http://down.tech.sina.com.cn/download/d_load.php?d_id=49535&down_id=1&ip=42.81.45.159"
    };

    String[] URLS = {
            // 随机小资源一般不超过10
            "http://girlatlas.b0.upaiyun.com/35/20150106/19152b4c633b321f4479.jpg!mid",
            "http://cdn-l.llsapp.com/connett/25183b40-22f2-0133-6e99-029df5130f9e",
            "http://cdn-l.llsapp.com/connett/c3115411-3669-466d-8ef2-e6c42c690303",
            "http://cdn-l.llsapp.com/connett/a55b4727-e228-410f-b44a-0385dbe9ab85",
            "http://cdn-l.llsapp.com/connett/7b6b5485-0d19-476c-816c-ff6523fae539",
            "http://cdn-l.llsapp.com/connett/33fa9155-c99a-407f-8d2c-82e9d17f4c32",
            "http://cdn-l.llsapp.com/connett/fe50a391-d111-44a9-9c2f-33aaaeec9186",
            "http://cdn.llsapp.com/crm_test_1449051526097.jpg",
            "http://cdn.llsapp.com/crm_test_1449554617476.jpeg",
            "http://cdn.llsapp.com/yy/image/3b0430db-5ff4-455c-9c8d-0213eea7b6c4.jpg",
            "http://cdn.llsapp.com/forum/image/ba80be187e0947f2b60c763a04910948_1446722022222.jpg",
            "http://cdn.llsapp.com/forum/image/NTNjMWQwMDAwMDAwMGQ0Zg==_1446122845.jpg",
            "http://cdn.llsapp.com/user_images/FEFC55C5-1E8F-45C6-AA4E-79FC79F97B6F",
            "http://cdn.llsapp.com/user_images/26ebf7deb8eb1f66056cbdac31aa18209d2f7daf_1436262740.jpg",
            "http://cdn.llsapp.com/yy/image/a1de0e33-c3f3-4795-b2b9-4dafbcf06bee.jpg",
            "http://cdn.llsapp.com/yy/image/cc4bc37d-ef77-4469-a8e9-2c70105a3f94.jpg",
            // 重复
            "http://cdn.llsapp.com/yy/image/cc4bc37d-ef77-4469-a8e9-2c70105a3f94.jpg",
            "http://cdn.llsapp.com/yy/image/dd72c879-b1c4-4fb9-b871-d57dfa3aa709.jpg",
            "http://cdn.llsapp.com/crm_test_1447220020113.jpg",
            "http://cdn.llsapp.com/crm_test_1447220428493.jpg",
            // 重复
            "http://cdn.llsapp.com/yy/image/a1de0e33-c3f3-4795-b2b9-4dafbcf06bee.jpg",
            "http://cdn.llsapp.com/forum/image/72e344b20d48432487389f8ad0dec163_1435047695818.png",
            "http://cdn.llsapp.com/forum/image/36d3070792b14633ad1f596c38f892e2_1435047020634.jpg",
            "http://cdn.llsapp.com/yy/image/5d8bfbd4-51b8-4fe6-ba01-4a5f37c478a6.jpg",
            "http://cdn.llsapp.com/forum/image/M2YwMWQwMDAwMDAwMTBmYw==_1440748066.jpg",
            "http://cdn.llsapp.com/forum/image/22f8389542734b05986c0b0dd8fd1735_1435230013392.jpg",
            "http://cdn.llsapp.com/forum/image/2e6b8f9676aa47228aad74dd37709b0e_1446202991820.jpg",
            "http://cdn.llsapp.com/forum/image/f82192fa9f764af396579e51afeb9aaf_1435049606128.jpg",
            "http://cdn.llsapp.com/forum/image/f74026981afa42e0b73a6983450deca1_1441780286505.jpg",
            "http://cdn.llsapp.com/357070051859561_1390016094611.jpg",
            // 重复
            "http://cdn-l.llsapp.com/connett/7b6b5485-0d19-476c-816c-ff6523fae539",
            "http://cdn.llsapp.com/forum/image/6f7a673ea1224019bf73bb2301f61b26_1435211914955.jpg",
            "http://cdn.llsapp.com/forum/image/a58b054f250e4237bd7d914c1feafc05_1435211918877.jpg",
            // 重复
            "http://cdn.llsapp.com/forum/image/f74026981afa42e0b73a6983450deca1_1441780286505.jpg",
            "http://cdn.llsapp.com/forum/image/432f360f3a1b4436b569c1a58c0dffe4_1435917578613.jpg",
            "http://cdn.llsapp.com/forum/image/a704f63a5b904961b71ea04b8a6aa36d_1397448248398.jpg",
            "http://cdn.llsapp.com/yy/image/52f4abdb-5f7f-46c2-9095-cce5fc09b296.png",
            "http://placekitten.com/580/320",
            "http://cdn.llsapp.com/forum/image/MWIwMWQwMDAwMDAwMTA2Yw==_1436253885.jpg",
            "http://cdn.llsapp.com/forum/image/2f003721ddb74ea1a84b2a6e603d6a44_1435046970863.jpg",
            "http://cdn.llsapp.com/crm_test_1447219868528.jpg",
            "http://cdn.llsapp.com/crm_test_1438658295447.jpg",


            // ---------------
            "http://imgsrc.baidu.com/forum/w%3D580/sign=2d51fcce8ad4b31cf03c94b3b7d7276f/48084b36acaf2eddc470ae648c1001e9380193bf.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=724ad1b57af40ad115e4c7eb672d1151/eb638535e5dde711e8dea57ba6efce1b9d166134.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=7155b164f3d3572c66e29cd4ba126352/d91090ef76c6a7efb59f4eabfcfaaf51f2de6687.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=4e454f3fd058ccbf1bbcb53229d9bcd4/c6188618367adab4b776fdce8ad4b31c8601e49f.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=e8431073c2fdfc03e578e3b0e43e87a9/af8ea0ec08fa513d06288a533c6d55fbb3fbd9ba.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=5a046dafc9fcc3ceb4c0c93ba244d6b7/5cd1f703918fa0ec15ee8580279759ee3d6ddb17.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=743d1d8071cf3bc7e800cde4e101babd/3c097bf40ad162d9e1e7839110dfa9ec8a13cd37.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=10ee22be728da9774e2f86238050f872/32d6912397dda144f74a8d3fb3b7d0a20df486f9.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=7a4eaf490bd162d985ee621421dea950/bb34e5dde71190ef0e807352cf1b9d16fcfa60c1.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=03f04c9f730e0cf3a0f74ef33a47f23d/e355564e9258d109207c483fd058ccbf6d814da5.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=10a0579bcefc1e17fdbf8c397a91f67c/c5f3b2119313b07e9989b0850dd7912397dd8c0c.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=eed1753686d6277fe9123230183a1f63/9dcd7cd98d1001e950d1f582b90e7bec55e7974b.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=4bd2cff1500fd9f9a0175561152cd42b/bc8aa61ea8d3fd1fe11e42b7314e251f95ca5f2d.jpg",
            // repeat case.
            "http://imgsrc.baidu.com/forum/w%3D580/sign=eed1753686d6277fe9123230183a1f63/9dcd7cd98d1001e950d1f582b90e7bec55e7974b.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=e7b4e3c7dbb44aed594ebeec831d876a/32f531adcbef76092a9a79122fdda3cc7dd99eaf.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=4d6e489206082838680ddc1c8898a964/3fe83901213fb80e11fd825a37d12f2eb9389414.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=299cf8ce8ad4b31cf03c94b3b7d7276f/48084b36acaf2eddc0bdaa648c1001e9380193f4.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=29d77fca3812b31bc76ccd21b6193674/a9dca144ad345982e8ed061f0df431adcaef84dd.jpg",
            // repeat case.
            "http://imgsrc.baidu.com/forum/w%3D580/sign=eed1753686d6277fe9123230183a1f63/9dcd7cd98d1001e950d1f582b90e7bec55e7974b.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=387f95ab6c224f4a5799731b39f69044/626134a85edf8db141979fe90823dd54574e7487.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=af2b5b0cca1349547e1ee86c664c92dd/b483b9014a90f60382797fca3812b31bb151ed70.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=291264639d82d158bb8259b9b00b19d5/8e50f8198618367a22af9d502f738bd4b31ce51f.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=c7d737439825bc312b5d01906ede8de7/d5c5b74543a9822625dec9aa8b82b9014a90eb26.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=77695d7638dbb6fd255be52e3925aba6/ae539822720e0cf3f179a7760b46f21fbf09aab6.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=614a17ae48540923aa696376a25ad1dc/87004a90f603738d458ce5afb21bb051f919ec7f.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=93d2e73ae850352ab16125006342fb1a/a13cf8dcd100baa16430af364610b912c8fc2e24.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=06184598bd315c6043956be7bdb3cbe6/894443a98226cffcf8f1563fb8014a90f703ea62.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=6db0c87337d3d539c13d0fcb0a86e927/413f6709c93d70cf9f9d4280f9dcd100bba12bdd.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=9560edf3241f95caa6f592bef9167fc5/2131e924b899a9014e62b3bb1c950a7b0308f5ed.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=a1cf8608c8ea15ce41eee00186023a25/9987c9177f3e67096bc9ad723ac79f3df9dc5577.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=eecf90f721a446237ecaa56aa8207246/60de8db1cb1349548ace02e9574e9258d0094a68.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=13560b451b4c510faec4e21250582528/0dfb828ba61ea8d3690da189960a304e251f5815.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=eecf90f721a446237ecaa56aa8207246/60de8db1cb1349548ace02e9574e9258d0094a68.jpg",
            // repeat case.
            "http://imgsrc.baidu.com/forum/w%3D580/sign=eecf90f721a446237ecaa56aa8207246/60de8db1cb1349548ace02e9574e9258d0094a68.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=eecf90f721a446237ecaa56aa8207246/60de8db1cb1349548ace02e9574e9258d0094a68.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=9bc331ae72f082022d9291377bfafb8a/1b2cd42a2834349b35b3bb08c8ea15ce37d3be83.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=862537777acb0a4685228b315b61f63e/ef08b3de9c82d15846698c3c810a19d8bd3e4251.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=9c1bda3ae850352ab16125006341fb1a/a13cf8dcd100baa16bf992364610b912c9fc2e63.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=420543d8d1160924dc25a213e405359b/32f2d7ca7bcb0a4606e7afb76a63f6246a60af7c.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=c544284d3b87e9504217f3642039531b/05c69f3df8dcd100c9e5dfaf738b4710b8122fc7.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=33776e678c1001e94e3c1407880f7b06/ee170924ab18972b44bc2744e7cd7b899f510abe.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=cea760b00df3d7ca0cf63f7ec21ebe3c/684f9258d109b3deca07c3e6cdbf6c81810a4c80.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=77aac436d53f8794d3ff4826e2190ead/189659ee3d6d55fb571451a86c224f4a21a4dd6b.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=ef6ca3c0cb8065387beaa41ba7dca115/fdcfc3fdfc039245aaf7c7818694a4c27c1e25fa.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=ef0286e6d009b3deebbfe460fcbe6cd3/0713b31bb051f8193f5422c4dbb44aed2f73e7c8.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=fec55e532f738bd4c421b239918a876c/f5ee76094b36acaf0aacb7727dd98d1000e99cf4.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=48422e39e850352ab16125006342fb1a/a13cf8dcd100baa1bfa066354610b912c9fc2eb4.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=2d1268678c1001e94e3c1407880c7b06/ee170924ab18972b5ad92144e7cd7b899f510a59.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=6f9ee8a14034970a47731027a5cbd1c0/a02e070828381f302e69ad27a8014c086f06f0c9.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=ad5032c19f2f07085f052a08d925b865/b31101e93901213f92886e5255e736d12e2e9581.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=72992644838ba61edfeec827713597cc/b900a18b87d6277f5d8312b629381f30e824fca8.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=433f1f6f63d9f2d3201124e799ed8a53/dbdce71190ef76c69f24dba59c16fdfaae51674e.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=7300c036d53f8794d3ff4826e21a0ead/189659ee3d6d55fb53be55a86c224f4a21a4ddc1.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=4c9c60b74a36acaf59e096f44cd88d03/6fdb81cb39dbb6fdd515c6a80824ab18962b37f6.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=95b291bfa08b87d65042ab1737092860/10dca3cc7cd98d1027472fbf203fb80e7aec90a9.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=ef679b0fca1349547e1ee86c664f92dd/b483b9014a90f603c235bfc93812b31bb151edbc.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=5ecdc676a686c91708035231f93c70c6/97004c086e061d95c17c15b67af40ad162d9ca03.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=b9ddaf869a504fc2a25fb00dd5dfe7f0/312542a7d933c89547b0bbf5d01373f083020076.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=266158f421a446237ecaa56aa8237246/60de8db1cb1349544260caea574e9258d0094ac6.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=50b490faeaf81a4c2632ecc1e72b6029/8f3433fa828ba61ef454eaa14034970a314e5982.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=31cb148d8644ebf86d716437e9f8d736/823fb13533fa828bfcb5b06dfc1f4134960a5aae.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=a8bbd18371cf3bc7e800cde4e101babd/3c097bf40ad162d93d614f9210dfa9ec8b13cdb6.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=4e26126f63d9f2d3201124e799ee8a53/dbdce71190ef76c6923dd6a59c16fdfaae516755.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=2630ab09d1a20cf44690fed746084b0c/ec1a0ef41bd5ad6ea276486480cb39dbb7fd3cb5.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=2ed231861e30e924cfa49c397c0a6e66/1f3eb80e7bec54e71f0b3690b8389b504ec26a5d.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=a4dd5daeb812c8fcb4f3f6c5cc0292b4/5d2662d0f703918f76ba1244503d269758eec4d2.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=458d67a0d31b0ef46ce89856edc551a1/8cfa43166d224f4ac1eb5c9d08f790529922d1cb.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=888b7ae7242dd42a5f0901a3333a5b2f/7f35970a304e251fca6bcb76a686c9177e3e53a4.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=5d2fcb76a686c91708035231f93f70c6/97004c086e061d95c29e18b67af40ad163d9ca61.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=f4524e5937d12f2ece05ae687fc3d5ff/45889e510fb30f24cd19c38dc995d143ac4b03b9.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=f291960fca1349547e1ee86c664f92dd/b483b9014a90f603dfc3b2c93812b31bb151edca.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=c526d13e64380cd7e61ea2e59145ad14/fdfcfc039245d688a1679c2aa5c27d1ed31b24d3.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=145760379f510fb37819779fe932c893/55610c338744ebf8e8d64ab1d8f9d72a6159a79e.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=7255fcaf91ef76c6d0d2fb23ad17fdf6/ef1273f082025aaf33875045faedab64024f1a83.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=9a90a5bf4b90f60304b09c4f0913b370/f48165380cd7912387cfbdfaac345982b2b78015.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=8b32fb409825bc312b5d01906ede8de7/d5c5b74543a98226693b05a98b82b9014b90eb43.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=42dbcb747acb0a4685228b315b62f63e/ef08b3de9c82d1588297703f810a19d8bc3e4223.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=08986a78a6efce1bea2bc8c29f50f3e8/bc035aafa40f4bfb639ab7da024f78f0f63618f2.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=13a61069902397ddd679980c6983b216/ac44d688d43f8794d25c61a0d31b0ef41ad53a99.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=6f03d5a97e3e6709be0045f70bc69fb8/50071d950a7b0208b371166f63d9f2d3562cc881.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=4a44166f63d9f2d3201124e799ed8a53/dbdce71190ef76c6965fd2a59c16fdfaae5167ab.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=26e0d6ad48540923aa696376a259d1dc/87004a90f603738d022624acb21bb051f919ecd5.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=d835b08a5882b2b7a79f39cc01accb0a/9ac37d1ed21b0ef462a4b0d0dcc451da80cb3ef4.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=de8abf31a1ec08fa260013af69ef3d4d/8a8e8c5494eef01f13a0034be1fe9925bd317d8c.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=d079799210dfa9ecfd2e561f52d1f754/48c7a7efce1b9d16df5081eff2deb48f8d5464ad.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=a97a4b860dd79123e0e0947c9d365917/c2029245d688d43fe46e8a7c7c1ed21b0ff43b7d.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=4c307cfdfaf2b211e42e8546fa816511/4c8a4710b912c8fc9fc6ec43fd039245d6882103.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=714fb895d50735fa91f04eb1ae500f9f/cc1ebe096b63f624b137238d8644ebf81b4ca3d3.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=9ce120865243fbf2c52ca62b807fca1e/f310728b4710b9129241f370c2fdfc03934522b8.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=a708cb53aa64034f0fcdc20e9fc17980/f7eb15ce36d3d5395af30a4d3b87e950342ab077.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=7a6533855ab5c9ea62f303ebe53bb622/efc9a786c9177f3e29f7f98371cf3bc79e3d5679.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=a3c9e88dc995d143da76e42b43f18296/6f0ed9f9d72a6059c443e5942934349b023bbaea.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=ee9dd7737a899e51788e3a1c72a6d990/c8256b600c338744309f2bf2500fd9f9d62aa0e3.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=3c24e0e6cdbf6c81f7372ce08c3fb1d7/b819367adab44aed8ed5ba6ab21c8701a08bfba2.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=37a42ca98b82b9013dadc33b438ca97e/ad12b07eca806538f48fa39d96dda144ac3482dc.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=18cbc2a13b292df597c3ac1d8c305ce2/47300a55b319ebc43b6071178326cffc1e171620.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=599e78acb21bb0518f24b3200678da77/9f45ad345982b2b7204b4d4a30adcbef77099b6d.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=70bdbebd9345d688a302b2ac94c37dab/36fb513d269759ee8e2d1745b3fb43166c22dfc4.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=8288e6b14afbfbeddc59367748f1f78e/3d3a5bb5c9ea15ceeef49787b7003af33a87b223.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=5bf14e8d8644ebf86d716437e9f8d736/823fb13533fa828b968fea6dfc1f4134960a5a94.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=0c3a8cad48540923aa696376a259d1dc/87004a90f603738d28fc7eacb21bb051f919ec8f.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=b9ca35b00df3d7ca0cf63f7ec21dbe3c/684f9258d109b3debd6a96e6cdbf6c81810a4c63.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=52196d93d52a283443a636036bb4c92e/a90b304e251f95cae388ef38c8177f3e6709523b.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=3ca90e9d08f79052ef1f47363cf2d738/f51249540923dd544a43dae6d009b3de9c824808.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=05fda1ee342ac65c6705667bcbf3b21d/c6ddd100baa1cd114df10faeb812c8fcc2ce2dfd.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=6b303b354610b912bfc1f6f6f3fcfcb5/b412632762d0f70337aee95209fa513d2697c525.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=2ec657a98b82b9013dadc33b438ca97e/ad12b07eca806538ededd89d96dda144ad34823e.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=bd1cdc74d0c8a786be2a4a065708c9c7/8698a9014c086e06859643c503087bf40ad1cb07.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=2c704569902397ddd679980c6983b216/ac44d688d43f8794ed8a34a0d31b0ef41ad53ac3.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=42e1458d8644ebf86d716437e9f8d736/823fb13533fa828b8f9fe16dfc1f4134960a5a84.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=fb5b3683279759ee4a5060c382fa434e/ce1e3a292df5e0fe6a84db8f5d6034a85fdf72a5.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=e86ba9a59c16fdfad86cc6e6848e8cea/9a0e4bfbfbedab644ccb1f4ef636afc378311e87.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=9e9ffaa8fcfaaf5184e381b7bc5594ed/75fafbedab64034f28749088aec379310b551d87.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=ef3cd96f2e2eb938ec6d7afae56085fe/a0500fb30f2442a762e8272bd043ad4bd013025f.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=f612834e83025aafd3327ec3cbecab8d/ea2b2834349b033b7cb4395414ce36d3d539bd05.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=1258b9ea0823dd542173a760e108b3df/7491f603738da977e05943a5b151f8198718e3c8.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=b2bf6795d50735fa91f04eb1ae500f9f/cc1ebe096b63f62472c7fc8d8644ebf81b4ca3a3.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=33e53c016d81800a6ee58906813433d6/087bdab44aed2e73696943a28601a18b86d6faba.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=c00943a28601a18bf0eb1247ae2d0761/92ae2edda3cc7cd9c6cdf1573801213fb90e9159.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=927fba532f738bd4c421b2399189876c/f5ee76094b36acaf661653727dd98d1000e99c4f.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=66690260b58f8c54e3d3c5270a282dee/3d4e78f0f736afc3b009fbebb219ebc4b745123c.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=e90ec8acb21bb0518f24b320067bda77/9f45ad345982b2b790dbfd4a30adcbef77099bfd.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=331550faac345982c58ae59a3cf5310b/b995a4c27d1ed21baa3cea6bac6eddc450da3f4c.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=56e2d9861e30e924cfa49c397c0a6e66/1f3eb80e7bec54e7673bde90b8389b504ec26a6e.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=cc0a533586d6277fe912323018391f63/9dcd7cd98d1001e9720ad381b90e7bec54e7970f.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=2e0417737a899e51788e3a1c72a5d990/c8256b600c338744f006ebf2500fd9f9d62aa07a.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=504292e7242dd42a5f0901a3333a5b2f/7f35970a304e251f12a22376a686c9177e3e53ec.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=a42ca911a50f4bfb8cd09e5c334e788f/0a9a033b5bb5c9ea33e0c56dd439b6003af3b32a.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=39fe414542166d223877159c76220945/82305c6034a85edfe1b438ad48540923dd547501.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=807d27b934fae6cd0cb4ab693fb20f9e/80086b63f6246b601b6574faeaf81a4c500fa2d2.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=bfb3f0855ab5c9ea62f303ebe538b622/efc9a786c9177f3eec213a8371cf3bc79f3d562c.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=9835385177094b36db921be593cd7c00/e3c551da81cb39db1f65a1d8d1160924aa18309c.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=07e91f461b4c510faec4e21250582528/0dfb828ba61ea8d37db2b58a960a304e241f58a9.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=358f41318d5494ee87220f111df4e0e1/46f1f736afc37931cc0446a7eac4b74542a911d5.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=7f2e51b14afbfbeddc59367748f1f78e/3d3a5bb5c9ea15ce13522087b7003af33b87b285.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=f87b4980b03533faf5b6932698d2fdca/b5d5b31c8701a18b6675d2c19f2f07082938fea0.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=95c5ccacb21bb0518f24b320067bda77/9f45ad345982b2b7ec10f94a30adcbef77099bb6.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=c103ff9aaa18972ba33a00c2d6cc7b9d/45ca0a46f21fbe097a76009a6a600c338744ad11.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=293cff4991529822053339cbe7cb7b3b/77550923dd54564efd4727b7b2de9c82d1584f1b.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=8a8c48b76a63f6241c5d390bb745eb32/f2be6c81800a19d8c4ad478b32fa828ba71e4697.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=c5790d4cb3119313c743ffb855390c10/7911b912c8fcc3ce55c70abd9345d688d43f203e.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=9ca91d7ab64543a9f51bfac42e168a7b/f85d10385343fbf29da165adb17eca8064388fb4.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=af58c225023b5bb5bed720f606d2d523/abcbd1c8a786c917f85291b7c83d70cf3ac757e8.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=43ffae503c6d55fbc5c6762e5d234f40/13f4e0fe9925bc313908c3165fdf8db1ca1370ec.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=55a84b8f5d6034a829e2b889fb1249d9/7da88226cffc1e17460f4ebf4b90f603728de98a.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=15d4b519d833c895a67e9873e1117397/244d510fd9f9d72a7aa9d293d52a2834359bbb74.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=464226e6cdbf6c81f7372ce08c3fb1d7/b819367adab44aedf4b37c6ab21c8701a08bfb45.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=6da166ef0eb30f24359aec0bf894d192/32328744ebf81a4c47272147d62a6059252da62c.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=4fa1f2c503087bf47dec57e1c2d2575e/71c3d5628535e5ddb525685177c6a7efce1b6230.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=395088713ac79f3d8fe1e4388aa0cdbc/45f50ad162d9f2d3a741e961a8ec8a136227ccea.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=131e281c0df431adbcd243317b37ac0f/30f51bd5ad6eddc4f073797538dbb6fd536633ad.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=0793b7f421a446237ecaa56aa8237246/60de8db1cb134954639225ea574e9258d0094ab5.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=079bb7f421a446237ecaa56aa8237246/60de8db1cb134954639a25ea574e9258d0094abd.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=06d44b609d82d158bb8259b9b00819d5/8e50f8198618367a0d69b2532f738bd4b21ce55a.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=449150c93812b31bc76ccd21b6193674/a9dca144ad34598285ab291c0df431adcbef8418.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=3d611c63e61190ef01fb92d7fe1a9df7/934ad11373f08202e2fb5db14afbfbedaa641bd0.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=e51c7d68267f9e2f70351d002f31e962/42d88d1001e9390165a842b07aec54e737d19693.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=1b7c903f810a19d8cb03840d03fb82c9/e4b54aed2e738bd464df7bbfa08b87d6267ff940.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=80c4a70bc8ea15ce41eee00186023a25/9987c9177f3e67094ac28c713ac79f3df9dc557b.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=3ee83e70c2fdfc03e578e3b0e43e87a9/af8ea0ec08fa513dd083a4503c6d55fbb2fbd911.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=79dd546dfc1f4134e0370576151e95c1/197e9e2f07082838c0f3159ab999a9014d08f140.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=8668bbaeb812c8fcb4f3f6c5cc0192b4/5d2662d0f703918f540ff444503d269758eec460.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=a1406895d50735fa91f04eb1ae500f9f/cc1ebe096b63f6246138f38d8644ebf81b4ca3dc.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=65ea09bd728da9774e2f86238050f872/32d6912397dda144824ea63cb3b7d0a20df486fe.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=a1e8d7956159252da3171d0c049a032c/c31e4134970a304e5d0e9575d0c8a786c9175c15.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=022c49eb0823dd542173a760e108b3df/7491f603738da977f02db3a4b151f8198718e3c4.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=4e717b4b0bd162d985ee621421dea950/bb34e5dde71190ef3abfa750cf1b9d16fcfa60fd.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=296f01563801213fcf334ed464e636f8/9519972bd40735fa42b27b369f510fb30e2408fb.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=208cca3f64380cd7e61ea2e59146ad14/fdfcfc039245d68844cd872ba5c27d1ed31b2476.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=ac81b826a8014c08193b28ad3a7a025b/6ae636d12f2eb938def54f7dd4628535e4dd6fa1.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=4371a9538b13632715edc23ba18ea056/f01a9d16fdfaaf51a170b4308d5494eef11f7aaa.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=fbb28bac622762d0803ea4b790ed0849/a317fdfaaf51f3dee6d18deb95eef01f3b2979da.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=29a9f1a03b292df597c3ac1d8c305ce2/47300a55b319ebc40a0242168326cffc1f1716c3.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=ef1e24a094cad1c8d0bbfc2f4f3f67c4/d725b899a9014c08b1561c2a0b7b02087af4f4d5.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=64a783bd5bafa40f3cc6ced59b65038c/1635349b033b5bb5debd147137d3d539b700bcd3.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=840cbab17aec54e741ec1a1689399bfd/0bfbe6cd7b899e51aa800d9b43a7d933c8950d37.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=c7b6a25309fa513d51aa6cd60d6c554c/b25594eef01f3a297bcce2419825bc315c607c3d.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=b7b2d786b7003af34dbadc68052bc619/f73c70cf3bc79f3d79bdd3bfbba1cd11738b29e5.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=c52aa550cf1b9d168ac79a69c3dcb4eb/64aea40f4bfbfbed188801f079f0f736aec31f68.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=95073312caef76093c0b99971edfa301/936fddc451da81cba028b4425366d01608243177.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=f5ef186aac6eddc426e7b4f309dab6a2/714b20a4462309f76b499b9d730e0cf3d7cad618.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=aefb827438dbb6fd255be52e3925aba6/ae539822720e0cf328eb78740b46f21fbe09aa26.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=c378aef4d01373f0f53f6f97940e4b8b/5e58252dd42a283426a000845ab5c9ea15cebf3f.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=7a589ea9fcfaaf5184e381b7bc5594ed/75fafbedab64034fccb3f489aec379310b551dc7.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=1142d2bfbba1cd1105b672288913c8b0/692d11dfa9ec8a138ab9616ff603918fa1ecc09b.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=7d615fdf35a85edffa8cfe2b795509d8/bc27cffc1e178a827851492ff703738da877e8d5.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=2583da46d62a60595210e1121835342d/96d2fd1f4134970a44c226a094cad1c8a6865d88.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=be5aeaef342ac65c6705667bcbf0b21d/c6ddd100baa1cd11f65644afb812c8fcc2ce2d59.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=9bc33512caef76093c0b99971edca301/936fddc451da81cbaeecb2425366d01609243133.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=222ed0808694a4c20a23e7233ef51bac/67ef3d6d55fbb2fbb7b0699d4e4a20a44723dca3.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=e31989af00e9390156028d364bed54f9/3725ab18972bd407aa3ae2727a899e510eb30944.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=d0d4a8102fdda3cc0be4b82831eb3905/07dab6fd5266d01692c6afa7962bd40734fa3566.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=79dc818ae4dde711e7d243fe97eecef4/ef42ad4bd11373f02ebc5e10a50f4bfbfaed04ba.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=45257e4b0bd162d985ee621421dea950/bb34e5dde71190ef31eba250cf1b9d16fdfa6029.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=431115875243fbf2c52ca62b807fca1e/f310728b4710b9124db1c671c2fdfc03934522c9.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=9e4d62b6c83d70cf4cfaaa05c8ddd1ba/347a02087bf40ad183aaf76c562c11dfa8eccef0.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=4d261167bd3eb13544c7b7b3961fa8cb/10728bd4b31c87016ca78f69267f9e2f0708ff29.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=0a2041eb0823dd542173a760e108b3df/7491f603738da977f821bba4b151f8198618e330.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=cdc3469310dfa9ecfd2e561f52d1f754/48c7a7efce1b9d16c2eabeeef2deb48f8c546414.jpg",
            "http://imgsrc.baidu.com/forum/w%3D580/sign=8c9786b5314e251fe2f7e4f09787c9c2/16391f30e92
Download .txt
gitextract_oil8rr72/

├── .github/
│   └── issue_template.md
├── .gitignore
├── .idea/
│   ├── codeStyleSettings.xml
│   ├── codeStyles/
│   │   ├── Project.xml
│   │   └── codeStyleConfig.xml
│   ├── compiler.xml
│   ├── copyright/
│   │   ├── apache2.xml
│   │   └── profiles_settings.xml
│   ├── dictionaries/
│   │   └── Jacksgong.xml
│   ├── encodings.xml
│   ├── gradle.xml
│   ├── inspectionProfiles/
│   │   ├── Project_Default.xml
│   │   └── profiles_settings.xml
│   ├── modules.xml
│   ├── runConfigurations.xml
│   └── vcs.xml
├── .travis.yml
├── CHANGELOG-ZH.md
├── CHANGELOG.md
├── LICENSE.txt
├── README-zh.md
├── README.md
├── build.gradle
├── checkstyle.xml
├── demo/
│   ├── .gitignore
│   ├── build.gradle
│   ├── filedownloaderdemo.jks
│   ├── proguard-rules.pro
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           ├── assets/
│           │   ├── filedownloader.properties
│           │   └── performance_test_data
│           ├── java/
│           │   └── com/
│           │       └── liulishuo/
│           │           └── filedownloader/
│           │               └── demo/
│           │                   ├── Constant.java
│           │                   ├── DemoApplication.java
│           │                   ├── GlobalMonitor.java
│           │                   ├── HybridTestActivity.java
│           │                   ├── MainActivity.java
│           │                   ├── MultitaskTestActivity.java
│           │                   ├── NotificationSampleActivity.java
│           │                   ├── SingleTaskTestActivity.java
│           │                   ├── TasksManagerDemoActivity.java
│           │                   ├── Utils.java
│           │                   └── performance/
│           │                       ├── IntParcel.java
│           │                       ├── LongParcel.java
│           │                       └── PerformanceTestActivity.java
│           └── res/
│               ├── drawable/
│               │   └── bg_item_task_manager.xml
│               ├── layout/
│               │   ├── activity_hybrid_test.xml
│               │   ├── activity_main.xml
│               │   ├── activity_mutitask_test.xml
│               │   ├── activity_notification_minset.xml
│               │   ├── activity_notification_sample.xml
│               │   ├── activity_performance.xml
│               │   ├── activity_single.xml
│               │   ├── activity_tasks_manager_demo.xml
│               │   └── item_tasks_manager.xml
│               ├── menu/
│               │   └── menu_main.xml
│               ├── values/
│               │   ├── colors.xml
│               │   ├── donottranslate.xml
│               │   ├── strings.xml
│               │   └── styles.xml
│               ├── values-zh/
│               │   └── strings.xml
│               └── xml/
│                   └── network_security_config.xml
├── gradle/
│   ├── bintray.gradle
│   ├── mvn-local.gradle
│   ├── mvn-push.gradle
│   └── wrapper/
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── install.sh
├── library/
│   ├── .gitignore
│   ├── LICENSE
│   ├── build.gradle
│   ├── gradle.properties
│   ├── proguard-rules.pro
│   └── src/
│       ├── main/
│       │   ├── AndroidManifest.xml
│       │   ├── aidl/
│       │   │   └── com/
│       │   │       └── liulishuo/
│       │   │           └── filedownloader/
│       │   │               ├── i/
│       │   │               │   ├── IFileDownloadIPCCallback.aidl
│       │   │               │   └── IFileDownloadIPCService.aidl
│       │   │               ├── message/
│       │   │               │   └── MessageSnapshot.aidl
│       │   │               └── model/
│       │   │                   ├── FileDownloadHeader.aidl
│       │   │                   └── FileDownloadTaskAtom.aidl
│       │   ├── java/
│       │   │   └── com/
│       │   │       └── liulishuo/
│       │   │           └── filedownloader/
│       │   │               ├── BaseDownloadTask.java
│       │   │               ├── DownloadSpeedMonitor.java
│       │   │               ├── DownloadTask.java
│       │   │               ├── DownloadTaskHunter.java
│       │   │               ├── FileDownloadConnectListener.java
│       │   │               ├── FileDownloadEventPool.java
│       │   │               ├── FileDownloadLargeFileListener.java
│       │   │               ├── FileDownloadLine.java
│       │   │               ├── FileDownloadLineAsync.java
│       │   │               ├── FileDownloadList.java
│       │   │               ├── FileDownloadListener.java
│       │   │               ├── FileDownloadMessageStation.java
│       │   │               ├── FileDownloadMessenger.java
│       │   │               ├── FileDownloadMonitor.java
│       │   │               ├── FileDownloadQueueSet.java
│       │   │               ├── FileDownloadSampleListener.java
│       │   │               ├── FileDownloadServiceProxy.java
│       │   │               ├── FileDownloadServiceSharedTransmit.java
│       │   │               ├── FileDownloadServiceUIGuard.java
│       │   │               ├── FileDownloadTaskLauncher.java
│       │   │               ├── FileDownloader.java
│       │   │               ├── IDownloadSpeed.java
│       │   │               ├── IFileDownloadMessenger.java
│       │   │               ├── IFileDownloadServiceProxy.java
│       │   │               ├── ILostServiceConnectedHandler.java
│       │   │               ├── IQueuesHandler.java
│       │   │               ├── ITaskHunter.java
│       │   │               ├── IThreadPoolMonitor.java
│       │   │               ├── LostServiceConnectedHandler.java
│       │   │               ├── MessageSnapshotGate.java
│       │   │               ├── PauseAllMarker.java
│       │   │               ├── QueuesHandler.java
│       │   │               ├── connection/
│       │   │               │   ├── DefaultConnectionCountAdapter.java
│       │   │               │   ├── FileDownloadConnection.java
│       │   │               │   ├── FileDownloadUrlConnection.java
│       │   │               │   └── RedirectHandler.java
│       │   │               ├── database/
│       │   │               │   ├── FileDownloadDatabase.java
│       │   │               │   ├── NoDatabaseImpl.java
│       │   │               │   ├── RemitDatabase.java
│       │   │               │   ├── SqliteDatabaseImpl.java
│       │   │               │   └── SqliteDatabaseOpenHelper.java
│       │   │               ├── download/
│       │   │               │   ├── ConnectTask.java
│       │   │               │   ├── ConnectionProfile.java
│       │   │               │   ├── CustomComponentHolder.java
│       │   │               │   ├── DownloadLaunchRunnable.java
│       │   │               │   ├── DownloadRunnable.java
│       │   │               │   ├── DownloadStatusCallback.java
│       │   │               │   ├── FetchDataTask.java
│       │   │               │   └── ProcessCallback.java
│       │   │               ├── event/
│       │   │               │   ├── DownloadEventPoolImpl.java
│       │   │               │   ├── DownloadEventSampleListener.java
│       │   │               │   ├── DownloadServiceConnectChangedEvent.java
│       │   │               │   ├── IDownloadEvent.java
│       │   │               │   ├── IDownloadEventPool.java
│       │   │               │   └── IDownloadListener.java
│       │   │               ├── exception/
│       │   │               │   ├── FileDownloadGiveUpRetryException.java
│       │   │               │   ├── FileDownloadHttpException.java
│       │   │               │   ├── FileDownloadNetworkPolicyException.java
│       │   │               │   ├── FileDownloadOutOfSpaceException.java
│       │   │               │   ├── FileDownloadSecurityException.java
│       │   │               │   └── PathConflictException.java
│       │   │               ├── message/
│       │   │               │   ├── BlockCompleteMessage.java
│       │   │               │   ├── IFlowDirectly.java
│       │   │               │   ├── IMessageSnapshot.java
│       │   │               │   ├── LargeMessageSnapshot.java
│       │   │               │   ├── MessageSnapshot.java
│       │   │               │   ├── MessageSnapshotFlow.java
│       │   │               │   ├── MessageSnapshotTaker.java
│       │   │               │   ├── MessageSnapshotThreadPool.java
│       │   │               │   └── SmallMessageSnapshot.java
│       │   │               ├── model/
│       │   │               │   ├── ConnectionModel.java
│       │   │               │   ├── FileDownloadHeader.java
│       │   │               │   ├── FileDownloadModel.java
│       │   │               │   ├── FileDownloadStatus.java
│       │   │               │   └── FileDownloadTaskAtom.java
│       │   │               ├── notification/
│       │   │               │   ├── BaseNotificationItem.java
│       │   │               │   ├── FileDownloadNotificationHelper.java
│       │   │               │   └── FileDownloadNotificationListener.java
│       │   │               ├── services/
│       │   │               │   ├── BaseFileServiceUIGuard.java
│       │   │               │   ├── DefaultIdGenerator.java
│       │   │               │   ├── DownloadMgrInitialParams.java
│       │   │               │   ├── FDServiceSeparateHandler.java
│       │   │               │   ├── FDServiceSharedHandler.java
│       │   │               │   ├── FileDownloadBroadcastHandler.java
│       │   │               │   ├── FileDownloadManager.java
│       │   │               │   ├── FileDownloadService.java
│       │   │               │   ├── FileDownloadThreadPool.java
│       │   │               │   ├── ForegroundServiceConfig.java
│       │   │               │   └── IFileDownloadServiceHandler.java
│       │   │               ├── stream/
│       │   │               │   ├── FileDownloadOutputStream.java
│       │   │               │   └── FileDownloadRandomAccessFile.java
│       │   │               └── util/
│       │   │                   ├── DownloadServiceNotConnectedHelper.java
│       │   │                   ├── ExtraKeys.java
│       │   │                   ├── FileDownloadExecutors.java
│       │   │                   ├── FileDownloadHelper.java
│       │   │                   ├── FileDownloadLog.java
│       │   │                   ├── FileDownloadProperties.java
│       │   │                   ├── FileDownloadSerialQueue.java
│       │   │                   └── FileDownloadUtils.java
│       │   └── res/
│       │       └── values/
│       │           └── strings.xml
│       └── test/
│           ├── java/
│           │   └── com/
│           │       └── liulishuo/
│           │           └── filedownloader/
│           │               ├── FileDownloaderTest.java
│           │               ├── connection/
│           │               │   └── FileDownloadUrlConnectionTest.java
│           │               ├── download/
│           │               │   ├── DownloadLaunchRunnableTest.java
│           │               │   └── DownloadRunnableTest.java
│           │               └── util/
│           │                   └── FileDownloadUtilsTest.java
│           └── resources/
│               └── mockito-extensions/
│                   └── org.mockito.plugins.MockMaker
├── okcat.yml
└── settings.gradle
Download .txt
SYMBOL INDEX (1854 symbols across 117 files)

FILE: demo/src/main/java/com/liulishuo/filedownloader/demo/Constant.java
  type Constant (line 6) | public interface Constant {

FILE: demo/src/main/java/com/liulishuo/filedownloader/demo/DemoApplication.java
  class DemoApplication (line 19) | public class DemoApplication extends Application {
    method onCreate (line 23) | @Override

FILE: demo/src/main/java/com/liulishuo/filedownloader/demo/GlobalMonitor.java
  class GlobalMonitor (line 28) | public class GlobalMonitor implements FileDownloadMonitor.IMonitor {
    class HolderClass (line 32) | private final static class HolderClass {
    method getImpl (line 36) | public static GlobalMonitor getImpl() {
    method onRequestStart (line 42) | @Override
    method onRequestStart (line 49) | @Override
    method onTaskBegin (line 53) | @Override
    method onTaskStarted (line 58) | @Override
    method onTaskOver (line 63) | @Override
    method getMarkStart (line 68) | public int getMarkStart() {
    method getMarkOver (line 72) | public int getMarkOver() {

FILE: demo/src/main/java/com/liulishuo/filedownloader/demo/HybridTestActivity.java
  class HybridTestActivity (line 28) | public class HybridTestActivity extends AppCompatActivity {
    method onCreate (line 34) | @Override
    method onClickDel (line 71) | public void onClickDel(final View view) {
    method onClickStartSingleDownload (line 108) | public void onClickStartSingleDownload(final View view) {
    method onClickMultiParallel (line 124) | public void onClickMultiParallel(final View view) {
    method onClickMultiSerial (line 150) | public void onClickMultiSerial(final View view) {
    method createListener (line 169) | private FileDownloadListener createListener() {
    method updateDisplay (line 248) | private void updateDisplay(final CharSequence msg) {
    method run (line 260) | @Override
    method onDestroy (line 268) | @Override
    method assignViews (line 279) | private void assignViews() {

FILE: demo/src/main/java/com/liulishuo/filedownloader/demo/MainActivity.java
  class MainActivity (line 18) | public class MainActivity extends AppCompatActivity {
    method onCreate (line 20) | @Override
    method onClickMultitask (line 36) | public void onClickMultitask(final View view) {
    method onClickSingle (line 40) | public void onClickSingle(final View view) {
    method onClickHybridTest (line 44) | public void onClickHybridTest(final View view) {
    method onClickTasksManager (line 48) | public void onClickTasksManager(final View view) {
    method onClickPerformance (line 52) | public void onClickPerformance(final View view) {
    method onClickNotification (line 56) | public void onClickNotification(final View view){
    method onCreateOptionsMenu (line 60) | @Override
    method onOptionsItemSelected (line 67) | @Override
    method openGitHub (line 78) | private void openGitHub() {
    method onDestroy (line 84) | @Override

FILE: demo/src/main/java/com/liulishuo/filedownloader/demo/MultitaskTestActivity.java
  class MultitaskTestActivity (line 46) | public class MultitaskTestActivity extends AppCompatActivity {
    method onDestroy (line 50) | @Override
    method onCreate (line 56) | @Override
    method resetDisplayData (line 144) | private void resetDisplayData() {
    method start (line 179) | private boolean start() {
    method pause (line 267) | private void pause() {
    method stopTimeCount (line 273) | private void stopTimeCount() {
    method createLis (line 286) | private FileDownloadListener createLis() {
    method checkEndAll (line 413) | private void checkEndAll() {
    method goTimeCount (line 429) | private void goTimeCount() {
    method run (line 439) | @Override
    method assignViews (line 487) | private void assignViews() {

FILE: demo/src/main/java/com/liulishuo/filedownloader/demo/NotificationSampleActivity.java
  class NotificationSampleActivity (line 50) | public class NotificationSampleActivity extends AppCompatActivity {
    method onCreate (line 59) | @Override
    method onClickStart (line 71) | public void onClickStart(final View view) {
    method onClickPause (line 105) | public void onClickPause(final View view) {
    method onClickDelete (line 109) | @SuppressWarnings("ResultOfMethodCallIgnored")
    class NotificationListener (line 129) | private static class NotificationListener extends FileDownloadNotifica...
      method NotificationListener (line 134) | public NotificationListener(
      method create (line 143) | @Override
      method addNotificationItem (line 153) | @Override
      method destroyNotification (line 161) | @Override
      method interceptCancel (line 169) | @Override
      method disableNotification (line 177) | @Override
    class NotificationItem (line 187) | public static class NotificationItem extends BaseNotificationItem {
      method NotificationItem (line 191) | private NotificationItem(int id, String title, String desc, String c...
      method show (line 218) | @Override
    method onDestroy (line 261) | @Override
    method assignViews (line 272) | private void assignViews() {

FILE: demo/src/main/java/com/liulishuo/filedownloader/demo/SingleTaskTestActivity.java
  class SingleTaskTestActivity (line 22) | public class SingleTaskTestActivity extends AppCompatActivity {
    method onCreate (line 24) | @Override
    method initFilePathEqualDirAndFileName (line 46) | private void initFilePathEqualDirAndFileName() {
    method initNormalDataAction (line 94) | private void initNormalDataAction() {
    method initChunkTransferEncodingDataAction (line 120) | private void initChunkTransferEncodingDataAction() {
    method onDestroy (line 145) | @Override
    method createDownloadTask (line 152) | private BaseDownloadTask createDownloadTask(final int position) {
    class ViewHolder (line 237) | private static class ViewHolder {
      method ViewHolder (line 246) | public ViewHolder(WeakReference<SingleTaskTestActivity> weakReferenc...
      method setFilenameTv (line 256) | public void setFilenameTv(TextView filenameTv) {
      method updateSpeed (line 260) | private void updateSpeed(int speed) {
      method updateProgress (line 264) | public void updateProgress(final int sofar, final int total, final i...
      method updatePending (line 280) | public void updatePending(BaseDownloadTask task) {
      method updatePaused (line 286) | public void updatePaused(final int speed) {
      method updateConnected (line 292) | public void updateConnected(String etag, String filename) {
      method updateWarn (line 298) | public void updateWarn() {
      method updateError (line 303) | public void updateError(final Throwable ex, final int speed) {
      method updateCompleted (line 310) | public void updateCompleted(final BaseDownloadTask task) {
      method toast (line 325) | private void toast(final String msg) {
    method assignViews (line 368) | private void assignViews() {

FILE: demo/src/main/java/com/liulishuo/filedownloader/demo/TasksManagerDemoActivity.java
  class TasksManagerDemoActivity (line 53) | public class TasksManagerDemoActivity extends AppCompatActivity {
    method onCreate (line 57) | @Override
    method postNotifyDataChanged (line 71) | public void postNotifyDataChanged() {
    method onDestroy (line 84) | @Override
    class TaskItemViewHolder (line 95) | private static class TaskItemViewHolder extends RecyclerView.ViewHolder {
      method TaskItemViewHolder (line 96) | public TaskItemViewHolder(View itemView) {
      method findViewById (line 101) | private View findViewById(final int id) {
      method update (line 114) | public void update(final int id, final int position) {
      method updateDownloaded (line 120) | public void updateDownloaded() {
      method updateNotDownloaded (line 128) | public void updateNotDownloaded(final int status, final long sofar, ...
      method updateDownloading (line 153) | public void updateDownloading(final int status, final long sofar, fi...
      method assignViews (line 186) | private void assignViews() {
    class TaskItemAdapter (line 195) | private static class TaskItemAdapter extends RecyclerView.Adapter<Task...
      method checkCurrentHolder (line 199) | private TaskItemViewHolder checkCurrentHolder(final BaseDownloadTask...
      method pending (line 208) | @Override
      method started (line 221) | @Override
      method connected (line 232) | @Override
      method progress (line 245) | @Override
      method error (line 257) | @Override
      method paused (line 270) | @Override
      method completed (line 283) | @Override
      method onClick (line 296) | @Override
      method onCreateViewHolder (line 333) | @Override
      method onBindViewHolder (line 344) | @Override
      method getItemCount (line 387) | @Override
    class TasksManager (line 396) | public static class TasksManager {
      class HolderClass (line 397) | private final static class HolderClass {
      method getImpl (line 402) | public static TasksManager getImpl() {
      method TasksManager (line 409) | private TasksManager() {
      method initDemo (line 416) | private void initDemo() {
      method addTaskForViewHolder (line 428) | public void addTaskForViewHolder(final BaseDownloadTask task) {
      method removeTaskForViewHolder (line 432) | public void removeTaskForViewHolder(final int id) {
      method updateViewHolder (line 436) | public void updateViewHolder(final int id, final TaskItemViewHolder ...
      method releaseTask (line 445) | public void releaseTask() {
      method registerServiceConnectionListener (line 451) | private void registerServiceConnectionListener(final WeakReference<T...
      method unregisterServiceConnectionListener (line 483) | private void unregisterServiceConnectionListener() {
      method onCreate (line 488) | public void onCreate(final WeakReference<TasksManagerDemoActivity> a...
      method onDestroy (line 495) | public void onDestroy() {
      method isReady (line 500) | public boolean isReady() {
      method get (line 504) | public TasksManagerModel get(final int position) {
      method getById (line 508) | public TasksManagerModel getById(final int id) {
      method isDownloaded (line 523) | public boolean isDownloaded(final int status) {
      method getStatus (line 527) | public int getStatus(final int id, String path) {
      method getTotal (line 531) | public long getTotal(final int id) {
      method getSoFar (line 535) | public long getSoFar(final int id) {
      method getTaskCounts (line 539) | public int getTaskCounts() {
      method addTask (line 543) | public TasksManagerModel addTask(final String url) {
      method addTask (line 547) | public TasksManagerModel addTask(final String url, final String path) {
      method createPath (line 565) | public String createPath(final String url) {
    class TasksManagerDBController (line 574) | private static class TasksManagerDBController {
      method TasksManagerDBController (line 578) | private TasksManagerDBController() {
      method getAllTasks (line 584) | public List<TasksManagerModel> getAllTasks() {
      method addTask (line 610) | public TasksManagerModel addTask(final String url, final String path) {
    class TasksManagerDBOpenHelper (line 632) | private static class TasksManagerDBOpenHelper extends SQLiteOpenHelper {
      method TasksManagerDBOpenHelper (line 636) | public TasksManagerDBOpenHelper(Context context) {
      method onCreate (line 641) | @Override
      method onUpgrade (line 660) | @Override
    class TasksManagerModel (line 668) | private static class TasksManagerModel {
      method getId (line 679) | public int getId() {
      method setId (line 683) | public void setId(int id) {
      method getName (line 687) | public String getName() {
      method setName (line 691) | public void setName(String name) {
      method getUrl (line 695) | public String getUrl() {
      method setUrl (line 699) | public void setUrl(String url) {
      method getPath (line 703) | public String getPath() {
      method setPath (line 707) | public void setPath(String path) {
      method toContentValues (line 711) | public ContentValues toContentValues() {

FILE: demo/src/main/java/com/liulishuo/filedownloader/demo/Utils.java
  class Utils (line 25) | public class Utils {
    method createNotificationChannel (line 26) | public static void createNotificationChannel(
    method deleteNotificationChannel (line 42) | public static void deleteNotificationChannel(String channelId, Context...
    method getNotificationManager (line 50) | @Nullable

FILE: demo/src/main/java/com/liulishuo/filedownloader/demo/performance/IntParcel.java
  class IntParcel (line 25) | public class IntParcel implements Parcelable {
    method operate (line 32) | public void operate() {
    method describeContents (line 38) | @Override
    method writeToParcel (line 43) | @Override
    method IntParcel (line 50) | public IntParcel() {
    method IntParcel (line 53) | protected IntParcel(Parcel in) {
    method createFromParcel (line 60) | public IntParcel createFromParcel(Parcel source) {
    method newArray (line 64) | public IntParcel[] newArray(int size) {

FILE: demo/src/main/java/com/liulishuo/filedownloader/demo/performance/LongParcel.java
  class LongParcel (line 25) | public class LongParcel implements Parcelable {
    method operate (line 31) | public void operate() {
    method describeContents (line 37) | @Override
    method writeToParcel (line 42) | @Override
    method LongParcel (line 49) | public LongParcel() {
    method LongParcel (line 52) | protected LongParcel(Parcel in) {
    method createFromParcel (line 59) | public LongParcel createFromParcel(Parcel source) {
    method newArray (line 63) | public LongParcel[] newArray(int size) {

FILE: demo/src/main/java/com/liulishuo/filedownloader/demo/performance/PerformanceTestActivity.java
  class PerformanceTestActivity (line 47) | public class PerformanceTestActivity extends AppCompatActivity {
    method onCreate (line 51) | @Override
    method onClickLongOperate (line 58) | public void onClickLongOperate(final View view) {
    method onClickLongParcel (line 69) | public void onClickLongParcel(final View view) {
    method onClickIntOperate (line 82) | public void onClickIntOperate(final View view) {
    method onClickIntParcel (line 93) | public void onClickIntParcel(final View view) {
    method onClickWriteTest (line 112) | public void onClickWriteTest(final View view) {
    method initPerformanceTest (line 316) | private InputStream initPerformanceTest() {
    method infoAppend (line 330) | private void infoAppend(final String msg, final long start) {
    method assignViews (line 346) | private void assignViews() {

FILE: library/src/main/java/com/liulishuo/filedownloader/BaseDownloadTask.java
  type BaseDownloadTask (line 30) | @SuppressWarnings({"WeakerAccess", "UnusedReturnValue"})
    method setMinIntervalUpdateSpeed (line 44) | BaseDownloadTask setMinIntervalUpdateSpeed(int minIntervalUpdateSpeedMs);
    method setPath (line 50) | BaseDownloadTask setPath(final String path);
    method setPath (line 64) | BaseDownloadTask setPath(final String path, final boolean pathAsDirect...
    method setListener (line 70) | BaseDownloadTask setListener(final FileDownloadListener listener);
    method setCallbackProgressTimes (line 89) | BaseDownloadTask setCallbackProgressTimes(int callbackProgressCount);
    method setCallbackProgressMinInterval (line 106) | BaseDownloadTask setCallbackProgressMinInterval(int minIntervalMillis);
    method setCallbackProgressIgnored (line 112) | BaseDownloadTask setCallbackProgressIgnored();
    method setTag (line 117) | BaseDownloadTask setTag(final Object tag);
    method setTag (line 126) | BaseDownloadTask setTag(final int key, final Object tag);
    method setForceReDownload (line 136) | BaseDownloadTask setForceReDownload(final boolean isForceReDownload);
    method setFinishListener (line 141) | BaseDownloadTask setFinishListener(final FinishListener finishListener);
    method addFinishListener (line 152) | BaseDownloadTask addFinishListener(final FinishListener finishListener);
    method removeFinishListener (line 161) | boolean removeFinishListener(final FinishListener finishListener);
    method setAutoRetryTimes (line 169) | BaseDownloadTask setAutoRetryTimes(int autoRetryTimes);
    method addHeader (line 178) | BaseDownloadTask addHeader(final String name, final String value);
    method addHeader (line 183) | BaseDownloadTask addHeader(final String line);
    method removeAllHeaders (line 188) | BaseDownloadTask removeAllHeaders(final String name);
    method setSyncCallback (line 195) | BaseDownloadTask setSyncCallback(final boolean syncCallback);
    method setWifiRequired (line 211) | BaseDownloadTask setWifiRequired(final boolean isWifiRequired);
    method ready (line 232) | int ready();
    method asInQueueTask (line 244) | InQueueTask asInQueueTask();
    method reuse (line 255) | boolean reuse();
    method isUsing (line 265) | boolean isUsing();
    method isRunning (line 274) | boolean isRunning();
    method isAttached (line 285) | @SuppressWarnings("BooleanMethodIsAlwaysInverted")
    method start (line 293) | int start();
    method pause (line 309) | boolean pause();
    method cancel (line 318) | boolean cancel();
    method getId (line 332) | int getId();
    method getDownloadId (line 338) | int getDownloadId();
    method getUrl (line 343) | String getUrl();
    method getCallbackProgressTimes (line 350) | int getCallbackProgressTimes();
    method getCallbackProgressMinInterval (line 356) | int getCallbackProgressMinInterval();
    method getPath (line 365) | String getPath();
    method isPathAsDirectory (line 371) | boolean isPathAsDirectory();
    method getFilename (line 383) | String getFilename();
    method getTargetFilePath (line 388) | String getTargetFilePath();
    method getListener (line 393) | FileDownloadListener getListener();
    method getSoFarBytes (line 399) | int getSoFarBytes();
    method getSmallFileSoFarBytes (line 406) | int getSmallFileSoFarBytes();
    method getLargeFileSoFarBytes (line 413) | long getLargeFileSoFarBytes();
    method getTotalBytes (line 423) | int getTotalBytes();
    method getSmallFileTotalBytes (line 430) | int getSmallFileTotalBytes();
    method getLargeFileTotalBytes (line 437) | long getLargeFileTotalBytes();
    method getSpeed (line 453) | int getSpeed();
    method getStatus (line 459) | byte getStatus();
    method isForceReDownload (line 465) | boolean isForceReDownload();
    method getEx (line 470) | Throwable getEx();
    method getErrorCause (line 475) | Throwable getErrorCause();
    method isReusedOldFile (line 483) | boolean isReusedOldFile();
    method getTag (line 488) | Object getTag();
    method getTag (line 499) | Object getTag(int key);
    method isContinue (line 505) | boolean isContinue();
    method isResuming (line 511) | boolean isResuming();
    method getEtag (line 517) | String getEtag();
    method getAutoRetryTimes (line 523) | int getAutoRetryTimes();
    method getRetryingTimes (line 529) | int getRetryingTimes();
    method isSyncCallback (line 538) | boolean isSyncCallback();
    method isLargeFile (line 545) | boolean isLargeFile();
    method isWifiRequired (line 551) | boolean isWifiRequired();
    type InQueueTask (line 556) | interface InQueueTask {
      method enqueue (line 566) | int enqueue();
    type FinishListener (line 569) | @SuppressWarnings("UnusedParameters")
      method over (line 581) | void over(final BaseDownloadTask task);
    type IRunningTask (line 589) | interface IRunningTask {
      method getOrigin (line 593) | BaseDownloadTask getOrigin();
      method getMessageHandler (line 598) | ITaskHunter.IMessageHandler getMessageHandler();
      method is (line 603) | boolean is(int id);
      method is (line 608) | boolean is(FileDownloadListener listener);
      method isOver (line 613) | @SuppressWarnings("BooleanMethodIsAlwaysInverted")
      method getAttachKey (line 624) | int getAttachKey();
      method setAttachKeyByQueue (line 632) | void setAttachKeyByQueue(int key);
      method setAttachKeyDefault (line 638) | void setAttachKeyDefault();
      method isMarkedAdded2List (line 643) | boolean isMarkedAdded2List();
      method markAdded2List (line 648) | void markAdded2List();
      method free (line 653) | void free();
      method startTaskByQueue (line 658) | void startTaskByQueue();
      method startTaskByRescue (line 666) | void startTaskByRescue();
      method getPauseLock (line 673) | Object getPauseLock();
      method isContainFinishListener (line 680) | boolean isContainFinishListener();
    type LifeCycleCallback (line 686) | interface LifeCycleCallback {
      method onBegin (line 690) | void onBegin();
      method onIng (line 696) | void onIng();
      method onOver (line 701) | void onOver();

FILE: library/src/main/java/com/liulishuo/filedownloader/DownloadSpeedMonitor.java
  class DownloadSpeedMonitor (line 25) | public class DownloadSpeedMonitor implements IDownloadSpeed.Monitor, IDo...
    method start (line 39) | @Override
    method end (line 45) | @Override
    method update (line 61) | @Override
    method reset (line 90) | @Override
    method getSpeed (line 96) | @Override
    method setMinIntervalUpdateSpeed (line 101) | @Override

FILE: library/src/main/java/com/liulishuo/filedownloader/DownloadTask.java
  class DownloadTask (line 35) | public class DownloadTask implements BaseDownloadTask, BaseDownloadTask....
    method DownloadTask (line 76) | DownloadTask(final String url) {
    method setMinIntervalUpdateSpeed (line 85) | @Override
    method setPath (line 91) | @Override
    method setPath (line 96) | @Override
    method setListener (line 117) | @Override
    method setCallbackProgressTimes (line 127) | @Override
    method setCallbackProgressMinInterval (line 133) | @Override
    method setCallbackProgressIgnored (line 139) | @Override
    method setTag (line 144) | @Override
    method setTag (line 153) | @Override
    method setForceReDownload (line 162) | @Override
    method setFinishListener (line 168) | @Override
    method addFinishListener (line 175) | @Override
    method removeFinishListener (line 188) | @Override
    method setAutoRetryTimes (line 193) | @Override
    method addHeader (line 199) | @Override
    method addHeader (line 206) | @Override
    method removeAllHeaders (line 213) | @Override
    method setSyncCallback (line 229) | @Override
    method setWifiRequired (line 235) | @Override
    method ready (line 241) | @Override
    method asInQueueTask (line 246) | @Override
    method reuse (line 251) | @Override
    method isUsing (line 267) | @Override
    method isRunning (line 273) | @Override
    method isAttached (line 283) | @Override
    method start (line 288) | @Override
    method startTaskUnchecked (line 311) | private int startTaskUnchecked() {
    method pause (line 338) | @Override
    method cancel (line 345) | @Override
    method getId (line 352) | @Override
    method getDownloadId (line 368) | @Override
    method getUrl (line 373) | @Override
    method getCallbackProgressTimes (line 378) | @Override
    method getCallbackProgressMinInterval (line 383) | @Override
    method getPath (line 388) | @Override
    method isPathAsDirectory (line 393) | @Override
    method getFilename (line 398) | @Override
    method getTargetFilePath (line 403) | @Override
    method getListener (line 408) | @Override
    method getSoFarBytes (line 413) | @Override
    method getSmallFileSoFarBytes (line 418) | @Override
    method getLargeFileSoFarBytes (line 426) | @Override
    method getTotalBytes (line 431) | @Override
    method getSmallFileTotalBytes (line 436) | @Override
    method getLargeFileTotalBytes (line 445) | @Override
    method getSpeed (line 450) | @Override
    method getStatus (line 455) | @Override
    method isForceReDownload (line 460) | @Override
    method getEx (line 465) | @Override
    method getErrorCause (line 470) | @Override
    method isReusedOldFile (line 475) | @Override
    method getTag (line 480) | @Override
    method getTag (line 485) | @Override
    method isContinue (line 494) | @Override
    method isResuming (line 499) | @Override
    method getEtag (line 504) | @Override
    method getAutoRetryTimes (line 509) | @Override
    method getRetryingTimes (line 514) | @Override
    method isSyncCallback (line 519) | @Override
    method isLargeFile (line 524) | @Override
    method isWifiRequired (line 529) | @Override
    method checkAndCreateHeader (line 536) | private void checkAndCreateHeader() {
    method getHeader (line 546) | @Override
    method markAdded2List (line 558) | @Override
    method free (line 563) | @Override
    method startTaskByQueue (line 571) | @Override
    method startTaskByRescue (line 576) | @Override
    method getPauseLock (line 584) | @Override
    method isContainFinishListener (line 589) | @Override
    method isMarkedAdded2List (line 595) | @Override
    method getRunningTask (line 600) | @Override
    method setFileName (line 605) | @Override
    method getFinishListenerList (line 610) | @Override
    method getOrigin (line 615) | @Override
    method getMessageHandler (line 620) | @Override
    method is (line 625) | @Override
    method is (line 630) | @Override
    method isOver (line 635) | @Override
    method getAttachKey (line 640) | @Override
    method setAttachKeyByQueue (line 645) | @Override
    method setAttachKeyDefault (line 650) | @Override
    method toString (line 661) | @Override
    class InQueueTaskImpl (line 666) | private static final class InQueueTaskImpl implements InQueueTask {
      method InQueueTaskImpl (line 669) | private InQueueTaskImpl(DownloadTask task) {
      method enqueue (line 674) | @Override

FILE: library/src/main/java/com/liulishuo/filedownloader/DownloadTaskHunter.java
  class DownloadTaskHunter (line 36) | public class DownloadTaskHunter implements ITaskHunter, ITaskHunter.ISta...
    method updateKeepAhead (line 43) | @Override
    method updateKeepFlow (line 57) | @Override
    method updateMoreLikelyCompleted (line 89) | @Override
    method updateSameFilePathTaskRunning (line 99) | @Override
    method getMessenger (line 114) | @Override
    method prepareErrorMessage (line 119) | @Override
    method update (line 126) | @SuppressWarnings("checkstyle:emptyblock")
    method onBegin (line 264) | @Override
    method onIng (line 276) | @Override
    method onOver (line 283) | @Override
    type ICaptureTask (line 311) | interface ICaptureTask {
      method getHeader (line 312) | FileDownloadHeader getHeader();
      method getRunningTask (line 314) | BaseDownloadTask.IRunningTask getRunningTask();
      method setFileName (line 316) | void setFileName(String fileName);
      method getFinishListenerList (line 318) | ArrayList<BaseDownloadTask.FinishListener> getFinishListenerList();
    method DownloadTaskHunter (line 340) | DownloadTaskHunter(ICaptureTask task, Object pauseLock) {
    method intoLaunchPool (line 349) | @Override
    method pause (line 395) | @Override
    method getStatus (line 438) | @Override
    method reset (line 443) | @Override
    method setMinIntervalUpdateSpeed (line 468) | @Override
    method getSpeed (line 473) | @Override
    method getSofarBytes (line 478) | @Override
    method getTotalBytes (line 483) | @Override
    method getErrorCause (line 488) | @Override
    method getRetryingTimes (line 493) | @Override
    method isReusedOldFile (line 498) | @Override
    method isResuming (line 503) | @Override
    method getEtag (line 508) | @Override
    method isLargeFile (line 513) | @Override
    method free (line 518) | @Override
    method prepare (line 526) | private void prepare() throws IOException {
    method getId (line 561) | private int getId() {
    method start (line 565) | @SuppressWarnings("checkstyle:emptyblock")
    method equalListener (line 659) | @Override

FILE: library/src/main/java/com/liulishuo/filedownloader/FileDownloadConnectListener.java
  class FileDownloadConnectListener (line 28) | public abstract class FileDownloadConnectListener extends IDownloadListe...
    method FileDownloadConnectListener (line 32) | public FileDownloadConnectListener() {
    method callback (line 35) | @Override
    method connected (line 54) | public abstract void connected();
    method disconnected (line 59) | public abstract void disconnected();
    method getConnectStatus (line 61) | public DownloadServiceConnectChangedEvent.ConnectStatus getConnectStat...

FILE: library/src/main/java/com/liulishuo/filedownloader/FileDownloadEventPool.java
  class FileDownloadEventPool (line 24) | public class FileDownloadEventPool extends DownloadEventPoolImpl {
    class HolderClass (line 26) | private static class HolderClass {
    method FileDownloadEventPool (line 30) | private FileDownloadEventPool() {
    method getImpl (line 34) | public static FileDownloadEventPool getImpl() {

FILE: library/src/main/java/com/liulishuo/filedownloader/FileDownloadLargeFileListener.java
  class FileDownloadLargeFileListener (line 24) | @SuppressWarnings({"WeakerAccess", "UnusedParameters"})
    method FileDownloadLargeFileListener (line 27) | public FileDownloadLargeFileListener() {
    method FileDownloadLargeFileListener (line 34) | public FileDownloadLargeFileListener(int priority) {
    method pending (line 46) | protected abstract void pending(final BaseDownloadTask task, final lon...
    method pending (line 55) | @Override
    method connected (line 68) | @SuppressWarnings("EmptyMethod")
    method connected (line 82) | @Override
    method progress (line 92) | protected abstract void progress(final BaseDownloadTask task, final lo...
    method progress (line 101) | @Override
    method retry (line 113) | @SuppressWarnings("EmptyMethod")
    method retry (line 125) | @SuppressWarnings("EmptyMethod")
    method paused (line 137) | protected abstract void paused(final BaseDownloadTask task, final long...
    method paused (line 146) | @Override

FILE: library/src/main/java/com/liulishuo/filedownloader/FileDownloadLine.java
  class FileDownloadLine (line 33) | public class FileDownloadLine {
    method startForeground (line 38) | public void startForeground(final int id, final Notification notificat...
    method getSoFar (line 62) | public long getSoFar(final int id) {
    method getTotal (line 89) | public long getTotal(final int id) {
    method getStatus (line 116) | public byte getStatus(final int id, final String path) {
    method wait (line 144) | private void wait(final ConnectSubscriber subscriber) {
    class ConnectListener (line 168) | static class ConnectListener implements Runnable {
      method ConnectListener (line 172) | ConnectListener(ConnectSubscriber subscriber) {
      method isFinished (line 176) | public boolean isFinished() {
      method run (line 180) | @Override
    type ConnectSubscriber (line 190) | interface ConnectSubscriber {
      method connected (line 191) | void connected();
      method getValue (line 193) | Object getValue();

FILE: library/src/main/java/com/liulishuo/filedownloader/FileDownloadLineAsync.java
  class FileDownloadLineAsync (line 25) | public class FileDownloadLineAsync {
    method startForeground (line 30) | public boolean startForeground(final int id, final Notification notifi...

FILE: library/src/main/java/com/liulishuo/filedownloader/FileDownloadList.java
  class FileDownloadList (line 30) | @SuppressWarnings("UnusedReturnValue")
    class HolderClass (line 33) | private static final class HolderClass {
    method getImpl (line 37) | public static FileDownloadList getImpl() {
    method FileDownloadList (line 43) | private FileDownloadList() {
    method isEmpty (line 47) | boolean isEmpty() {
    method size (line 51) | int size() {
    method count (line 59) | int count(final int id) {
    method get (line 71) | public BaseDownloadTask.IRunningTask get(final int id) {
    method getReceiveServiceTaskList (line 83) | List<BaseDownloadTask.IRunningTask> getReceiveServiceTaskList(final in...
    method getDownloadingList (line 101) | List<BaseDownloadTask.IRunningTask> getDownloadingList(final int id) {
    method isNotContains (line 115) | boolean isNotContains(final BaseDownloadTask.IRunningTask download) {
    method copy (line 119) | List<BaseDownloadTask.IRunningTask> copy(final FileDownloadListener li...
    method assembleTasksToStart (line 132) | List<BaseDownloadTask.IRunningTask> assembleTasksToStart(int attachKey,
    method copy (line 147) | BaseDownloadTask.IRunningTask[] copy() {
    method divertAndIgnoreDuplicate (line 158) | void divertAndIgnoreDuplicate(
    method remove (line 174) | public boolean remove(final BaseDownloadTask.IRunningTask willRemoveDo...
    method add (line 222) | void add(final BaseDownloadTask.IRunningTask task) {
    method addUnchecked (line 240) | void addUnchecked(final BaseDownloadTask.IRunningTask task) {

FILE: library/src/main/java/com/liulishuo/filedownloader/FileDownloadListener.java
  class FileDownloadListener (line 36) | @SuppressWarnings({"WeakerAccess", "UnusedParameters"})
    method FileDownloadListener (line 39) | public FileDownloadListener() {
    method FileDownloadListener (line 46) | public FileDownloadListener(int priority) {
    method isInvalid (line 55) | protected boolean isInvalid() {
    method pending (line 67) | protected abstract void pending(final BaseDownloadTask task, final int...
    method started (line 76) | protected void started(final BaseDownloadTask task) {
    method connected (line 89) | protected void connected(final BaseDownloadTask task, final String etag,
    method progress (line 102) | protected abstract void progress(final BaseDownloadTask task, final in...
    method blockComplete (line 118) | protected void blockComplete(final BaseDownloadTask task) throws Throw...
    method retry (line 131) | protected void retry(final BaseDownloadTask task, final Throwable ex, ...
    method completed (line 146) | protected abstract void completed(final BaseDownloadTask task);
    method paused (line 157) | protected abstract void paused(final BaseDownloadTask task, final int ...
    method error (line 170) | protected abstract void error(final BaseDownloadTask task, final Throw...
    method warn (line 179) | protected abstract void warn(final BaseDownloadTask task);

FILE: library/src/main/java/com/liulishuo/filedownloader/FileDownloadMessageStation.java
  class FileDownloadMessageStation (line 32) | @SuppressWarnings("WeakerAccess")
    class HolderClass (line 41) | private static final class HolderClass {
    method getImpl (line 45) | public static FileDownloadMessageStation getImpl() {
    method FileDownloadMessageStation (line 49) | private FileDownloadMessageStation() {
    method requestEnqueue (line 54) | void requestEnqueue(final IFileDownloadMessenger messenger) {
    method requestEnqueue (line 58) | void requestEnqueue(final IFileDownloadMessenger messenger,
    method handoverInUIThread (line 95) | private void handoverInUIThread(IFileDownloadMessenger messenger) {
    method interceptBlockCompleteMessage (line 104) | private static boolean interceptBlockCompleteMessage(final IFileDownlo...
    method enqueue (line 120) | private void enqueue(final IFileDownloadMessenger messenger) {
    method push (line 128) | private void push() {
    class UIHandlerCallback (line 165) | private static class UIHandlerCallback implements Handler.Callback {
      method handleMessage (line 167) | @Override
      method dispose (line 179) | private void dispose(final ArrayList<IFileDownloadMessenger> disposi...
    method isIntervalValid (line 209) | public static boolean isIntervalValid() {

FILE: library/src/main/java/com/liulishuo/filedownloader/FileDownloadMessenger.java
  class FileDownloadMessenger (line 33) | class FileDownloadMessenger implements IFileDownloadMessenger {
    method FileDownloadMessenger (line 42) | FileDownloadMessenger(final BaseDownloadTask.IRunningTask task,
    method init (line 47) | private void init(final BaseDownloadTask.IRunningTask task,
    method notifyBegin (line 54) | @Override
    method notifyPending (line 71) | @Override
    method notifyStarted (line 82) | @Override
    method notifyConnected (line 93) | @Override
    method notifyProgress (line 104) | @Override
    method notifyBlockComplete (line 128) | @Override
    method notifyRetry (line 140) | @Override
    method notifyWarn (line 155) | @Override
    method notifyError (line 166) | @Override
    method notifyPaused (line 177) | @Override
    method notifyCompleted (line 188) | @Override
    method process (line 199) | private void process(MessageSnapshot snapshot) {
    method inspectAndHandleOverStatus (line 228) | private void inspectAndHandleOverStatus(int status) {
    method handoverMessage (line 243) | @Override
    method handoverDirectly (line 371) | @Override
    method reAppointment (line 376) | @Override
    method isBlockingCompleted (line 388) | @Override
    method discard (line 393) | @Override
    method toString (line 398) | @Override

FILE: library/src/main/java/com/liulishuo/filedownloader/FileDownloadMonitor.java
  class FileDownloadMonitor (line 27) | public class FileDownloadMonitor {
    method setGlobalMonitor (line 30) | public static void setGlobalMonitor(final IMonitor monitor) {
    method releaseGlobalMonitor (line 34) | public static void releaseGlobalMonitor() {
    method getMonitor (line 38) | public static IMonitor getMonitor() {
    method isValid (line 42) | public static boolean isValid() {
    type IMonitor (line 55) | public interface IMonitor {
      method onRequestStart (line 63) | void onRequestStart(int count, boolean serial, FileDownloadListener ...
      method onRequestStart (line 70) | void onRequestStart(BaseDownloadTask task);
      method onTaskBegin (line 77) | void onTaskBegin(BaseDownloadTask task);
      method onTaskStarted (line 84) | void onTaskStarted(BaseDownloadTask task);
      method onTaskOver (line 91) | void onTaskOver(BaseDownloadTask task);

FILE: library/src/main/java/com/liulishuo/filedownloader/FileDownloadQueueSet.java
  class FileDownloadQueueSet (line 27) | @SuppressWarnings({"SameParameterValue", "WeakerAccess"})
    method FileDownloadQueueSet (line 49) | public FileDownloadQueueSet(FileDownloadListener target) {
    method downloadTogether (line 60) | public FileDownloadQueueSet downloadTogether(BaseDownloadTask... tasks) {
    method downloadTogether (line 71) | public FileDownloadQueueSet downloadTogether(List<BaseDownloadTask> ta...
    method downloadSequentially (line 83) | public FileDownloadQueueSet downloadSequentially(BaseDownloadTask... t...
    method downloadSequentially (line 93) | public FileDownloadQueueSet downloadSequentially(List<BaseDownloadTask...
    method reuseAndStart (line 105) | public void reuseAndStart() {
    method start (line 120) | public void start() {
    method setDirectory (line 174) | public FileDownloadQueueSet setDirectory(String directory) {
    method setAutoRetryTimes (line 182) | public FileDownloadQueueSet setAutoRetryTimes(int autoRetryTimes) {
    method setSyncCallback (line 190) | public FileDownloadQueueSet setSyncCallback(final boolean syncCallback) {
    method setForceReDownload (line 198) | public FileDownloadQueueSet setForceReDownload(final boolean isForceRe...
    method setCallbackProgressTimes (line 206) | public FileDownloadQueueSet setCallbackProgressTimes(final int callbac...
    method setCallbackProgressMinInterval (line 214) | public FileDownloadQueueSet setCallbackProgressMinInterval(int minInte...
    method ignoreEachTaskInternalProgress (line 222) | public FileDownloadQueueSet ignoreEachTaskInternalProgress() {
    method disableCallbackProgressTimes (line 230) | public FileDownloadQueueSet disableCallbackProgressTimes() {
    method setTag (line 237) | public FileDownloadQueueSet setTag(final Object tag) {
    method addTaskFinishListener (line 245) | public FileDownloadQueueSet addTaskFinishListener(
    method setWifiRequired (line 258) | public FileDownloadQueueSet setWifiRequired(boolean isWifiRequired) {

FILE: library/src/main/java/com/liulishuo/filedownloader/FileDownloadSampleListener.java
  class FileDownloadSampleListener (line 22) | public class FileDownloadSampleListener extends FileDownloadListener {
    method pending (line 24) | @Override
    method progress (line 29) | @Override
    method blockComplete (line 34) | @Override
    method completed (line 39) | @Override
    method paused (line 44) | @Override
    method error (line 49) | @Override
    method warn (line 54) | @Override

FILE: library/src/main/java/com/liulishuo/filedownloader/FileDownloadServiceProxy.java
  class FileDownloadServiceProxy (line 36) | public class FileDownloadServiceProxy implements IFileDownloadServicePro...
    class HolderClass (line 38) | private static final class HolderClass {
    method getImpl (line 42) | public static FileDownloadServiceProxy getImpl() {
    method getConnectionListener (line 46) | public static FDServiceSharedHandler.FileDownloadServiceSharedConnection
    method FileDownloadServiceProxy (line 56) | private FileDownloadServiceProxy() {
    method start (line 62) | @Override
    method pause (line 73) | @Override
    method isDownloading (line 78) | @Override
    method getSofar (line 83) | @Override
    method getTotal (line 88) | @Override
    method getStatus (line 93) | @Override
    method pauseAllTasks (line 98) | @Override
    method isIdle (line 103) | @Override
    method isConnected (line 108) | @Override
    method bindStartByContext (line 113) | @Override
    method bindStartByContext (line 118) | @Override
    method unbindByContext (line 123) | @Override
    method startForeground (line 128) | @Override
    method stopForeground (line 133) | @Override
    method setMaxNetworkThreadCount (line 138) | @Override
    method clearTaskData (line 143) | @Override
    method clearAllTaskData (line 148) | @Override
    method isRunServiceForeground (line 153) | @Override

FILE: library/src/main/java/com/liulishuo/filedownloader/FileDownloadServiceSharedTransmit.java
  class FileDownloadServiceSharedTransmit (line 44) | class FileDownloadServiceSharedTransmit implements
    method start (line 51) | @Override
    method pause (line 67) | @Override
    method isDownloading (line 76) | @Override
    method getSofar (line 85) | @Override
    method getTotal (line 94) | @Override
    method getStatus (line 103) | @Override
    method pauseAllTasks (line 112) | @Override
    method isIdle (line 122) | @Override
    method isConnected (line 131) | @Override
    method bindStartByContext (line 136) | @Override
    method bindStartByContext (line 143) | @Override
    method unbindByContext (line 161) | @Override
    method startForeground (line 168) | @Override
    method stopForeground (line 178) | @Override
    method setMaxNetworkThreadCount (line 189) | @Override
    method clearTaskData (line 198) | @Override
    method clearAllTaskData (line 206) | @Override
    method isRunServiceForeground (line 216) | @Override
    method onConnected (line 223) | @Override
    method onDisconnected (line 239) | @Override

FILE: library/src/main/java/com/liulishuo/filedownloader/FileDownloadServiceUIGuard.java
  class FileDownloadServiceUIGuard (line 47) | class FileDownloadServiceUIGuard extends
    method FileDownloadServiceUIGuard (line 51) | FileDownloadServiceUIGuard() {
    method createCallback (line 55) | @Override
    method asInterface (line 60) | @Override
    method registerCallback (line 65) | @Override
    method unregisterCallback (line 72) | @Override
    class FileDownloadServiceCallback (line 79) | protected static class FileDownloadServiceCallback extends IFileDownlo...
      method callback (line 81) | @Override
    method start (line 95) | @Override
    method pause (line 117) | @Override
    method isDownloading (line 132) | @Override
    method getSofar (line 147) | @Override
    method getTotal (line 163) | @Override
    method getStatus (line 179) | @Override
    method pauseAllTasks (line 195) | @Override
    method isIdle (line 212) | @Override
    method startForeground (line 227) | @Override
    method stopForeground (line 241) | @Override
    method setMaxNetworkThreadCount (line 257) | @Override
    method clearTaskData (line 272) | @Override
    method clearAllTaskData (line 287) | @Override

FILE: library/src/main/java/com/liulishuo/filedownloader/FileDownloadTaskLauncher.java
  class FileDownloadTaskLauncher (line 31) | class FileDownloadTaskLauncher {
    class HolderClass (line 33) | private static class HolderClass {
    method getImpl (line 43) | public static FileDownloadTaskLauncher getImpl() {
    method launch (line 49) | synchronized void launch(final ITaskHunter.IStarter taskStarter) {
    method expireAll (line 53) | synchronized void expireAll() {
    method expire (line 57) | synchronized void expire(final ITaskHunter.IStarter taskStarter) {
    method expire (line 61) | synchronized void expire(final FileDownloadListener lis) {
    class LaunchTaskPool (line 66) | private static class LaunchTaskPool {
      method LaunchTaskPool (line 77) | LaunchTaskPool() {
      method asyncExecute (line 81) | public void asyncExecute(final ITaskHunter.IStarter taskStarter) {
      method expire (line 85) | public void expire(ITaskHunter.IStarter starter) {
      method expire (line 93) | public void expire(final FileDownloadListener listener) {
      method expireAll (line 123) | public void expireAll() {
      method init (line 133) | private void init() {
    class LaunchTaskRunnable (line 140) | private static class LaunchTaskRunnable implements Runnable {
      method LaunchTaskRunnable (line 144) | LaunchTaskRunnable(final ITaskHunter.IStarter taskStarter) {
      method run (line 149) | @Override
      method isSameListener (line 158) | public boolean isSameListener(final FileDownloadListener listener) {
      method equals (line 162) | @SuppressWarnings("checkstyle:equalshashcode")
      method expire (line 168) | public void expire() {

FILE: library/src/main/java/com/liulishuo/filedownloader/FileDownloader.java
  class FileDownloader (line 45) | @SuppressWarnings("WeakerAccess")
    method setup (line 57) | public static void setup(Context context) {
    method setupOnApplicationOnCreate (line 86) | public static DownloadMgrInitialParams.InitCustomMaker setupOnApplicat...
    method init (line 101) | public static void init(final Context context) {
    method init (line 113) | public static void init(final Context context,
    class HolderClass (line 129) | private static final class HolderClass {
    method getImpl (line 133) | public static FileDownloader getImpl() {
    method setGlobalPost2UIInterval (line 155) | public static void setGlobalPost2UIInterval(final int intervalMillisec...
    method setGlobalHandleSubPackageSize (line 174) | public static void setGlobalHandleSubPackageSize(final int packageSize) {
    method enableAvoidDropFrame (line 188) | public static void enableAvoidDropFrame() {
    method disableAvoidDropFrame (line 199) | public static void disableAvoidDropFrame() {
    method isEnabledAvoidDropFrame (line 209) | public static boolean isEnabledAvoidDropFrame() {
    method create (line 216) | public BaseDownloadTask create(final String url) {
    method start (line 227) | public boolean start(final FileDownloadListener listener, final boolea...
    method pause (line 248) | public void pause(final FileDownloadListener listener) {
    method pauseAll (line 260) | public void pauseAll() {
    method pause (line 282) | public int pause(final int id) {
    method clear (line 315) | public boolean clear(final int id, final String targetFilePath) {
    method clearAllTaskData (line 348) | public void clearAllTaskData() {
    method getSoFar (line 357) | public long getSoFar(final int downloadId) {
    method getTotal (line 369) | public long getTotal(final int id) {
    method getStatusIgnoreCompleted (line 386) | public byte getStatusIgnoreCompleted(final int id) {
    method getStatus (line 397) | public byte getStatus(final String url, final String path) {
    method getStatus (line 409) | public byte getStatus(final int id, final String path) {
    method replaceListener (line 436) | public int replaceListener(String url, FileDownloadListener listener) {
    method replaceListener (line 448) | public int replaceListener(String url, String path, FileDownloadListen...
    method replaceListener (line 460) | public int replaceListener(int id, FileDownloadListener listener) {
    method bindService (line 480) | public void bindService() {
    method bindService (line 500) | public void bindService(final Runnable runnable) {
    method unBindService (line 512) | public void unBindService() {
    method unBindServiceIfIdle (line 524) | public boolean unBindServiceIfIdle() {
    method isServiceConnected (line 542) | public boolean isServiceConnected() {
    method addServiceConnectListener (line 553) | public void addServiceConnectListener(final FileDownloadConnectListene...
    method removeServiceConnectListener (line 565) | public void removeServiceConnectListener(final FileDownloadConnectList...
    method startForeground (line 592) | public void startForeground(int id, Notification notification) {
    method stopForeground (line 606) | public void stopForeground(boolean removeNotification) {
    method setTaskCompleted (line 638) | @SuppressWarnings("UnusedParameters")
    method setTaskCompleted (line 664) | @SuppressWarnings("UnusedParameters")
    method setMaxNetworkThreadCount (line 681) | public boolean setMaxNetworkThreadCount(final int count) {
    method insureServiceBind (line 712) | public FileDownloadLine insureServiceBind() {
    method insureServiceBindAsync (line 728) | public FileDownloadLineAsync insureServiceBindAsync() {
    method getQueuesHandler (line 735) | IQueuesHandler getQueuesHandler() {
    method getLostConnectedHandler (line 749) | ILostServiceConnectedHandler getLostConnectedHandler() {

FILE: library/src/main/java/com/liulishuo/filedownloader/IDownloadSpeed.java
  type IDownloadSpeed (line 23) | public interface IDownloadSpeed {
    type Monitor (line 28) | interface Monitor {
      method start (line 32) | void start(long startBytes);
      method end (line 39) | void end(final long sofarBytes);
      method update (line 46) | void update(long sofarBytes);
      method reset (line 51) | void reset();
    type Lookup (line 58) | interface Lookup {
      method getSpeed (line 63) | int getSpeed();
      method setMinIntervalUpdateSpeed (line 69) | void setMinIntervalUpdateSpeed(int minIntervalUpdateSpeed);

FILE: library/src/main/java/com/liulishuo/filedownloader/IFileDownloadMessenger.java
  type IFileDownloadMessenger (line 26) | interface IFileDownloadMessenger {
    method notifyBegin (line 35) | boolean notifyBegin();
    method notifyPending (line 44) | void notifyPending(MessageSnapshot snapshot);
    method notifyStarted (line 53) | void notifyStarted(MessageSnapshot snapshot);
    method notifyConnected (line 62) | void notifyConnected(MessageSnapshot snapshot);
    method notifyProgress (line 71) | void notifyProgress(MessageSnapshot snapshot);
    method notifyBlockComplete (line 80) | void notifyBlockComplete(MessageSnapshot snapshot);
    method notifyRetry (line 88) | void notifyRetry(MessageSnapshot snapshot);
    method notifyWarn (line 98) | void notifyWarn(MessageSnapshot snapshot);
    method notifyError (line 110) | void notifyError(MessageSnapshot snapshot);
    method notifyPaused (line 119) | void notifyPaused(MessageSnapshot snapshot);
    method notifyCompleted (line 128) | void notifyCompleted(MessageSnapshot snapshot);
    method handoverMessage (line 133) | void handoverMessage();
    method handoverDirectly (line 140) | boolean handoverDirectly();
    method reAppointment (line 146) | void reAppointment(BaseDownloadTask.IRunningTask task,
    method isBlockingCompleted (line 156) | boolean isBlockingCompleted();
    method discard (line 164) | void discard();

FILE: library/src/main/java/com/liulishuo/filedownloader/IFileDownloadServiceProxy.java
  type IFileDownloadServiceProxy (line 26) | public interface IFileDownloadServiceProxy {
    method start (line 27) | boolean start(final String url, final String path, final boolean pathA...
    method pause (line 33) | boolean pause(final int id);
    method isDownloading (line 35) | boolean isDownloading(final String url, final String path);
    method getSofar (line 37) | long getSofar(final int downloadId);
    method getTotal (line 39) | long getTotal(final int downloadId);
    method getStatus (line 41) | byte getStatus(final int downloadId);
    method pauseAllTasks (line 43) | void pauseAllTasks();
    method isIdle (line 45) | boolean isIdle();
    method isConnected (line 47) | boolean isConnected();
    method bindStartByContext (line 49) | void bindStartByContext(final Context context);
    method bindStartByContext (line 51) | void bindStartByContext(final Context context, final Runnable connecte...
    method unbindByContext (line 53) | void unbindByContext(final Context context);
    method startForeground (line 55) | void startForeground(int id, Notification notification);
    method stopForeground (line 57) | void stopForeground(boolean removeNotification);
    method setMaxNetworkThreadCount (line 59) | boolean setMaxNetworkThreadCount(int count);
    method clearTaskData (line 61) | boolean clearTaskData(int id);
    method clearAllTaskData (line 63) | void clearAllTaskData();
    method isRunServiceForeground (line 65) | boolean isRunServiceForeground();

FILE: library/src/main/java/com/liulishuo/filedownloader/ILostServiceConnectedHandler.java
  type ILostServiceConnectedHandler (line 24) | public interface ILostServiceConnectedHandler {
    method isInWaitingList (line 30) | boolean isInWaitingList(BaseDownloadTask.IRunningTask task);
    method taskWorkFine (line 35) | void taskWorkFine(BaseDownloadTask.IRunningTask task);
    method dispatchTaskStart (line 40) | boolean dispatchTaskStart(BaseDownloadTask.IRunningTask task);

FILE: library/src/main/java/com/liulishuo/filedownloader/IQueuesHandler.java
  type IQueuesHandler (line 25) | public interface IQueuesHandler {
    method startQueueParallel (line 33) | boolean startQueueParallel(FileDownloadListener listener);
    method startQueueSerial (line 41) | boolean startQueueSerial(FileDownloadListener listener);
    method freezeAllSerialQueues (line 43) | void freezeAllSerialQueues();
    method unFreezeSerialQueues (line 45) | void unFreezeSerialQueues(List<Integer> attachKeyList);
    method serialQueueSize (line 47) | int serialQueueSize();
    method contain (line 49) | boolean contain(int attachKey);

FILE: library/src/main/java/com/liulishuo/filedownloader/ITaskHunter.java
  type ITaskHunter (line 25) | public interface ITaskHunter extends IDownloadSpeed.Lookup {
    method intoLaunchPool (line 31) | void intoLaunchPool();
    method pause (line 36) | boolean pause();
    method getStatus (line 42) | byte getStatus();
    method reset (line 47) | void reset();
    method getSofarBytes (line 52) | long getSofarBytes();
    method getTotalBytes (line 57) | long getTotalBytes();
    method getErrorCause (line 62) | Throwable getErrorCause();
    method getRetryingTimes (line 67) | int getRetryingTimes();
    method isReusedOldFile (line 73) | boolean isReusedOldFile();
    method isResuming (line 79) | boolean isResuming();
    method getEtag (line 84) | String getEtag();
    method isLargeFile (line 89) | boolean isLargeFile();
    method free (line 94) | void free();
    type IStarter (line 101) | interface IStarter {
      method start (line 105) | void start();
      method equalListener (line 111) | boolean equalListener(FileDownloadListener listener);
    type IMessageHandler (line 117) | interface IMessageHandler {
      method updateKeepAhead (line 125) | boolean updateKeepAhead(final MessageSnapshot snapshot);
      method updateKeepFlow (line 133) | boolean updateKeepFlow(final MessageSnapshot snapshot);
      method updateMoreLikelyCompleted (line 144) | boolean updateMoreLikelyCompleted(final MessageSnapshot snapshot);
      method updateSameFilePathTaskRunning (line 157) | boolean updateSameFilePathTaskRunning(final MessageSnapshot snapshot);
      method getMessenger (line 162) | IFileDownloadMessenger getMessenger();
      method prepareErrorMessage (line 168) | MessageSnapshot prepareErrorMessage(Throwable cause);

FILE: library/src/main/java/com/liulishuo/filedownloader/IThreadPoolMonitor.java
  type IThreadPoolMonitor (line 25) | public interface IThreadPoolMonitor {
    method isDownloading (line 26) | boolean isDownloading(FileDownloadModel model);
    method findRunningTaskIdBySameTempPath (line 28) | int findRunningTaskIdBySameTempPath(String tempFilePath, int excludeId);

FILE: library/src/main/java/com/liulishuo/filedownloader/LostServiceConnectedHandler.java
  class LostServiceConnectedHandler (line 31) | public class LostServiceConnectedHandler extends FileDownloadConnectList...
    method connected (line 36) | @Override
    method disconnected (line 72) | @Override
    method isInWaitingList (line 114) | @Override
    method taskWorkFine (line 119) | @Override
    method dispatchTaskStart (line 128) | @Override

FILE: library/src/main/java/com/liulishuo/filedownloader/MessageSnapshotGate.java
  class MessageSnapshotGate (line 30) | public class MessageSnapshotGate implements MessageSnapshotFlow.MessageR...
    method transmitMessage (line 32) | private boolean transmitMessage(List<BaseDownloadTask.IRunningTask> ta...
    method receive (line 79) | @Override

FILE: library/src/main/java/com/liulishuo/filedownloader/PauseAllMarker.java
  class PauseAllMarker (line 32) | public class PauseAllMarker implements Handler.Callback {
    method PauseAllMarker (line 42) | public PauseAllMarker(IFileDownloadIPCService serviceHandler) {
    method createMarker (line 46) | @SuppressWarnings("ResultOfMethodCallIgnored")
    method markerFile (line 64) | private static File markerFile() {
    method isMarked (line 72) | private static boolean isMarked() {
    method clearMarker (line 76) | @SuppressWarnings("ResultOfMethodCallIgnored")
    method startPauseAllLooperCheck (line 84) | public void startPauseAllLooperCheck() {
    method stopPauseAllLooperCheck (line 91) | public void stopPauseAllLooperCheck() {
    method handleMessage (line 97) | @Override

FILE: library/src/main/java/com/liulishuo/filedownloader/QueuesHandler.java
  class QueuesHandler (line 35) | class QueuesHandler implements IQueuesHandler {
    method QueuesHandler (line 39) | QueuesHandler() {
    method startQueueParallel (line 43) | @Override
    method startQueueSerial (line 61) | @Override
    method freezeAllSerialQueues (line 91) | @Override
    method unFreezeSerialQueues (line 100) | @Override
    method serialQueueSize (line 108) | @Override
    method contain (line 113) | @Override
    method onAssembledTasksToStart (line 118) | private boolean onAssembledTasksToStart(int attachKey,
    class SerialHandlerCallback (line 151) | private class SerialHandlerCallback implements Handler.Callback {
      method SerialHandlerCallback (line 157) | SerialHandlerCallback() {
      method setHandler (line 162) | public void setHandler(final Handler handler) {
      method setList (line 166) | public void setList(List<BaseDownloadTask.IRunningTask> list) {
      method handleMessage (line 170) | @Override
      method freeze (line 222) | public void freeze() {
      method unfreeze (line 227) | public void unfreeze() {
      method goNext (line 231) | private void goNext(final int nextIndex) {
    class SerialFinishListener (line 250) | private static class SerialFinishListener implements BaseDownloadTask....
      method SerialFinishListener (line 253) | private SerialFinishListener(WeakReference<SerialHandlerCallback> wS...
      method setNextIndex (line 259) | public BaseDownloadTask.FinishListener setNextIndex(int index) {
      method over (line 264) | @Override
    method freezeSerialHandler (line 272) | private void freezeSerialHandler(Handler handler) {
    method unFreezeSerialHandler (line 276) | private void unFreezeSerialHandler(Handler handler) {

FILE: library/src/main/java/com/liulishuo/filedownloader/connection/DefaultConnectionCountAdapter.java
  class DefaultConnectionCountAdapter (line 25) | public class DefaultConnectionCountAdapter implements FileDownloadHelper...
    method determineConnectionCount (line 36) | @Override

FILE: library/src/main/java/com/liulishuo/filedownloader/connection/FileDownloadConnection.java
  type FileDownloadConnection (line 30) | @SuppressWarnings("EmptyMethod")
    method addHeader (line 41) | void addHeader(String name, String value);
    method dispatchAddResumeOffset (line 52) | @SuppressWarnings("UnusedParameters")
    method getInputStream (line 62) | InputStream getInputStream() throws IOException;
    method getRequestHeaderFields (line 73) | Map<String, List<String>> getRequestHeaderFields();
    method getResponseHeaderFields (line 84) | Map<String, List<String>> getResponseHeaderFields();
    method getResponseHeaderField (line 96) | String getResponseHeaderField(String name);
    method setRequestMethod (line 120) | boolean setRequestMethod(String method) throws ProtocolException;
    method execute (line 126) | void execute() throws IOException;
    method getResponseCode (line 139) | int getResponseCode() throws IOException;
    method ending (line 144) | void ending();

FILE: library/src/main/java/com/liulishuo/filedownloader/connection/FileDownloadUrlConnection.java
  class FileDownloadUrlConnection (line 35) | public class FileDownloadUrlConnection implements FileDownloadConnection {
    method FileDownloadUrlConnection (line 38) | public FileDownloadUrlConnection(String originUrl, Configuration confi...
    method FileDownloadUrlConnection (line 43) | public FileDownloadUrlConnection(URL url, Configuration configuration)...
    method FileDownloadUrlConnection (line 64) | public FileDownloadUrlConnection(String originUrl) throws IOException {
    method addHeader (line 68) | @Override
    method dispatchAddResumeOffset (line 73) | @Override
    method getInputStream (line 78) | @Override
    method getRequestHeaderFields (line 83) | @Override
    method getResponseHeaderFields (line 88) | @Override
    method getResponseHeaderField (line 93) | @Override
    method setRequestMethod (line 98) | @Override public boolean setRequestMethod(String method) throws Protoc...
    method execute (line 107) | @Override
    method getResponseCode (line 112) | @Override
    method ending (line 121) | @Override
    class Creator (line 130) | public static class Creator implements FileDownloadHelper.ConnectionCr...
      method Creator (line 133) | public Creator() {
      method Creator (line 137) | public Creator(Configuration configuration) {
      method create (line 141) | FileDownloadConnection create(URL url) throws IOException {
      method create (line 145) | @Override
    class Configuration (line 154) | public static class Configuration {
      method proxy (line 166) | public Configuration proxy(Proxy proxy) {
      method readTimeout (line 185) | public Configuration readTimeout(int readTimeout) {
      method connectTimeout (line 202) | public Configuration connectTimeout(int connectTimeout) {

FILE: library/src/main/java/com/liulishuo/filedownloader/connection/RedirectHandler.java
  class RedirectHandler (line 33) | public class RedirectHandler {
    method process (line 49) | public static FileDownloadConnection process(
    method isRedirect (line 98) | private static boolean isRedirect(int code) {
    method buildRedirectConnection (line 107) | private static FileDownloadConnection buildRedirectConnection(

FILE: library/src/main/java/com/liulishuo/filedownloader/database/FileDownloadDatabase.java
  type FileDownloadDatabase (line 39) | @SuppressWarnings("UnusedParameters")
    method onTaskStart (line 47) | void onTaskStart(final int id);
    method find (line 54) | FileDownloadModel find(final int id);
    method findConnectionModel (line 61) | List<ConnectionModel> findConnectionModel(int id);
    method removeConnections (line 68) | void removeConnections(int id);
    method insertConnectionModel (line 75) | void insertConnectionModel(ConnectionModel model);
    method updateConnectionModel (line 85) | void updateConnectionModel(int id, int index, long currentOffset);
    method updateConnectionCount (line 92) | void updateConnectionCount(int id, int count);
    method insert (line 99) | void insert(final FileDownloadModel downloadModel);
    method update (line 106) | void update(final FileDownloadModel downloadModel);
    method remove (line 114) | boolean remove(final int id);
    method clear (line 119) | void clear();
    method updateOldEtagOverdue (line 125) | void updateOldEtagOverdue(int id, String newEtag, long sofar, long tot...
    method updateConnected (line 137) | void updateConnected(int id, long total, String etag, String filename);
    method updateProgress (line 145) | void updateProgress(int id, long sofarBytes);
    method updateError (line 155) | void updateError(int id, Throwable throwable, long sofar);
    method updateRetry (line 164) | void updateRetry(int id, Throwable throwable);
    method updateCompleted (line 174) | void updateCompleted(int id, final long total);
    method updatePause (line 183) | void updatePause(int id, final long sofar);
    method updatePending (line 191) | void updatePending(int id);
    method maintainer (line 203) | Maintainer maintainer();
    type Maintainer (line 209) | @SuppressWarnings("EmptyMethod")
      method onFinishMaintain (line 214) | void onFinishMaintain();
      method onRemovedInvalidData (line 221) | void onRemovedInvalidData(FileDownloadModel model);
      method onRefreshedValidData (line 228) | void onRefreshedValidData(FileDownloadModel model);
      method changeFileDownloadModelId (line 240) | void changeFileDownloadModelId(int oldId, FileDownloadModel modelWit...

FILE: library/src/main/java/com/liulishuo/filedownloader/database/NoDatabaseImpl.java
  class NoDatabaseImpl (line 57) | public class NoDatabaseImpl implements FileDownloadDatabase {
    method NoDatabaseImpl (line 62) | public NoDatabaseImpl() {
    method createMaker (line 65) | public static Maker createMaker() {
    method onTaskStart (line 69) | @Override
    method find (line 73) | @Override
    method findConnectionModel (line 80) | @Override
    method removeConnections (line 91) | @Override
    method insertConnectionModel (line 98) | @Override
    method updateConnectionModel (line 111) | @Override
    method updateConnectionCount (line 126) | @Override
    method insert (line 130) | @Override
    method update (line 137) | @Override
    method remove (line 155) | @Override
    method clear (line 163) | @Override
    method updateOldEtagOverdue (line 170) | @Override
    method updateConnected (line 175) | @Override
    method updateProgress (line 179) | @Override
    method updateError (line 183) | @Override
    method updateRetry (line 187) | @Override
    method updateCompleted (line 191) | @Override
    method updatePause (line 196) | @Override
    method updatePending (line 200) | @Override
    method maintainer (line 204) | @Override
    class Maintainer (line 209) | class Maintainer implements FileDownloadDatabase.Maintainer {
      method iterator (line 211) | @Override
      method onFinishMaintain (line 216) | @Override
      method onRemovedInvalidData (line 220) | @Override
      method onRefreshedValidData (line 224) | @Override
      method changeFileDownloadModelId (line 228) | @Override
    class MaintainerIterator (line 234) | class MaintainerIterator implements Iterator<FileDownloadModel> {
      method MaintainerIterator (line 236) | MaintainerIterator() {
      method hasNext (line 239) | @Override
      method next (line 244) | @Override
      method remove (line 249) | @Override
    class Maker (line 254) | public static class Maker implements FileDownloadHelper.DatabaseCustom...
      method customMake (line 256) | @Override

FILE: library/src/main/java/com/liulishuo/filedownloader/database/RemitDatabase.java
  class RemitDatabase (line 39) | public class RemitDatabase implements FileDownloadDatabase {
    method RemitDatabase (line 54) | public RemitDatabase() {
    method syncCacheToDB (line 91) | private void syncCacheToDB(int id) {
    method isNoNeedUpdateToRealDB (line 108) | private boolean isNoNeedUpdateToRealDB(int id) {
    method onTaskStart (line 112) | @Override public void onTaskStart(int id) {
    method find (line 116) | @Override public FileDownloadModel find(int id) {
    method findConnectionModel (line 120) | @Override public List<ConnectionModel> findConnectionModel(int id) {
    method removeConnections (line 124) | @Override public void removeConnections(int id) {
    method insertConnectionModel (line 131) | @Override public void insertConnectionModel(ConnectionModel model) {
    method updateConnectionModel (line 138) | @Override public void updateConnectionModel(int id, int index, long cu...
    method updateProgress (line 145) | @Override public void updateProgress(int id, long sofarBytes) {
    method updateConnectionCount (line 151) | @Override public void updateConnectionCount(int id, int count) {
    method insert (line 158) | @Override public void insert(FileDownloadModel downloadModel) {
    method update (line 164) | @Override public void update(FileDownloadModel downloadModel) {
    method remove (line 170) | @Override public boolean remove(int id) {
    method clear (line 175) | @Override public void clear() {
    method updateOldEtagOverdue (line 180) | @Override public void updateOldEtagOverdue(int id, String newEtag, lon...
    method updateConnected (line 187) | @Override public void updateConnected(int id, long total, String etag,...
    method updatePending (line 193) | @Override public void updatePending(int id) {
    method updateRetry (line 199) | @Override public void updateRetry(int id, Throwable throwable) {
    method ensureCacheToDB (line 205) | private void ensureCacheToDB(int id) {
    method updateError (line 216) | @Override public void updateError(int id, Throwable throwable, long so...
    method updateCompleted (line 225) | @Override public void updateCompleted(int id, long total) {
    method updatePause (line 241) | @Override public void updatePause(int id, long sofar) {
    method maintainer (line 251) | @Override public Maintainer maintainer() {
    class Maker (line 256) | public static class Maker implements FileDownloadHelper.DatabaseCustom...
      method customMake (line 258) | @Override public FileDownloadDatabase customMake() {

FILE: library/src/main/java/com/liulishuo/filedownloader/database/SqliteDatabaseImpl.java
  class SqliteDatabaseImpl (line 55) | public class SqliteDatabaseImpl implements FileDownloadDatabase {
    method createMaker (line 62) | public static Maker createMaker() {
    method SqliteDatabaseImpl (line 66) | public SqliteDatabaseImpl() {
    method onTaskStart (line 73) | @Override public void onTaskStart(int id) {
    method find (line 76) | @Override
    method findConnectionModel (line 92) | @Override
    method removeConnections (line 118) | @Override
    method insertConnectionModel (line 124) | @Override
    method updateConnectionModel (line 129) | @Override
    method updateConnectionCount (line 138) | @Override
    method insert (line 146) | @Override
    method update (line 151) | @Override
    method remove (line 168) | @Override
    method clear (line 175) | @Override
    method updateOldEtagOverdue (line 181) | @Override
    method updateConnected (line 194) | @Override
    method updateProgress (line 205) | @Override
    method updateError (line 214) | @Override
    method updateRetry (line 224) | @Override
    method updateCompleted (line 233) | @Override
    method updatePause (line 238) | @Override
    method updatePending (line 247) | @Override
    method maintainer (line 252) | @Override
    method maintainer (line 257) | public FileDownloadDatabase.Maintainer maintainer(
    method update (line 263) | private void update(final int id, final ContentValues cv) {
    class Maintainer (line 267) | public class Maintainer implements FileDownloadDatabase.Maintainer {
      method Maintainer (line 275) | Maintainer() {
      method Maintainer (line 279) | Maintainer(SparseArray<FileDownloadModel> downloaderModelMap,
      method iterator (line 285) | @Override
      method onFinishMaintain (line 290) | @Override
      method onRemovedInvalidData (line 340) | @Override
      method onRefreshedValidData (line 344) | @Override
      method changeFileDownloadModelId (line 349) | @Override
    class MaintainerIterator (line 356) | class MaintainerIterator implements Iterator<FileDownloadModel> {
      method MaintainerIterator (line 362) | MaintainerIterator() {
      method hasNext (line 366) | @Override
      method next (line 371) | @Override
      method remove (line 380) | @Override
      method onFinishMaintain (line 385) | void onFinishMaintain() {
    method createFromCursor (line 403) | private static FileDownloadModel createFromCursor(Cursor c) {
    class Maker (line 421) | public static class Maker implements FileDownloadHelper.DatabaseCustom...
      method customMake (line 423) | @Override

FILE: library/src/main/java/com/liulishuo/filedownloader/database/SqliteDatabaseOpenHelper.java
  class SqliteDatabaseOpenHelper (line 32) | public class SqliteDatabaseOpenHelper extends SQLiteOpenHelper {
    method SqliteDatabaseOpenHelper (line 36) | public SqliteDatabaseOpenHelper(final Context context) {
    method onOpen (line 40) | @Override
    method onCreate (line 51) | @Override
    method onUpgrade (line 78) | @Override
    method onDowngrade (line 120) | @Override public void onDowngrade(SQLiteDatabase db, int oldVersion, i...

FILE: library/src/main/java/com/liulishuo/filedownloader/download/ConnectTask.java
  class ConnectTask (line 38) | public class ConnectTask {
    method ConnectTask (line 51) | private ConnectTask(ConnectionProfile profile,
    method updateConnectionProfile (line 60) | void updateConnectionProfile(long downloadedOffset) {
    method connect (line 77) | FileDownloadConnection connect() throws IOException, IllegalAccessExce...
    method addUserRequiredHeader (line 105) | private void addUserRequiredHeader(FileDownloadConnection connection) {
    method addRangeHeader (line 135) | private void addRangeHeader(FileDownloadConnection connection) throws ...
    method fixNeededHeader (line 146) | private void fixNeededHeader(FileDownloadConnection connection) {
    method isRangeNotFromBeginning (line 152) | boolean isRangeNotFromBeginning() {
    method getFinalRedirectedUrl (line 156) | String getFinalRedirectedUrl() {
    method getRequestHeader (line 164) | public Map<String, List<String>> getRequestHeader() {
    method getProfile (line 168) | public ConnectionProfile getProfile() {
    method retryOnConnectedWithNewParam (line 172) | public void retryOnConnectedWithNewParam(ConnectionProfile profile, St...
    class Reconnect (line 180) | class Reconnect extends Throwable {
    class Builder (line 185) | static class Builder {
      method setDownloadId (line 193) | public Builder setDownloadId(int downloadId) {
      method setUrl (line 198) | public Builder setUrl(String url) {
      method setEtag (line 203) | public Builder setEtag(String etag) {
      method setHeader (line 208) | public Builder setHeader(FileDownloadHeader header) {
      method setConnectionProfile (line 213) | public Builder setConnectionProfile(ConnectionProfile model) {
      method build (line 218) | ConnectTask build() {

FILE: library/src/main/java/com/liulishuo/filedownloader/download/ConnectionProfile.java
  class ConnectionProfile (line 28) | public class ConnectionProfile {
    method ConnectionProfile (line 44) | private ConnectionProfile() {
    method ConnectionProfile (line 54) | private ConnectionProfile(long startOffset, long currentOffset, long e...
    method ConnectionProfile (line 59) | private ConnectionProfile(long startOffset, long currentOffset, long e...
    method processProfile (line 74) | public void processProfile(FileDownloadConnection connection) throws P...
    method toString (line 91) | @Override
    class ConnectionProfileBuild (line 97) | public static class ConnectionProfileBuild {
      method buildTrialConnectionProfile (line 98) | public static ConnectionProfile buildTrialConnectionProfile() {
      method buildTrialConnectionProfileNoRange (line 102) | public static ConnectionProfile buildTrialConnectionProfileNoRange() {
      method buildBeginToEndConnectionProfile (line 106) | public static ConnectionProfile buildBeginToEndConnectionProfile(lon...
      method buildToEndConnectionProfile (line 110) | public static ConnectionProfile buildToEndConnectionProfile(long sta...
      method buildConnectionProfile (line 116) | public static ConnectionProfile buildConnectionProfile(long startOff...

FILE: library/src/main/java/com/liulishuo/filedownloader/download/CustomComponentHolder.java
  class CustomComponentHolder (line 37) | public class CustomComponentHolder {
    class LazyLoader (line 47) | private static final class LazyLoader {
    method getImpl (line 51) | public static CustomComponentHolder getImpl() {
    method setInitCustomMaker (line 55) | public void setInitCustomMaker(DownloadMgrInitialParams.InitCustomMake...
    method createConnection (line 65) | public FileDownloadConnection createConnection(String url) throws IOEx...
    method createOutputStream (line 69) | public FileDownloadOutputStream createOutputStream(File file) throws I...
    method getIdGeneratorInstance (line 73) | public FileDownloadHelper.IdGenerator getIdGeneratorInstance() {
    method getDatabaseInstance (line 85) | public FileDownloadDatabase getDatabaseInstance() {
    method getForegroundConfigInstance (line 98) | public ForegroundServiceConfig getForegroundConfigInstance() {
    method getMaxNetworkThreadCount (line 111) | public int getMaxNetworkThreadCount() {
    method isSupportSeek (line 115) | public boolean isSupportSeek() {
    method determineConnectionCount (line 119) | public int determineConnectionCount(int downloadId, String url, String...
    method getConnectionCountAdapter (line 124) | private FileDownloadHelper.ConnectionCountAdapter getConnectionCountAd...
    method getConnectionCreator (line 137) | private FileDownloadHelper.ConnectionCreator getConnectionCreator() {
    method getOutputStreamCreator (line 149) | private FileDownloadHelper.OutputStreamCreator getOutputStreamCreator() {
    method getDownloadMgrInitialParams (line 161) | private DownloadMgrInitialParams getDownloadMgrInitialParams() {
    method maintainDatabase (line 171) | private static void maintainDatabase(FileDownloadDatabase.Maintainer m...

FILE: library/src/main/java/com/liulishuo/filedownloader/download/DownloadLaunchRunnable.java
  class DownloadLaunchRunnable (line 75) | public class DownloadLaunchRunnable implements Runnable, ProcessCallback {
    method DownloadLaunchRunnable (line 122) | private DownloadLaunchRunnable(FileDownloadModel model, FileDownloadHe...
    method DownloadLaunchRunnable (line 144) | private DownloadLaunchRunnable(DownloadStatusCallback callback, FileDo...
    method createForTest (line 166) | static DownloadLaunchRunnable createForTest(DownloadStatusCallback cal...
    method pause (line 178) | public void pause() {
    method pending (line 192) | public void pending() {
    method run (line 200) | @Override
    method calcConnectionCount (line 346) | private int calcConnectionCount(long totalLength) {
    method trialConnect (line 361) | private void trialConnect() throws IOException, RetryDirectly, Illegal...
    method isMultiConnectionAvailable (line 389) | private boolean isMultiConnectionAvailable() {
    method determineConnectionCount (line 398) | private int determineConnectionCount() {
    method inspectTaskModelResumeAvailableOnDB (line 402) | void inspectTaskModelResumeAvailableOnDB(List<ConnectionModel> connect...
    method handleTrialConnectResult (line 447) | private void handleTrialConnectResult(Map<String, List<String>> reques...
    method realDownloadWithSingleConnection (line 576) | private void realDownloadWithSingleConnection(final long totalLength)
    method realDownloadWithMultiConnectionFromResume (line 613) | private void realDownloadWithMultiConnectionFromResume(final int conne...
    method realDownloadWithMultiConnectionFromBeginning (line 623) | private void realDownloadWithMultiConnectionFromBeginning(final long t...
    method fetchWithMultipleConnection (line 662) | private void fetchWithMultipleConnection(final List<ConnectionModel> c...
    method handlePreAllocate (line 760) | private void handlePreAllocate(long totalLength, String path)
    method onProgress (line 793) | @Override
    method onCompleted (line 800) | @Override
    method isRetry (line 828) | @Override
    method onError (line 848) | @Override
    method onRetry (line 872) | @Override
    method syncProgressFromCache (line 890) | @Override
    method checkupBeforeConnect (line 895) | private void checkupBeforeConnect()
    method checkupAfterGetFilename (line 915) | private void checkupAfterGetFilename() throws RetryDirectly, DiscardSa...
    method getId (line 992) | public int getId() {
    method isAlive (line 996) | public boolean isAlive() {
    method getTempFilePath (line 1000) | public String getTempFilePath() {
    class RetryDirectly (line 1004) | class RetryDirectly extends Throwable {
    class DiscardSafely (line 1007) | class DiscardSafely extends Throwable {
    class Builder (line 1010) | public static class Builder {
      method setModel (line 1020) | public Builder setModel(FileDownloadModel model) {
      method setHeader (line 1025) | public Builder setHeader(FileDownloadHeader header) {
      method setThreadPoolMonitor (line 1030) | public Builder setThreadPoolMonitor(IThreadPoolMonitor threadPoolMon...
      method setMinIntervalMillis (line 1035) | public Builder setMinIntervalMillis(Integer minIntervalMillis) {
      method setCallbackProgressMaxCount (line 1040) | public Builder setCallbackProgressMaxCount(Integer callbackProgressM...
      method setForceReDownload (line 1045) | public Builder setForceReDownload(Boolean forceReDownload) {
      method setWifiRequired (line 1050) | public Builder setWifiRequired(Boolean wifiRequired) {
      method setMaxRetryTimes (line 1055) | public Builder setMaxRetryTimes(Integer maxRetryTimes) {
      method build (line 1060) | public DownloadLaunchRunnable build() {

FILE: library/src/main/java/com/liulishuo/filedownloader/download/DownloadRunnable.java
  class DownloadRunnable (line 38) | public class DownloadRunnable implements Runnable {
    method DownloadRunnable (line 51) | private DownloadRunnable(int id, int connectionIndex, ConnectTask conn...
    method pause (line 62) | public void pause() {
    method discard (line 67) | public void discard() {
    method run (line 71) | @Override
    method getDownloadedOffset (line 157) | private long getDownloadedOffset() {
    class Builder (line 175) | public static class Builder {
      method setCallback (line 183) | public Builder setCallback(ProcessCallback callback) {
      method setId (line 188) | public Builder setId(int id) {
      method setUrl (line 193) | public Builder setUrl(String url) {
      method setEtag (line 198) | public Builder setEtag(String etag) {
      method setHeader (line 203) | public Builder setHeader(FileDownloadHeader header) {
      method setConnectionModel (line 208) | public Builder setConnectionModel(ConnectionProfile model) {
      method setPath (line 213) | public Builder setPath(String path) {
      method setWifiRequired (line 218) | public Builder setWifiRequired(boolean wifiRequired) {
      method setConnectionIndex (line 223) | public Builder setConnectionIndex(Integer connectionIndex) {
      method build (line 228) | public DownloadRunnable build() {
      method buildForTest (line 240) | DownloadRunnable buildForTest(ConnectTask connectTask) {

FILE: library/src/main/java/com/liulishuo/filedownloader/download/DownloadStatusCallback.java
  class DownloadStatusCallback (line 51) | public class DownloadStatusCallback implements Handler.Callback {
    method DownloadStatusCallback (line 70) | DownloadStatusCallback(FileDownloadModel model,
    method isAlive (line 82) | public boolean isAlive() {
    method discardAllMessage (line 89) | void discardAllMessage() {
    method onPending (line 102) | public void onPending() {
    method onStartThread (line 110) | void onStartThread() {
    method onConnected (line 117) | void onConnected(boolean isResume, long totalLength, String etag, Stri...
    method onMultiConnection (line 142) | void onMultiConnection() {
    method onProgress (line 153) | void onProgress(long increaseBytes) {
    method onRetry (line 170) | void onRetry(Exception exception, int remainRetryTimes) {
    method onPausedDirectly (line 184) | void onPausedDirectly() {
    method onErrorDirectly (line 188) | void onErrorDirectly(Exception exception) {
    method onCompletedDirectly (line 192) | void onCompletedDirectly() throws IOException {
    method sendMessage (line 204) | private synchronized void sendMessage(Message message) {
    method calculateCallbackMinIntervalBytes (line 227) | private static long calculateCallbackMinIntervalBytes(final long conte...
    method exFiltrate (line 239) | private Exception exFiltrate(Exception ex) {
    method handleSQLiteFullException (line 275) | private void handleSQLiteFullException(final SQLiteFullException sqLit...
    method renameTempFile (line 290) | private void renameTempFile() throws IOException {
    method handleMessage (line 332) | @Override
    method handleProgress (line 359) | private void handleProgress() {
    method handleCompleted (line 380) | private void handleCompleted() throws IOException {
    method interceptBeforeCompleted (line 395) | private boolean interceptBeforeCompleted() {
    method handleRetry (line 408) | private void handleRetry(final Exception exception, final int remainRe...
    method handlePaused (line 420) | private void handlePaused() {
    method handleError (line 427) | private void handleError(Exception exception) {
    method inspectNeedCallbackToUser (line 454) | private void inspectNeedCallbackToUser(final long now) {
    method onStatusChanged (line 473) | private void onStatusChanged(final byte status) {
    class ProcessParams (line 499) | public static class ProcessParams {
      method setResuming (line 504) | void setResuming(boolean isResuming) {
      method isResuming (line 508) | public boolean isResuming() {
      method setException (line 512) | void setException(Exception exception) {
      method setRetryingTimes (line 516) | void setRetryingTimes(int retryingTimes) {
      method getException (line 520) | public Exception getException() {
      method getRetryingTimes (line 524) | public int getRetryingTimes() {

FILE: library/src/main/java/com/liulishuo/filedownloader/download/FetchDataTask.java
  class FetchDataTask (line 37) | public class FetchDataTask {
    method pause (line 58) | public void pause() {
    method FetchDataTask (line 62) | private FetchDataTask(FileDownloadConnection connection, ConnectionPro...
    method run (line 80) | public void run() throws IOException, IllegalAccessException, IllegalA...
    method checkAndSync (line 205) | private void checkAndSync() {
    method sync (line 218) | private void sync() {
    class Builder (line 253) | public static class Builder {
      method setConnection (line 263) | public Builder setConnection(FileDownloadConnection connection) {
      method setConnectionProfile (line 268) | public Builder setConnectionProfile(ConnectionProfile connectionProf...
      method setCallback (line 273) | public Builder setCallback(ProcessCallback callback) {
      method setPath (line 278) | public Builder setPath(String path) {
      method setWifiRequired (line 283) | public Builder setWifiRequired(boolean wifiRequired) {
      method setHost (line 288) | public Builder setHost(DownloadRunnable downloadRunnable) {
      method setConnectionIndex (line 293) | public Builder setConnectionIndex(int connectionIndex) {
      method setDownloadId (line 298) | public Builder setDownloadId(int downloadId) {
      method build (line 303) | public FetchDataTask build() throws IllegalArgumentException {

FILE: library/src/main/java/com/liulishuo/filedownloader/download/ProcessCallback.java
  type ProcessCallback (line 22) | public interface ProcessCallback {
    method onProgress (line 24) | void onProgress(long increaseBytes);
    method onCompleted (line 26) | void onCompleted(DownloadRunnable doneRunnable, long startOffset, long...
    method isRetry (line 28) | boolean isRetry(Exception exception);
    method onError (line 30) | void onError(Exception exception);
    method onRetry (line 32) | void onRetry(Exception exception);
    method syncProgressFromCache (line 34) | void syncProgressFromCache();

FILE: library/src/main/java/com/liulishuo/filedownloader/event/DownloadEventPoolImpl.java
  class DownloadEventPoolImpl (line 29) | public class DownloadEventPoolImpl implements IDownloadEventPool {
    method addListener (line 35) | @Override
    method removeListener (line 59) | @Override
    method publish (line 85) | @Override
    method asyncPublishInNewThread (line 109) | @Override
    method trigger (line 124) | private void trigger(final LinkedList<IDownloadListener> listeners,

FILE: library/src/main/java/com/liulishuo/filedownloader/event/DownloadEventSampleListener.java
  class DownloadEventSampleListener (line 22) | public class DownloadEventSampleListener extends IDownloadListener {
    method DownloadEventSampleListener (line 25) | public DownloadEventSampleListener(IEventListener i) {
    method callback (line 34) | @Override
    type IEventListener (line 39) | public interface IEventListener {
      method callback (line 40) | boolean callback(IDownloadEvent event);

FILE: library/src/main/java/com/liulishuo/filedownloader/event/DownloadServiceConnectChangedEvent.java
  class DownloadServiceConnectChangedEvent (line 23) | public class DownloadServiceConnectChangedEvent extends IDownloadEvent {
    method DownloadServiceConnectChangedEvent (line 26) | public DownloadServiceConnectChangedEvent(final ConnectStatus status,
    type ConnectStatus (line 36) | public enum ConnectStatus {
    method getStatus (line 42) | public ConnectStatus getStatus() {
    method isSuchService (line 48) | public boolean isSuchService(final Class<?> serviceClass) {

FILE: library/src/main/java/com/liulishuo/filedownloader/event/IDownloadEvent.java
  class IDownloadEvent (line 24) | @SuppressWarnings({"WeakerAccess", "CanBeFinal"})
    method IDownloadEvent (line 28) | public IDownloadEvent(final String id) {
    method IDownloadEvent (line 36) | public IDownloadEvent(final String id, boolean order) {
    method getId (line 46) | public final String getId() {

FILE: library/src/main/java/com/liulishuo/filedownloader/event/IDownloadEventPool.java
  type IDownloadEventPool (line 25) | interface IDownloadEventPool {
    method addListener (line 27) | boolean addListener(final String eventId, final IDownloadListener list...
    method removeListener (line 29) | boolean removeListener(final String eventId, final IDownloadListener l...
    method publish (line 31) | boolean publish(final IDownloadEvent event);
    method asyncPublishInNewThread (line 33) | void asyncPublishInNewThread(final IDownloadEvent event);

FILE: library/src/main/java/com/liulishuo/filedownloader/event/IDownloadListener.java
  class IDownloadListener (line 25) | public abstract class IDownloadListener {
    method callback (line 37) | public abstract boolean callback(IDownloadEvent event);

FILE: library/src/main/java/com/liulishuo/filedownloader/exception/FileDownloadGiveUpRetryException.java
  class FileDownloadGiveUpRetryException (line 24) | public class FileDownloadGiveUpRetryException extends RuntimeException {
    method FileDownloadGiveUpRetryException (line 25) | public FileDownloadGiveUpRetryException(final String detailMessage) {

FILE: library/src/main/java/com/liulishuo/filedownloader/exception/FileDownloadHttpException.java
  class FileDownloadHttpException (line 30) | public class FileDownloadHttpException extends IOException {
    method FileDownloadHttpException (line 35) | public FileDownloadHttpException(final int code,
    method getRequestHeader (line 49) | public Map<String, List<String>> getRequestHeader() {
    method getResponseHeader (line 56) | public Map<String, List<String>> getResponseHeader() {
    method getCode (line 63) | public int getCode() {
    method cloneSerializableMap (line 67) | private static Map<String, List<String>> cloneSerializableMap(

FILE: library/src/main/java/com/liulishuo/filedownloader/exception/FileDownloadNetworkPolicyException.java
  class FileDownloadNetworkPolicyException (line 27) | public class FileDownloadNetworkPolicyException extends FileDownloadGive...
    method FileDownloadNetworkPolicyException (line 28) | public FileDownloadNetworkPolicyException() {

FILE: library/src/main/java/com/liulishuo/filedownloader/exception/FileDownloadOutOfSpaceException.java
  class FileDownloadOutOfSpaceException (line 37) | @SuppressWarnings("SameParameterValue")
    method FileDownloadOutOfSpaceException (line 42) | @TargetApi(Build.VERSION_CODES.GINGERBREAD)
    method FileDownloadOutOfSpaceException (line 52) | public FileDownloadOutOfSpaceException(long freeSpaceBytes, long requi...
    method init (line 62) | private void init(long freeSpaceBytes, long requiredSpaceBytes, long b...
    method getFreeSpaceBytes (line 71) | public long getFreeSpaceBytes() {
    method getRequiredSpaceBytes (line 78) | public long getRequiredSpaceBytes() {
    method getBreakpointBytes (line 88) | public long getBreakpointBytes() {

FILE: library/src/main/java/com/liulishuo/filedownloader/exception/FileDownloadSecurityException.java
  class FileDownloadSecurityException (line 22) | public class FileDownloadSecurityException extends Exception {
    method FileDownloadSecurityException (line 23) | public FileDownloadSecurityException(String msg) {

FILE: library/src/main/java/com/liulishuo/filedownloader/exception/PathConflictException.java
  class PathConflictException (line 27) | public class PathConflictException extends IllegalAccessException {
    method PathConflictException (line 33) | public PathConflictException(final int anotherSamePathTaskId, final St...
    method getDownloadingConflictPath (line 54) | public String getDownloadingConflictPath() {
    method getTargetFilePath (line 64) | public String getTargetFilePath() {
    method getAnotherSamePathTaskId (line 75) | public int getAnotherSamePathTaskId() {

FILE: library/src/main/java/com/liulishuo/filedownloader/message/BlockCompleteMessage.java
  type BlockCompleteMessage (line 29) | public interface BlockCompleteMessage {
    method transmitToCompleted (line 31) | MessageSnapshot transmitToCompleted();
    class BlockCompleteMessageImpl (line 33) | class BlockCompleteMessageImpl extends MessageSnapshot implements Bloc...
      method BlockCompleteMessageImpl (line 36) | public BlockCompleteMessageImpl(MessageSnapshot snapshot) {
      method transmitToCompleted (line 46) | @Override
      method getStatus (line 51) | @Override

FILE: library/src/main/java/com/liulishuo/filedownloader/message/IFlowDirectly.java
  type IFlowDirectly (line 23) | public interface IFlowDirectly {

FILE: library/src/main/java/com/liulishuo/filedownloader/message/IMessageSnapshot.java
  type IMessageSnapshot (line 22) | interface IMessageSnapshot {
    method getId (line 26) | int getId();
    method getStatus (line 32) | byte getStatus();
    method getThrowable (line 37) | Throwable getThrowable();
    method getRetryingTimes (line 42) | int getRetryingTimes();
    method isResuming (line 48) | boolean isResuming();
    method getEtag (line 53) | String getEtag();
    method getLargeSofarBytes (line 61) | long getLargeSofarBytes();
    method getLargeTotalBytes (line 69) | long getLargeTotalBytes();
    method getSmallSofarBytes (line 77) | int getSmallSofarBytes();
    method getSmallTotalBytes (line 85) | int getSmallTotalBytes();
    method isReusedDownloadedFile (line 91) | boolean isReusedDownloadedFile();
    method isLargeFile (line 96) | boolean isLargeFile();
    method getFileName (line 101) | String getFileName();

FILE: library/src/main/java/com/liulishuo/filedownloader/message/LargeMessageSnapshot.java
  class LargeMessageSnapshot (line 29) | public abstract class LargeMessageSnapshot extends MessageSnapshot {
    method LargeMessageSnapshot (line 31) | LargeMessageSnapshot(int id) {
    method LargeMessageSnapshot (line 36) | LargeMessageSnapshot(Parcel in) {
    method getSmallSofarBytes (line 40) | @Override
    method getSmallTotalBytes (line 49) | @Override
    class PendingMessageSnapshot (line 59) | public static class PendingMessageSnapshot extends LargeMessageSnapshot {
      method PendingMessageSnapshot (line 63) | PendingMessageSnapshot(PendingMessageSnapshot snapshot) {
      method PendingMessageSnapshot (line 67) | PendingMessageSnapshot(int id, long sofarBytes, long totalBytes) {
      method getStatus (line 73) | @Override
      method getLargeSofarBytes (line 78) | @Override
      method getLargeTotalBytes (line 83) | @Override
      method describeContents (line 88) | @Override
      method writeToParcel (line 93) | @Override
      method PendingMessageSnapshot (line 100) | PendingMessageSnapshot(Parcel in) {
    class ConnectedMessageSnapshot (line 108) | public static class ConnectedMessageSnapshot extends LargeMessageSnaps...
      method ConnectedMessageSnapshot (line 114) | ConnectedMessageSnapshot(int id, boolean resuming, long totalBytes,
      method describeContents (line 123) | @Override
      method writeToParcel (line 128) | @Override
      method ConnectedMessageSnapshot (line 137) | ConnectedMessageSnapshot(Parcel in) {
      method getFileName (line 145) | @Override
      method getStatus (line 150) | @Override
      method isResuming (line 155) | @Override
      method getLargeTotalBytes (line 160) | @Override
      method getEtag (line 165) | @Override
    class ProgressMessageSnapshot (line 172) | public static class ProgressMessageSnapshot extends LargeMessageSnapsh...
      method ProgressMessageSnapshot (line 175) | ProgressMessageSnapshot(int id, long sofarBytes) {
      method getStatus (line 180) | @Override
      method getLargeSofarBytes (line 185) | @Override
      method describeContents (line 190) | @Override
      method writeToParcel (line 195) | @Override
      method ProgressMessageSnapshot (line 201) | ProgressMessageSnapshot(Parcel in) {
    class CompletedFlowDirectlySnapshot (line 208) | public static class CompletedFlowDirectlySnapshot extends CompletedSna...
      method CompletedFlowDirectlySnapshot (line 211) | CompletedFlowDirectlySnapshot(int id, boolean reusedDownloadedFile,
      method CompletedFlowDirectlySnapshot (line 216) | CompletedFlowDirectlySnapshot(Parcel in) {
    class CompletedSnapshot (line 221) | public static class CompletedSnapshot extends LargeMessageSnapshot {
      method CompletedSnapshot (line 225) | CompletedSnapshot(int id, boolean reusedDownloadedFile,
      method describeContents (line 232) | @Override
      method writeToParcel (line 237) | @Override
      method CompletedSnapshot (line 244) | CompletedSnapshot(Parcel in) {
      method getStatus (line 250) | @Override
      method getLargeTotalBytes (line 255) | @Override
      method isReusedDownloadedFile (line 260) | @Override
    class ErrorMessageSnapshot (line 267) | public static class ErrorMessageSnapshot extends LargeMessageSnapshot {
      method ErrorMessageSnapshot (line 271) | ErrorMessageSnapshot(int id, long sofarBytes, Throwable throwable) {
      method getLargeSofarBytes (line 277) | @Override
      method getStatus (line 282) | @Override
      method getThrowable (line 287) | @Override
      method describeContents (line 292) | @Override
      method writeToParcel (line 297) | @Override
      method ErrorMessageSnapshot (line 304) | ErrorMessageSnapshot(Parcel in) {
    class RetryMessageSnapshot (line 312) | public static class RetryMessageSnapshot extends ErrorMessageSnapshot {
      method RetryMessageSnapshot (line 315) | RetryMessageSnapshot(int id, long sofarBytes, Throwable throwable,
      method getRetryingTimes (line 321) | @Override
      method describeContents (line 326) | @Override
      method writeToParcel (line 331) | @Override
      method RetryMessageSnapshot (line 337) | RetryMessageSnapshot(Parcel in) {
      method getStatus (line 342) | @Override
    class WarnFlowDirectlySnapshot (line 349) | public static class WarnFlowDirectlySnapshot extends WarnMessageSnapsh...
      method WarnFlowDirectlySnapshot (line 352) | WarnFlowDirectlySnapshot(int id, long sofarBytes, long totalBytes) {
      method WarnFlowDirectlySnapshot (line 356) | WarnFlowDirectlySnapshot(Parcel in) {
    class WarnMessageSnapshot (line 361) | public static class WarnMessageSnapshot extends PendingMessageSnapshot...
      method WarnMessageSnapshot (line 364) | WarnMessageSnapshot(int id, long sofarBytes, long totalBytes) {
      method WarnMessageSnapshot (line 368) | WarnMessageSnapshot(Parcel in) {
      method turnToPending (line 372) | @Override
      method getStatus (line 377) | @Override
    class PausedSnapshot (line 384) | public static class PausedSnapshot extends PendingMessageSnapshot {
      method PausedSnapshot (line 385) | PausedSnapshot(int id, long sofarBytes, long totalBytes) {
      method getStatus (line 389) | @Override

FILE: library/src/main/java/com/liulishuo/filedownloader/message/MessageSnapshot.java
  class MessageSnapshot (line 28) | public abstract class MessageSnapshot implements IMessageSnapshot, Parce...
    method MessageSnapshot (line 32) | MessageSnapshot(int id) {
    method getId (line 36) | @Override
    method getThrowable (line 41) | @Override
    method getRetryingTimes (line 46) | @Override
    method isResuming (line 51) | @Override
    method getEtag (line 56) | @Override
    method getLargeSofarBytes (line 61) | @Override
    method getLargeTotalBytes (line 66) | @Override
    method getSmallSofarBytes (line 71) | @Override
    method getSmallTotalBytes (line 76) | @Override
    method isReusedDownloadedFile (line 81) | @Override
    method getFileName (line 86) | @Override
    method isLargeFile (line 91) | @Override
    type IWarnMessageSnapshot (line 97) | public interface IWarnMessageSnapshot {
      method turnToPending (line 98) | MessageSnapshot turnToPending();
    method describeContents (line 102) | @Override
    method writeToParcel (line 107) | @Override
    method MessageSnapshot (line 115) | MessageSnapshot(Parcel in) {
    method createFromParcel (line 120) | @Override
    method newArray (line 192) | @Override
    class NoFieldException (line 198) | public static class NoFieldException extends IllegalStateException {
      method NoFieldException (line 199) | NoFieldException(String methodName, MessageSnapshot snapshot) {
    class StartedMessageSnapshot (line 208) | public static class StartedMessageSnapshot extends MessageSnapshot {
      method StartedMessageSnapshot (line 210) | StartedMessageSnapshot(int id) {
      method StartedMessageSnapshot (line 214) | StartedMessageSnapshot(Parcel in) {
      method getStatus (line 218) | @Override

FILE: library/src/main/java/com/liulishuo/filedownloader/message/MessageSnapshotFlow.java
  class MessageSnapshotFlow (line 24) | public class MessageSnapshotFlow {
    class HolderClass (line 29) | public static final class HolderClass {
    method getImpl (line 33) | public static MessageSnapshotFlow getImpl() {
    method setReceiver (line 37) | public void setReceiver(MessageReceiver receiver) {
    method inflow (line 46) | public void inflow(final MessageSnapshot snapshot) {
    type MessageReceiver (line 60) | public interface MessageReceiver {
      method receive (line 61) | void receive(MessageSnapshot snapshot);

FILE: library/src/main/java/com/liulishuo/filedownloader/message/MessageSnapshotTaker.java
  class MessageSnapshotTaker (line 31) | public class MessageSnapshotTaker {
    method take (line 33) | public static MessageSnapshot take(byte status, FileDownloadModel mode...
    method catchCanReusedOldFile (line 37) | public static MessageSnapshot catchCanReusedOldFile(int id, File oldFile,
    method catchWarn (line 56) | public static MessageSnapshot catchWarn(int id, long sofar, long total...
    method catchException (line 73) | public static MessageSnapshot catchException(int id, long sofar, Throw...
    method catchPause (line 81) | public static MessageSnapshot catchPause(BaseDownloadTask task) {
    method takeBlockCompleted (line 91) | public static MessageSnapshot takeBlockCompleted(MessageSnapshot snaps...
    method take (line 102) | public static MessageSnapshot take(byte status, FileDownloadModel model,

FILE: library/src/main/java/com/liulishuo/filedownloader/message/MessageSnapshotThreadPool.java
  class MessageSnapshotThreadPool (line 28) | public class MessageSnapshotThreadPool {
    method MessageSnapshotThreadPool (line 34) | MessageSnapshotThreadPool(@SuppressWarnings("SameParameterValue") fina...
    method execute (line 43) | public void execute(final MessageSnapshot snapshot) {
    class FlowSingleExecutor (line 84) | public class FlowSingleExecutor {
      method FlowSingleExecutor (line 88) | public FlowSingleExecutor(int index) {
      method enqueue (line 92) | public void enqueue(final int id) {
      method execute (line 96) | public void execute(final MessageSnapshot snapshot) {

FILE: library/src/main/java/com/liulishuo/filedownloader/message/SmallMessageSnapshot.java
  class SmallMessageSnapshot (line 29) | public abstract class SmallMessageSnapshot extends MessageSnapshot {
    method SmallMessageSnapshot (line 31) | SmallMessageSnapshot(int id) {
    method SmallMessageSnapshot (line 36) | SmallMessageSnapshot(Parcel in) {
    method getLargeTotalBytes (line 40) | @Override
    method getLargeSofarBytes (line 45) | @Override
    class PendingMessageSnapshot (line 51) | public static class PendingMessageSnapshot extends SmallMessageSnapshot {
      method PendingMessageSnapshot (line 55) | PendingMessageSnapshot(PendingMessageSnapshot snapshot) {
      method PendingMessageSnapshot (line 59) | PendingMessageSnapshot(int id, int sofarBytes, int totalBytes) {
      method PendingMessageSnapshot (line 65) | PendingMessageSnapshot(Parcel in) {
      method writeToParcel (line 71) | @Override
      method getStatus (line 78) | @Override
      method getSmallSofarBytes (line 83) | @Override
      method getSmallTotalBytes (line 88) | @Override
    class ConnectedMessageSnapshot (line 96) | public static class ConnectedMessageSnapshot extends SmallMessageSnaps...
      method ConnectedMessageSnapshot (line 102) | ConnectedMessageSnapshot(int id, boolean resuming, int totalBytes,
      method describeContents (line 111) | @Override
      method writeToParcel (line 116) | @Override
      method ConnectedMessageSnapshot (line 125) | ConnectedMessageSnapshot(Parcel in) {
      method getFileName (line 133) | @Override
      method getStatus (line 138) | @Override
      method isResuming (line 143) | @Override
      method getSmallTotalBytes (line 148) | @Override
      method getEtag (line 153) | @Override
    class ProgressMessageSnapshot (line 160) | public static class ProgressMessageSnapshot extends SmallMessageSnapsh...
      method ProgressMessageSnapshot (line 163) | ProgressMessageSnapshot(int id, int sofarBytes) {
      method getStatus (line 168) | @Override
      method getSmallSofarBytes (line 173) | @Override
      method describeContents (line 178) | @Override
      method writeToParcel (line 183) | @Override
      method ProgressMessageSnapshot (line 189) | ProgressMessageSnapshot(Parcel in) {
    class CompletedFlowDirectlySnapshot (line 196) | public static class CompletedFlowDirectlySnapshot extends CompletedSna...
      method CompletedFlowDirectlySnapshot (line 199) | CompletedFlowDirectlySnapshot(int id, boolean reusedDownloadedFile,
      method CompletedFlowDirectlySnapshot (line 204) | CompletedFlowDirectlySnapshot(Parcel in) {
    class CompletedSnapshot (line 209) | public static class CompletedSnapshot extends SmallMessageSnapshot {
      method CompletedSnapshot (line 213) | CompletedSnapshot(int id, boolean reusedDownloadedFile,
      method describeContents (line 220) | @Override
      method writeToParcel (line 225) | @Override
      method CompletedSnapshot (line 232) | CompletedSnapshot(Parcel in) {
      method getStatus (line 238) | @Override
      method getSmallTotalBytes (line 243) | @Override
      method isReusedDownloadedFile (line 248) | @Override
    class ErrorMessageSnapshot (line 255) | public static class ErrorMessageSnapshot extends SmallMessageSnapshot {
      method ErrorMessageSnapshot (line 259) | ErrorMessageSnapshot(int id, int sofarBytes, Throwable throwable) {
      method getSmallSofarBytes (line 265) | @Override
      method getStatus (line 270) | @Override
      method getThrowable (line 275) | @Override
      method describeContents (line 280) | @Override
      method writeToParcel (line 285) | @Override
      method ErrorMessageSnapshot (line 292) | ErrorMessageSnapshot(Parcel in) {
    class RetryMessageSnapshot (line 300) | public static class RetryMessageSnapshot extends ErrorMessageSnapshot {
      method RetryMessageSnapshot (line 303) | RetryMessageSnapshot(int id, int sofarBytes, Throwable throwable,
      method getRetryingTimes (line 309) | @Override
      method describeContents (line 314) | @Override
      method writeToParcel (line 319) | @Override
      method RetryMessageSnapshot (line 325) | RetryMessageSnapshot(Parcel in) {
      method getStatus (line 330) | @Override
    class WarnFlowDirectlySnapshot (line 338) | public static class WarnFlowDirectlySnapshot extends WarnMessageSnapsh...
      method WarnFlowDirectlySnapshot (line 340) | WarnFlowDirectlySnapshot(int id, int sofarBytes, int totalBytes) {
      method WarnFlowDirectlySnapshot (line 344) | WarnFlowDirectlySnapshot(Parcel in) {
    class WarnMessageSnapshot (line 349) | public static class WarnMessageSnapshot extends PendingMessageSnapshot...
      method WarnMessageSnapshot (line 352) | WarnMessageSnapshot(int id, int sofarBytes, int totalBytes) {
      method WarnMessageSnapshot (line 356) | WarnMessageSnapshot(Parcel in) {
      method turnToPending (line 360) | @Override
      method getStatus (line 365) | @Override
    class PausedSnapshot (line 372) | public static class PausedSnapshot extends PendingMessageSnapshot {
      method PausedSnapshot (line 373) | PausedSnapshot(int id, int sofarBytes, int totalBytes) {
      method getStatus (line 377) | @Override

FILE: library/src/main/java/com/liulishuo/filedownloader/model/ConnectionModel.java
  class ConnectionModel (line 29) | public class ConnectionModel {
    method getId (line 45) | public int getId() {
    method setId (line 49) | public void setId(int id) {
    method getIndex (line 53) | public int getIndex() {
    method setIndex (line 57) | public void setIndex(int index) {
    method getStartOffset (line 61) | public long getStartOffset() {
    method setStartOffset (line 65) | public void setStartOffset(long startOffset) {
    method getCurrentOffset (line 69) | public long getCurrentOffset() {
    method setCurrentOffset (line 73) | public void setCurrentOffset(long currentOffset) {
    method getEndOffset (line 77) | public long getEndOffset() {
    method setEndOffset (line 81) | public void setEndOffset(long endOffset) {
    method toContentValues (line 85) | public ContentValues toContentValues() {
    method getTotalOffset (line 95) | public static long getTotalOffset(List<ConnectionModel> modelList) {
    method toString (line 103) | @Override

FILE: library/src/main/java/com/liulishuo/filedownloader/model/FileDownloadHeader.java
  class FileDownloadHeader (line 31) | public class FileDownloadHeader implements Parcelable {
    method add (line 40) | public void add(String name, String value) {
    method add (line 65) | public void add(String line) {
    method removeAll (line 76) | public void removeAll(String name) {
    method describeContents (line 84) | @Override
    method writeToParcel (line 89) | @Override
    method getHeaders (line 94) | public HashMap<String, List<String>> getHeaders() {
    method FileDownloadHeader (line 98) | public FileDownloadHeader() {
    method FileDownloadHeader (line 101) | protected FileDownloadHeader(Parcel in) {
    method createFromParcel (line 107) | public FileDownloadHeader createFromParcel(Parcel source) {
    method newArray (line 111) | public FileDownloadHeader[] newArray(int size) {
    method toString (line 116) | @Override

FILE: library/src/main/java/com/liulishuo/filedownloader/model/FileDownloadModel.java
  class FileDownloadModel (line 36) | @SuppressWarnings("WeakerAccess")
    method setId (line 80) | public void setId(int id) {
    method setUrl (line 84) | public void setUrl(String url) {
    method setPath (line 88) | public void setPath(String path, boolean pathAsDirectory) {
    method setStatus (line 93) | public void setStatus(byte status) {
    method setSoFar (line 97) | public void setSoFar(long soFar) {
    method increaseSoFar (line 101) | public void increaseSoFar(long increaseBytes) {
    method setTotal (line 105) | public void setTotal(long total) {
    method getId (line 110) | public int getId() {
    method getUrl (line 114) | public String getUrl() {
    method getPath (line 124) | public String getPath() {
    method getTargetFilePath (line 139) | public String getTargetFilePath() {
    method getTempFilePath (line 143) | public String getTempFilePath() {
    method getStatus (line 150) | public byte getStatus() {
    method getSoFar (line 154) | public long getSoFar() {
    method getTotal (line 158) | public long getTotal() {
    method isChunked (line 162) | public boolean isChunked() {
    method getETag (line 166) | public String getETag() {
    method setETag (line 170) | public void setETag(String eTag) {
    method getErrMsg (line 174) | public String getErrMsg() {
    method setErrMsg (line 178) | public void setErrMsg(String errMsg) {
    method setFilename (line 182) | public void setFilename(String filename) {
    method isPathAsDirectory (line 186) | public boolean isPathAsDirectory() {
    method getFilename (line 190) | public String getFilename() {
    method setConnectionCount (line 194) | public void setConnectionCount(int connectionCount) {
    method getConnectionCount (line 198) | public int getConnectionCount() {
    method resetConnectionCount (line 205) | public void resetConnectionCount() {
    method toContentValues (line 209) | public ContentValues toContentValues() {
    method isLargeFile (line 231) | public boolean isLargeFile() {
    method deleteTaskFiles (line 235) | public void deleteTaskFiles() {
    method deleteTempFile (line 240) | public void deleteTempFile() {
    method deleteTargetFile (line 252) | public void deleteTargetFile() {
    method toString (line 263) | @Override
    method describeContents (line 272) | @Override
    method writeToParcel (line 277) | @Override
    method FileDownloadModel (line 293) | public FileDownloadModel() {
    method FileDownloadModel (line 298) | protected FileDownloadModel(Parcel in) {
    method createFromParcel (line 315) | @Override
    method newArray (line 320) | @Override

FILE: library/src/main/java/com/liulishuo/filedownloader/model/FileDownloadStatus.java
  class FileDownloadStatus (line 21) | @SuppressWarnings({"checkstyle:linelength", "checkstyle:constantname"})
    method isOver (line 128) | public static boolean isOver(final int status) {
    method isIng (line 132) | public static boolean isIng(final int status) {
    method isKeepAhead (line 136) | public static boolean isKeepAhead(final int status, final int nextStat...
    method isKeepFlow (line 202) | @SuppressWarnings("checkstyle:avoidnestedblocks")
    method isMoreLikelyCompleted (line 277) | public static boolean isMoreLikelyCompleted(BaseDownloadTask task) {

FILE: library/src/main/java/com/liulishuo/filedownloader/model/FileDownloadTaskAtom.java
  class FileDownloadTaskAtom (line 32) | @SuppressWarnings({"WeakerAccess", "deprecation", "DeprecatedIsStillUsed"})
    method FileDownloadTaskAtom (line 38) | public FileDownloadTaskAtom(String url, String path, long totalBytes) {
    method getId (line 46) | public int getId() {
    method getUrl (line 54) | public String getUrl() {
    method setUrl (line 58) | public void setUrl(String url) {
    method getPath (line 62) | public String getPath() {
    method setPath (line 66) | public void setPath(String path) {
    method getTotalBytes (line 70) | public long getTotalBytes() {
    method setTotalBytes (line 74) | public void setTotalBytes(long totalBytes) {
    method describeContents (line 78) | @Override
    method writeToParcel (line 83) | @Override
    method FileDownloadTaskAtom (line 90) | protected FileDownloadTaskAtom(Parcel in) {
    method createFromParcel (line 98) | @Override
    method newArray (line 103) | @Override

FILE: library/src/main/java/com/liulishuo/filedownloader/notification/BaseNotificationItem.java
  class BaseNotificationItem (line 32) | @SuppressWarnings("WeakerAccess")
    method BaseNotificationItem (line 41) | public BaseNotificationItem(final int id, final String title, final St...
    method show (line 48) | public void show(boolean isShowProgress) {
    method show (line 55) | public abstract void show(boolean statusChanged, int status, boolean i...
    method update (line 57) | public void update(final int sofar, final int total) {
    method updateStatus (line 63) | public void updateStatus(final int status) {
    method cancel (line 67) | public void cancel() {
    method getManager (line 73) | protected NotificationManager getManager() {
    method getId (line 81) | public int getId() {
    method setId (line 85) | public void setId(int id) {
    method getSofar (line 89) | public int getSofar() {
    method setSofar (line 93) | public void setSofar(int sofar) {
    method getTotal (line 97) | public int getTotal() {
    method setTotal (line 101) | public void setTotal(int total) {
    method getTitle (line 105) | public String getTitle() {
    method setTitle (line 109) | public void setTitle(String title) {
    method getDesc (line 113) | public String getDesc() {
    method setDesc (line 117) | public void setDesc(String desc) {
    method getStatus (line 121) | public int getStatus() {
    method setStatus (line 126) | public void setStatus(int status) {
    method getLastStatus (line 130) | public int getLastStatus() {
    method isChanged (line 134) | public boolean isChanged() {

FILE: library/src/main/java/com/liulishuo/filedownloader/notification/FileDownloadNotificationHelper.java
  class FileDownloadNotificationHelper (line 30) | @SuppressWarnings("WeakerAccess")
    method get (line 40) | public T get(final int id) {
    method contains (line 44) | public boolean contains(final int id) {
    method remove (line 54) | public T remove(final int id) {
    method add (line 67) | public void add(T notification) {
    method showProgress (line 79) | public void showProgress(final int id, final int sofar, final int tota...
    method showIndeterminate (line 96) | public void showIndeterminate(final int id, int status) {
    method cancel (line 112) | public void cancel(final int id) {
    method clear (line 125) | public void clear() {

FILE: library/src/main/java/com/liulishuo/filedownloader/notification/FileDownloadNotificationListener.java
  class FileDownloadNotificationListener (line 29) | @SuppressWarnings({"WeakerAccess", "UnusedParameters"})
    method FileDownloadNotificationListener (line 33) | public FileDownloadNotificationListener(FileDownloadNotificationHelper...
    method getHelper (line 38) | public FileDownloadNotificationHelper getHelper() {
    method addNotificationItem (line 43) | public void addNotificationItem(int downloadId) {
    method addNotificationItem (line 54) | public void addNotificationItem(BaseDownloadTask task) {
    method destroyNotification (line 71) | public void destroyNotification(BaseDownloadTask task) {
    method showIndeterminate (line 85) | public void showIndeterminate(BaseDownloadTask task) {
    method showProgress (line 93) | public void showProgress(BaseDownloadTask task, int soFarBytes,
    method create (line 107) | protected abstract BaseNotificationItem create(BaseDownloadTask task);
    method interceptCancel (line 119) | protected boolean interceptCancel(BaseDownloadTask task,
    method disableNotification (line 131) | protected boolean disableNotification(final BaseDownloadTask task) {
    method pending (line 135) | @Override
    method started (line 141) | @Override
    method progress (line 147) | @Override
    method retry (line 152) | @Override
    method blockComplete (line 158) | @Override
    method completed (line 162) | @Override
    method paused (line 167) | @Override
    method error (line 172) | @Override
    method warn (line 177) | @Override

FILE: library/src/main/java/com/liulishuo/filedownloader/services/BaseFileServiceUIGuard.java
  class BaseFileServiceUIGuard (line 44) | public abstract class BaseFileServiceUIGuard<CALLBACK extends Binder, IN...
    method getCallback (line 54) | protected CALLBACK getCallback() {
    method getService (line 58) | protected INTERFACE getService() {
    method BaseFileServiceUIGuard (line 62) | protected BaseFileServiceUIGuard(Class<?> serviceClass) {
    method createCallback (line 67) | protected abstract CALLBACK createCallback();
    method onServiceConnected (line 69) | @Override
    method onServiceDisconnected (line 96) | @Override
    method releaseConnect (line 104) | private void releaseConnect(final boolean isLost) {
    method bindStartByContext (line 127) | @Override
    method bindStartByContext (line 132) | @Override
    method unbindByContext (line 171) | @Override
    method isRunServiceForeground (line 193) | @Override
    method asInterface (line 198) | protected abstract INTERFACE asInterface(IBinder service);
    method registerCallback (line 200) | protected abstract void registerCallback(final INTERFACE service, fina...
    method unregisterCallback (line 203) | protected abstract void unregisterCallback(final INTERFACE service, fi...
    method popCache (line 207) | protected Object popCache(final String key) {
    method putCache (line 211) | protected String putCache(final Object object) {
    method isConnected (line 220) | @Override

FILE: library/src/main/java/com/liulishuo/filedownloader/services/DefaultIdGenerator.java
  class DefaultIdGenerator (line 28) | public class DefaultIdGenerator implements FileDownloadHelper.IdGenerator {
    method transOldId (line 30) | @Override
    method generateId (line 35) | @Override

FILE: library/src/main/java/com/liulishuo/filedownloader/services/DownloadMgrInitialParams.java
  class DownloadMgrInitialParams (line 35) | public class DownloadMgrInitialParams {
    method DownloadMgrInitialParams (line 39) | public DownloadMgrInitialParams() {
    method DownloadMgrInitialParams (line 43) | public DownloadMgrInitialParams(InitCustomMaker maker) {
    method getMaxNetworkThreadCount (line 47) | public int getMaxNetworkThreadCount() {
    method createDatabase (line 68) | public FileDownloadDatabase createDatabase() {
    method createOutputStreamCreator (line 86) | public FileDownloadHelper.OutputStreamCreator createOutputStreamCreato...
    method createConnectionCreator (line 104) | public FileDownloadHelper.ConnectionCreator createConnectionCreator() {
    method createConnectionCountAdapter (line 122) | public FileDownloadHelper.ConnectionCountAdapter createConnectionCount...
    method createIdGenerator (line 139) | public FileDownloadHelper.IdGenerator createIdGenerator() {
    method createForegroundServiceConfig (line 157) | public ForegroundServiceConfig createForegroundServiceConfig() {
    method createDefaultForegroundServiceConfig (line 174) | private ForegroundServiceConfig createDefaultForegroundServiceConfig() {
    method createDefaultIdGenerator (line 178) | private FileDownloadHelper.IdGenerator createDefaultIdGenerator() {
    method getDefaultMaxNetworkThreadCount (line 182) | private int getDefaultMaxNetworkThreadCount() {
    method createDefaultDatabase (line 186) | private FileDownloadDatabase createDefaultDatabase() {
    method createDefaultOutputStreamCreator (line 190) | private FileDownloadHelper.OutputStreamCreator createDefaultOutputStre...
    method createDefaultConnectionCreator (line 194) | private FileDownloadHelper.ConnectionCreator createDefaultConnectionCr...
    method createDefaultConnectionCountAdapter (line 198) | private FileDownloadHelper.ConnectionCountAdapter createDefaultConnect...
    class InitCustomMaker (line 202) | public static class InitCustomMaker {
      method idGenerator (line 216) | public InitCustomMaker idGenerator(FileDownloadHelper.IdGenerator id...
      method connectionCountAdapter (line 228) | public InitCustomMaker connectionCountAdapter(
      method database (line 250) | public InitCustomMaker database(FileDownloadHelper.DatabaseCustomMak...
      method maxNetworkThreadCount (line 269) | public InitCustomMaker maxNetworkThreadCount(int maxNetworkThreadCou...
      method outputStreamCreator (line 286) | public InitCustomMaker outputStreamCreator(FileDownloadHelper.Output...
      method connectionCreator (line 314) | public InitCustomMaker connectionCreator(FileDownloadHelper.Connecti...
      method foregroundServiceConfig (line 323) | public InitCustomMaker foregroundServiceConfig(ForegroundServiceConf...
      method commit (line 328) | @SuppressWarnings("EmptyMethod")
      method toString (line 333) | @Override

FILE: library/src/main/java/com/liulishuo/filedownloader/services/FDServiceSeparateHandler.java
  class FDServiceSeparateHandler (line 36) | public class FDServiceSeparateHandler extends IFileDownloadIPCService.Stub
    method callback (line 44) | @SuppressWarnings("UnusedReturnValue")
    method FDServiceSeparateHandler (line 60) | FDServiceSeparateHandler(WeakReference<FileDownloadService> wService,
    method registerCallback (line 68) | @Override
    method unregisterCallback (line 73) | @Override
    method checkDownloading (line 78) | @Override
    method start (line 83) | @Override
    method pause (line 93) | @Override
    method pauseAllTasks (line 98) | @Override
    method setMaxNetworkThreadCount (line 103) | @Override
    method getSofar (line 108) | @Override
    method getTotal (line 113) | @Override
    method getStatus (line 118) | @Override
    method isIdle (line 123) | @Override
    method startForeground (line 128) | @Override
    method stopForeground (line 135) | @Override
    method clearTaskData (line 142) | @Override
    method clearAllTaskData (line 147) | @Override
    method onStartCommand (line 152) | @Override
    method onBind (line 156) | @Override
    method onDestroy (line 161) | @Override
    method receive (line 166) | @Override

FILE: library/src/main/java/com/liulishuo/filedownloader/services/FDServiceSharedHandler.java
  class FDServiceSharedHandler (line 32) | public class FDServiceSharedHandler extends IFileDownloadIPCService.Stub
    method FDServiceSharedHandler (line 37) | FDServiceSharedHandler(WeakReference<FileDownloadService> wService,
    method registerCallback (line 43) | @Override
    method unregisterCallback (line 47) | @Override
    method checkDownloading (line 51) | @Override
    method start (line 56) | @Override
    method pause (line 66) | @Override
    method pauseAllTasks (line 71) | @Override
    method setMaxNetworkThreadCount (line 76) | @Override
    method getSofar (line 81) | @Override
    method getTotal (line 86) | @Override
    method getStatus (line 91) | @Override
    method isIdle (line 96) | @Override
    method startForeground (line 101) | @Override
    method stopForeground (line 108) | @Override
    method clearTaskData (line 115) | @Override
    method clearAllTaskData (line 120) | @Override
    method onStartCommand (line 125) | @Override
    method onBind (line 131) | @Override
    method onDestroy (line 136) | @Override
    type FileDownloadServiceSharedConnection (line 142) | public interface FileDownloadServiceSharedConnection {
      method onConnected (line 143) | void onConnected(FDServiceSharedHandler handler);
      method onDisconnected (line 145) | void onDisconnected();

FILE: library/src/main/java/com/liulishuo/filedownloader/services/FileDownloadBroadcastHandler.java
  class FileDownloadBroadcastHandler (line 29) | public class FileDownloadBroadcastHandler {
    method parseIntent (line 39) | public static FileDownloadModel parseIntent(Intent intent) {
    method sendCompletedBroadcast (line 50) | public static void sendCompletedBroadcast(FileDownloadModel model) {

FILE: library/src/main/java/com/liulishuo/filedownloader/services/FileDownloadManager.java
  class FileDownloadManager (line 48) | class FileDownloadManager implements IThreadPoolMonitor {
    method FileDownloadManager (line 52) | FileDownloadManager() {
    method start (line 59) | public synchronized void start(final String url, final String path,
    method isDownloading (line 204) | public boolean isDownloading(String url, String path) {
    method isDownloading (line 208) | public boolean isDownloading(int id) {
    method pause (line 212) | public boolean pause(final int id) {
    method pauseAll (line 230) | public void pauseAll() {
    method getSoFar (line 242) | public long getSoFar(final int id) {
    method getTotal (line 261) | public long getTotal(final int id) {
    method getStatus (line 270) | public byte getStatus(final int id) {
    method isIdle (line 279) | public boolean isIdle() {
    method setMaxNetworkThreadCount (line 283) | public synchronized boolean setMaxNetworkThreadCount(int count) {
    method isDownloading (line 287) | @Override
    method findRunningTaskIdBySameTempPath (line 330) | @Override
    method clearTaskData (line 335) | public boolean clearTaskData(int id) {
    method clearAllTaskData (line 351) | public void clearAllTaskData() {

FILE: library/src/main/java/com/liulishuo/filedownloader/services/FileDownloadService.java
  class FileDownloadService (line 46) | @SuppressLint("Registered")
    method onCreate (line 52) | @Override
    method onStartCommand (line 79) | @Override
    method inspectRunServiceForeground (line 86) | private void inspectRunServiceForeground(Intent intent) {
    method onDestroy (line 111) | @Override
    method onBind (line 118) | @Override
    class SharedMainProcessService (line 123) | public static class SharedMainProcessService extends FileDownloadServi...
    class SeparateProcessService (line 126) | public static class SeparateProcessService extends FileDownloadService {

FILE: library/src/main/java/com/liulishuo/filedownloader/services/FileDownloadThreadPool.java
  class FileDownloadThreadPool (line 33) | class FileDownloadThreadPool {
    method FileDownloadThreadPool (line 42) | FileDownloadThreadPool(final int maxNetworkThreadCount) {
    method setMaxNetworkThreadCount (line 48) | public synchronized boolean setMaxNetworkThreadCount(int count) {
    method execute (line 75) | public void execute(DownloadLaunchRunnable launchRunnable) {
    method cancel (line 91) | public void cancel(final int id) {
    method filterOutNoExist (line 111) | private synchronized void filterOutNoExist() {
    method isInThreadPool (line 124) | public synchronized boolean isInThreadPool(final int downloadId) {
    method findRunningTaskIdBySameTempPath (line 129) | public synchronized int findRunningTaskIdBySameTempPath(String tempFil...
    method exactSize (line 161) | public synchronized int exactSize() {
    method getAllExactRunningDownloadIds (line 166) | public synchronized List<Integer> getAllExactRunningDownloadIds() {

FILE: library/src/main/java/com/liulishuo/filedownloader/services/ForegroundServiceConfig.java
  class ForegroundServiceConfig (line 26) | @TargetApi(26)
    method ForegroundServiceConfig (line 34) | private ForegroundServiceConfig() {
    method getNotificationId (line 41) | public int getNotificationId() {
    method getNotificationChannelId (line 45) | public String getNotificationChannelId() {
    method getNotificationChannelName (line 49) | public String getNotificationChannelName() {
    method getNotification (line 53) | public Notification getNotification(Context context) {
    method isNeedRecreateChannelId (line 63) | public boolean isNeedRecreateChannelId() {
    method setNotificationId (line 67) | public void setNotificationId(int notificationId) {
    method setNotificationChannelId (line 71) | public void setNotificationChannelId(String notificationChannelId) {
    method setNotificationChannelName (line 75) | public void setNotificationChannelName(String notificationChannelName) {
    method setNotification (line 79) | public void setNotification(Notification notification) {
    method setNeedRecreateChannelId (line 83) | public void setNeedRecreateChannelId(boolean needRecreateChannelId) {
    method buildDefaultNotification (line 87) | private Notification buildDefaultNotification(Context context) {
    method toString (line 97) | @Override
    class Builder (line 110) | public static class Builder {
      method notificationId (line 117) | public Builder notificationId(int notificationId) {
      method notificationChannelId (line 122) | public Builder notificationChannelId(String notificationChannelId) {
      method notificationChannelName (line 127) | public Builder notificationChannelName(String notificationChannelNam...
      method notification (line 132) | public Builder notification(Notification notification) {
      method needRecreateChannelId (line 137) | public Builder needRecreateChannelId(boolean needRecreateChannelId) {
      method build (line 142) | public ForegroundServiceConfig build() {

FILE: library/src/main/java/com/liulishuo/filedownloader/services/IFileDownloadServiceHandler.java
  type IFileDownloadServiceHandler (line 28) | @SuppressWarnings("UnusedParameters")
    method onStartCommand (line 36) | void onStartCommand(Intent intent, int flags, int startId);
    method onBind (line 43) | IBinder onBind(Intent intent);
    method onDestroy (line 51) | void onDestroy();

FILE: library/src/main/java/com/liulishuo/filedownloader/stream/FileDownloadOutputStream.java
  type FileDownloadOutputStream (line 30) | public interface FileDownloadOutputStream {
    method write (line 41) | void write(byte b[], int off, int len) throws IOException;
    method flushAndSync (line 57) | void flushAndSync() throws IOException;
    method close (line 68) | void close() throws IOException;
    method seek (line 89) | void seek(long offset) throws IOException, IllegalAccessException;
    method setLength (line 109) | void setLength(final long newLength) throws IOException, IllegalAccess...

FILE: library/src/main/java/com/liulishuo/filedownloader/stream/FileDownloadRandomAccessFile.java
  class FileDownloadRandomAccessFile (line 32) | public class FileDownloadRandomAccessFile implements FileDownloadOutputS...
    method FileDownloadRandomAccessFile (line 37) | FileDownloadRandomAccessFile(File file) throws IOException {
    method write (line 43) | @Override
    method flushAndSync (line 48) | @Override
    method close (line 54) | @Override
    method seek (line 60) | @Override
    method setLength (line 65) | @Override
    class Creator (line 70) | public static class Creator implements FileDownloadHelper.OutputStream...
      method create (line 72) | @Override
      method supportSeek (line 77) | @Override

FILE: library/src/main/java/com/liulishuo/filedownloader/util/DownloadServiceNotConnectedHelper.java
  class DownloadServiceNotConnectedHelper (line 30) | public class DownloadServiceNotConnectedHelper {
    method start (line 40) | public static boolean start(final String url, final String path,
    method pause (line 47) | public static boolean pause(final int id) {
    method isDownloading (line 52) | public static boolean isDownloading(final String url, final String pat...
    method getSofar (line 57) | public static long getSofar(final int id) {
    method getTotal (line 62) | public static long getTotal(final int id) {
    method getStatus (line 67) | public static byte getStatus(final int id) {
    method pauseAllTasks (line 72) | public static void pauseAllTasks() {
    method isIdle (line 76) | public static boolean isIdle() {
    method startForeground (line 81) | public static void startForeground(int notificationId, Notification no...
    method stopForeground (line 86) | public static void stopForeground(boolean removeNotification) {
    method setMaxNetworkThreadCount (line 91) | public static boolean setMaxNetworkThreadCount(int count) {
    method clearTaskData (line 96) | public static boolean clearTaskData(int id) {
    method clearAllTaskData (line 101) | public static boolean clearAllTaskData() {
    method log (line 106) | private static void log(String message, Object... args) {

FILE: library/src/main/java/com/liulishuo/filedownloader/util/ExtraKeys.java
  class ExtraKeys (line 19) | public class ExtraKeys {

FILE: library/src/main/java/com/liulishuo/filedownloader/util/FileDownloadExecutors.java
  class FileDownloadExecutors (line 36) | public class FileDownloadExecutors {
    method newFixedThreadPool (line 39) | public static ThreadPoolExecutor newFixedThreadPool(String prefix) {
    method newDefaultThreadPool (line 45) | public static ThreadPoolExecutor newDefaultThreadPool(int nThreads, St...
    method newDefaultThreadPool (line 49) | public static ThreadPoolExecutor newDefaultThreadPool(int nThreads,
    class FileDownloadThreadFactory (line 59) | static class FileDownloadThreadFactory implements ThreadFactory {
      method FileDownloadThreadFactory (line 65) | FileDownloadThreadFactory(String prefix) {
      method newThread (line 70) | @Override

FILE: library/src/main/java/com/liulishuo/filedownloader/util/FileDownloadHelper.java
  class FileDownloadHelper (line 41) | public class FileDownloadHelper {
    method holdContext (line 46) | public static void holdContext(final Context context) {
    method getAppContext (line 50) | public static Context getAppContext() {
    type IdGenerator (line 54) | @SuppressWarnings("UnusedParameters")
      method transOldId (line 72) | int transOldId(final int oldId, final String url, final String path,
      method generateId (line 100) | int generateId(final String url, final String path, final boolean pa...
    type ConnectionCountAdapter (line 103) | @SuppressWarnings("UnusedParameters")
      method determineConnectionCount (line 128) | int determineConnectionCount(int downloadId, String url, String path...
    type DatabaseCustomMaker (line 131) | public interface DatabaseCustomMaker {
      method customMake (line 146) | FileDownloadDatabase customMake();
    type OutputStreamCreator (line 149) | public interface OutputStreamCreator {
      method create (line 165) | FileDownloadOutputStream create(File file) throws IOException;
      method supportSeek (line 174) | boolean supportSeek();
    type ConnectionCreator (line 177) | public interface ConnectionCreator {
      method create (line 186) | FileDownloadConnection create(String url) throws IOException;
    method inspectAndInflowDownloaded (line 200) | public static boolean inspectAndInflowDownloaded(int id, String path, ...
    method inspectAndInflowDownloading (line 227) | public static boolean inspectAndInflowDownloading(int id, FileDownload...
    method inspectAndInflowConflictPath (line 251) | public static boolean inspectAndInflowConflictPath(int id, long sofar,

FILE: library/src/main/java/com/liulishuo/filedownloader/util/FileDownloadLog.java
  class FileDownloadLog (line 27) | public class FileDownloadLog {
    method e (line 33) | public static void e(Object o, Throwable e, String msg, Object... args) {
    method e (line 37) | public static void e(Object o, String msg, Object... args) {
    method i (line 41) | public static void i(Object o, String msg, Object... args) {
    method d (line 45) | public static void d(Object o, String msg, Object... args) {
    method w (line 49) | public static void w(Object o, String msg, Object... args) {
    method v (line 53) | public static void v(Object o, String msg, Object... args) {
    method log (line 57) | private static void log(int priority, Object o, String message, Object...
    method log (line 61) | private static void log(int priority, Object o, Throwable throwable, S...
    method getTag (line 74) | private static String getTag(final Object o) {

FILE: library/src/main/java/com/liulishuo/filedownloader/util/FileDownloadProperties.java
  class FileDownloadProperties (line 126) | public class FileDownloadProperties {
    class HolderClass (line 148) | public static class HolderClass {
    method getImpl (line 152) | public static FileDownloadProperties getImpl() {
    method FileDownloadProperties (line 160) | private FileDownloadProperties() {
    method getValidNetworkThreadCount (line 322) | public static int getValidNetworkThreadCount(int requireCount) {

FILE: library/src/main/java/com/liulishuo/filedownloader/util/FileDownloadSerialQueue.java
  class FileDownloadSerialQueue (line 36) | public class FileDownloadSerialQueue {
    method FileDownloadSerialQueue (line 51) | public FileDownloadSerialQueue() {
    method enqueue (line 64) | public void enqueue(BaseDownloadTask task) {
    method pause (line 84) | public void pause() {
    method resume (line 107) | public void resume() {
    method getWorkingTaskId (line 134) | public int getWorkingTaskId() {
    method getWaitingTaskCount (line 143) | public int getWaitingTaskCount() {
    method shutdown (line 152) | public List<BaseDownloadTask> shutdown() {
    class SerialLoop (line 169) | private class SerialLoop implements Handler.Callback {
      method handleMessage (line 171) | @Override
    class SerialFinishCallback (line 189) | private static class SerialFinishCallback implements BaseDownloadTask....
      method SerialFinishCallback (line 192) | SerialFinishCallback(WeakReference<FileDownloadSerialQueue> queueWea...
      method over (line 196) | @Override
    method sendNext (line 217) | private void sendNext() {

FILE: library/src/main/java/com/liulishuo/filedownloader/util/FileDownloadUtils.java
  class FileDownloadUtils (line 58) | @SuppressWarnings({"SameParameterValue", "WeakerAccess"})
    method setMinProgressStep (line 79) | public static void setMinProgressStep(int minProgressStep) throws Ille...
    method setMinProgressTime (line 106) | public static void setMinProgressTime(long minProgressTime) throws Ill...
    method getMinProgressStep (line 118) | public static int getMinProgressStep() {
    method getMinProgressTime (line 122) | public static long getMinProgressTime() {
    method isFilenameValid (line 129) | @SuppressWarnings({"SameReturnValue", "UnusedParameters"})
    method getDefaultSaveRootPath (line 142) | public static String getDefaultSaveRootPath() {
    method getDefaultSaveFilePath (line 163) | public static String getDefaultSaveFilePath(final String url) {
    method generateFileName (line 167) | public static String generateFileName(final String url) {
    method generateFilePath (line 174) | public static String generateFilePath(String directory, String filenam...
    method setDefaultSaveRootPath (line 192) | public static void setDefaultSaveRootPath(final String path) {
    method getTempPath (line 201) | public static String getTempPath(final String targetPath) {
    method generateId (line 210) | public static int generateId(final String url, final String path) {
    method generateId (line 223) | public static int generateId(final String url, final String path,
    method md5 (line 229) | public static String md5(String string) {
    method getStack (line 248) | public static String getStack() {
    method getStack (line 252) | public static String getStack(final boolean printLine) {
    method getStack (line 257) | public static String getStack(final StackTraceElement[] stackTrace, fi...
    method isDownloaderProcess (line 289) | public static boolean isDownloaderProcess(final Context context) {
    method convertHeaderString (line 334) | public static String[] convertHeaderString(final String nameAndValuesS...
    method getFreeSpaceBytes (line 352) | public static long getFreeSpaceBytes(final String path) {
    method formatString (line 365) | public static String formatString(final String msg, Object... args) {
    method markConverted (line 372) | @SuppressWarnings("ResultOfMethodCallIgnored")
    method isFilenameConverted (line 395) | public static boolean isFilenameConverted(final Context context) {
    method getConvertedMarkedFile (line 403) | public static File getConvertedMarkedFile(final Context context) {
    method parseContentRangeFoInstanceLength (line 415) | public static long parseContentRangeFoInstanceLength(String contentRan...
    method parseContentDisposition (line 439) | public static String parseContentDisposition(String contentDisposition) {
    method getTargetFilePath (line 471) | public static String getTargetFilePath(String path, boolean pathAsDire...
    method getParent (line 492) | public static String getParent(final String path) {
    method getThreadPoolName (line 513) | public static String getThreadPoolName(String name) {
    method isNetworkNotOnWifiType (line 517) | public static boolean isNetworkNotOnWifiType() {
    method checkPermission (line 533) | public static boolean checkPermission(String permission) {
    method convertContentLengthString (line 539) | public static long convertContentLengthString(String s) {
    method findEtag (line 548) | public static String findEtag(final int id, FileDownloadConnection con...
    method isAcceptRange (line 563) | public static boolean isAcceptRange(int responseCode, FileDownloadConn...
    method findInstanceLengthForTrial (line 574) | public static long findInstanceLengthForTrial(FileDownloadConnection c...
    method findInstanceLengthFromContentRange (line 592) | public static long findInstanceLengthFromContentRange(FileDownloadConn...
    method getContentRangeHeader (line 596) | private static String getContentRangeHeader(FileDownloadConnection con...
    method findContentLength (line 600) | public static long findContentLength(final int id, FileDownloadConnect...
    method findContentLengthFromContentRange (line 634) | public static long findContentLengthFromContentRange(FileDownloadConne...
    method parseContentLengthFromContentRange (line 641) | public static long parseContentLengthFromContentRange(String contentRa...
    method findFilename (line 659) | public static String findFilename(FileDownloadConnection connection, S...
    method createOutputStream (line 680) | public static FileDownloadOutputStream createOutputStream(final String...
    method isBreakpointAvailable (line 712) | public static boolean isBreakpointAvailable(final int id, final FileDo...
    method isBreakpointAvailable (line 719) | public static boolean isBreakpointAvailable(final int id, final FileDo...
    method isBreakpointAvailable (line 739) | public static boolean isBreakpointAvailable(final int id, final FileDo...
    method deleteTaskFiles (line 811) | public static void deleteTaskFiles(String targetFilepath, String tempF...
    method deleteTempFile (line 816) | public static void deleteTempFile(String tempFilePath) {
    method deleteTargetFile (line 826) | public static void deleteTargetFile(String targetFilePath) {
    method isNeedSync (line 836) | public static boolean isNeedSync(long bytesDelta, long timestampDelta) {
    method defaultUserAgent (line 841) | public static String defaultUserAgent() {
    method isAppOnForeground (line 845) | private static boolean isAppOnForeground(Context context) {
    method needMakeServiceForeground (line 874) | public static boolean needMakeServiceForeground(Context context) {
    method findFileNameFromUrl (line 878) | static String findFileNameFromUrl(String url) {

FILE: library/src/test/java/com/liulishuo/filedownloader/FileDownloaderTest.java
  class FileDownloaderTest (line 30) | @RunWith(RobolectricTestRunner.class)
    method setup_withContext_hold (line 33) | @Test
    method setupOnApplicationOnCreate_withContext_hold (line 41) | @Test
    method setupOnApplicationOnCreate_InitCustomMaker_valid (line 49) | @Test

FILE: library/src/test/java/com/liulishuo/filedownloader/connection/FileDownloadUrlConnectionTest.java
  class FileDownloadUrlConnectionTest (line 34) | @SuppressWarnings("CanBeFinal")
    method setUp (line 46) | @Before
    method construct_noConfiguration_noAssigned (line 54) | @Test
    method construct_validConfiguration_Assigned (line 64) | @Test

FILE: library/src/test/java/com/liulishuo/filedownloader/download/DownloadLaunchRunnableTest.java
  class DownloadLaunchRunnableTest (line 49) | @RunWith(RobolectricTestRunner.class)
    method onRetry_validRetryTimesDecrease_only1 (line 53) | @Test
    method run_noWifiButRequired_callbackNetworkError (line 69) | @Test
    method mockContextNoWifiState (line 100) | private static void mockContextNoWifiState(Context context) {
    method getMockNonOptDatabaseMaker (line 111) | private static FileDownloadHelper.DatabaseCustomMaker getMockNonOptDat...

FILE: library/src/test/java/com/liulishuo/filedownloader/download/DownloadRunnableTest.java
  class DownloadRunnableTest (line 37) | @SuppressWarnings("ALL")
    method setUp (line 51) | @Before
    method run_withConnectFailed_retry (line 63) | @Test
    method run_responseCodeNotMet_error (line 72) | @Test
    class MockProcessCallback (line 87) | private static class MockProcessCallback implements ProcessCallback {
      method onProgress (line 89) | @Override
      method onCompleted (line 93) | @Override
      method isRetry (line 99) | @Override
      method onError (line 109) | @Override
      method onRetry (line 114) | @Override
      method syncProgressFromCache (line 118) | @Override

FILE: library/src/test/java/com/liulishuo/filedownloader/util/FileDownloadUtilsTest.java
  class FileDownloadUtilsTest (line 33) | @RunWith(RobolectricTestRunner.class)
    method parseContentDisposition (line 37) | @Test
    method parseContentLengthFromContentRange_withNullContentRange (line 64) | @Test
    method parseContentLengthFromContentRange_withEmptyContentRange (line 70) | @Test
    method parseContentLengthFromContentRange_withStartToEndRange (line 76) | @Test
    method parseContentLengthFromContentRange_withUnavailableContentRange (line 83) | @Test
    method findFilename_securityIssue (line 92) | @Test
    method getFileNameFromUrl (line 111) | @Test
Condensed preview — 189 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,213K chars).
[
  {
    "path": ".github/issue_template.md",
    "chars": 1108,
    "preview": "#### Before Issue\n\n1. Please search on the [Issues](https://github.com/lingochamp/FileDownloader/issues)\n2. Please searc"
  },
  {
    "path": ".gitignore",
    "chars": 192,
    "preview": "*.iml\n.gradle\n/local.properties\n/.idea/workspace.xml\n/.idea/libraries\n/.idea/misc.xml\n/.idea/checkstyle-idea.xml\n/.idea/"
  },
  {
    "path": ".idea/codeStyleSettings.xml",
    "chars": 8805,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"ProjectCodeStyleSettingsManager\">\n    <o"
  },
  {
    "path": ".idea/codeStyles/Project.xml",
    "chars": 7929,
    "preview": "<component name=\"ProjectCodeStyleConfiguration\">\n  <code_scheme name=\"Project\" version=\"173\">\n    <option name=\"RIGHT_MA"
  },
  {
    "path": ".idea/codeStyles/codeStyleConfig.xml",
    "chars": 153,
    "preview": "<component name=\"ProjectCodeStyleConfiguration\">\n  <state>\n    <option name=\"PREFERRED_PROJECT_CODE_STYLE\" value=\"Defaul"
  },
  {
    "path": ".idea/compiler.xml",
    "chars": 709,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"CompilerConfiguration\">\n    <option name"
  },
  {
    "path": ".idea/copyright/apache2.xml",
    "chars": 785,
    "preview": "<component name=\"CopyrightManager\">\n  <copyright>\n    <option name=\"myName\" value=\"apache2\" />\n    <option name=\"notice\""
  },
  {
    "path": ".idea/copyright/profiles_settings.xml",
    "chars": 739,
    "preview": "<component name=\"CopyrightManager\">\n  <settings default=\"apache2\">\n    <LanguageOptions name=\"Groovy\">\n      <option nam"
  },
  {
    "path": ".idea/dictionaries/Jacksgong.xml",
    "chars": 532,
    "preview": "<component name=\"ProjectDictionaryState\">\n  <dictionary name=\"Jacksgong\">\n    <words>\n      <w>buildship</w>\n      <w>ch"
  },
  {
    "path": ".idea/encodings.xml",
    "chars": 159,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"Encoding\">\n    <file url=\"PROJECT\" chars"
  },
  {
    "path": ".idea/gradle.xml",
    "chars": 811,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"GradleSettings\">\n    <option name=\"linke"
  },
  {
    "path": ".idea/inspectionProfiles/Project_Default.xml",
    "chars": 2577,
    "preview": "<component name=\"InspectionProjectProfileManager\">\n  <profile version=\"1.0\">\n    <option name=\"myName\" value=\"Project De"
  },
  {
    "path": ".idea/inspectionProfiles/profiles_settings.xml",
    "chars": 235,
    "preview": "<component name=\"InspectionProjectProfileManager\">\n  <settings>\n    <option name=\"PROJECT_PROFILE\" value=\"Project Defaul"
  },
  {
    "path": ".idea/modules.xml",
    "chars": 482,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"ProjectModuleManager\">\n    <modules>\n   "
  },
  {
    "path": ".idea/runConfigurations.xml",
    "chars": 564,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"RunConfigurationProducerService\">\n    <o"
  },
  {
    "path": ".idea/vcs.xml",
    "chars": 180,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"VcsDirectoryMappings\">\n    <mapping dire"
  },
  {
    "path": ".travis.yml",
    "chars": 650,
    "preview": "language: android\n\njdk:\n# build-tools 24.0.2 need jdk8 or above.\n- oraclejdk8\nandroid:\n  components:\n    # Ref https://g"
  },
  {
    "path": "CHANGELOG-ZH.md",
    "chars": 30484,
    "preview": "# Change log\n\n> [ Change log in english](https://github.com/lingochamp/FileDownloader/blob/master/CHANGELOG.md)\n\n## Vers"
  },
  {
    "path": "CHANGELOG.md",
    "chars": 48860,
    "preview": "# Change log\n\n> [中文迭代日志](https://github.com/lingochamp/FileDownloader/blob/master/CHANGELOG-ZH.md)\n\n## Version 1.7.7\n\n- "
  },
  {
    "path": "LICENSE.txt",
    "chars": 11329,
    "preview": "\n                                 Apache License\n                           Version 2.0, January 2004\n                  "
  },
  {
    "path": "README-zh.md",
    "chars": 21584,
    "preview": "# FileDownloader\nAndroid 文件下载引擎,稳定、高效、灵活、简单易用\n\n[![Gitter][gitter_svg]][gitter_url]\n[![Download][bintray_svg]][bintray_ur"
  },
  {
    "path": "README.md",
    "chars": 9649,
    "preview": "# FileDownloader\nAndroid multi-task file download engine.\n\n\n[![Download][bintray_svg]][bintray_url]\n![][file_downloader_"
  },
  {
    "path": "build.gradle",
    "chars": 432,
    "preview": "buildscript {\n    repositories {\n        jcenter()\n        google()\n    }\n    dependencies {\n        classpath 'com.andr"
  },
  {
    "path": "checkstyle.xml",
    "chars": 6063,
    "preview": "<?xml version=\"1.0\"?>\n<!DOCTYPE module PUBLIC\n    \"-//Puppy Crawl//DTD Check Configuration 1.3//EN\"\n    \"http://checksty"
  },
  {
    "path": "demo/.gitignore",
    "chars": 7,
    "preview": "/build\n"
  },
  {
    "path": "demo/build.gradle",
    "chars": 1766,
    "preview": "apply plugin: 'com.android.application'\n\nandroid {\n    signingConfigs {\n        release {\n            keyAlias 'FileDown"
  },
  {
    "path": "demo/proguard-rules.pro",
    "chars": 106,
    "preview": "# filedownloader uses okhttp3-lib, so need add below proguard rules.\n-dontwarn okhttp3.*\n-dontwarn okio.**"
  },
  {
    "path": "demo/src/main/AndroidManifest.xml",
    "chars": 2092,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package="
  },
  {
    "path": "demo/src/main/assets/filedownloader.properties",
    "chars": 3893,
    "preview": "# If you occur exception: 'can't know the size of the download file, and its Transfer-Encoding is not Chunked either',\n#"
  },
  {
    "path": "demo/src/main/java/com/liulishuo/filedownloader/demo/Constant.java",
    "chars": 119661,
    "preview": "package com.liulishuo.filedownloader.demo;\n\n/**\n * Created by Jacksgong on 12/19/15.\n */\npublic interface Constant {\n\n  "
  },
  {
    "path": "demo/src/main/java/com/liulishuo/filedownloader/demo/DemoApplication.java",
    "chars": 3324,
    "preview": "package com.liulishuo.filedownloader.demo;\n\nimport android.app.Application;\nimport android.content.Context;\nimport andro"
  },
  {
    "path": "demo/src/main/java/com/liulishuo/filedownloader/demo/GlobalMonitor.java",
    "chars": 1998,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "demo/src/main/java/com/liulishuo/filedownloader/demo/HybridTestActivity.java",
    "chars": 10156,
    "preview": "package com.liulishuo.filedownloader.demo;\n\nimport android.os.Bundle;\nimport android.os.Handler;\nimport android.os.Messa"
  },
  {
    "path": "demo/src/main/java/com/liulishuo/filedownloader/demo/MainActivity.java",
    "chars": 3006,
    "preview": "package com.liulishuo.filedownloader.demo;\n\nimport android.content.Intent;\nimport android.net.Uri;\nimport android.os.Bun"
  },
  {
    "path": "demo/src/main/java/com/liulishuo/filedownloader/demo/MultitaskTestActivity.java",
    "chars": 20361,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "demo/src/main/java/com/liulishuo/filedownloader/demo/NotificationSampleActivity.java",
    "chars": 10664,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "demo/src/main/java/com/liulishuo/filedownloader/demo/SingleTaskTestActivity.java",
    "chars": 14392,
    "preview": "package com.liulishuo.filedownloader.demo;\n\nimport android.os.Bundle;\nimport android.support.design.widget.Snackbar;\nimp"
  },
  {
    "path": "demo/src/main/java/com/liulishuo/filedownloader/demo/TasksManagerDemoActivity.java",
    "chars": 25655,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "demo/src/main/java/com/liulishuo/filedownloader/demo/Utils.java",
    "chars": 2028,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "demo/src/main/java/com/liulishuo/filedownloader/demo/performance/IntParcel.java",
    "chars": 1737,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "demo/src/main/java/com/liulishuo/filedownloader/demo/performance/LongParcel.java",
    "chars": 1754,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "demo/src/main/java/com/liulishuo/filedownloader/demo/performance/PerformanceTestActivity.java",
    "chars": 10921,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "demo/src/main/res/drawable/bg_item_task_manager.xml",
    "chars": 1027,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ Copyright (c) 2015 LingoChamp Inc.\n  ~\n  ~ Licensed under the Apache Lice"
  },
  {
    "path": "demo/src/main/res/layout/activity_hybrid_test.xml",
    "chars": 2005,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    an"
  },
  {
    "path": "demo/src/main/res/layout/activity_main.xml",
    "chars": 1130,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    andr"
  },
  {
    "path": "demo/src/main/res/layout/activity_mutitask_test.xml",
    "chars": 9908,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ Copyright (c) 2015 LingoChamp Inc.\n  ~\n  ~ Licensed under the Apache Lice"
  },
  {
    "path": "demo/src/main/res/layout/activity_notification_minset.xml",
    "chars": 2355,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ Copyright (c) 2015 LingoChamp Inc.\n  ~\n  ~ Licensed under the Apache Lice"
  },
  {
    "path": "demo/src/main/res/layout/activity_notification_sample.xml",
    "chars": 3008,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ Copyright (c) 2015 LingoChamp Inc.\n  ~\n  ~ Licensed under the Apache Lice"
  },
  {
    "path": "demo/src/main/res/layout/activity_performance.xml",
    "chars": 2850,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ Copyright (c) 2015 LingoChamp Inc.\n  ~\n  ~ Licensed under the Apache Lice"
  },
  {
    "path": "demo/src/main/res/layout/activity_single.xml",
    "chars": 9687,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<ScrollView xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    androi"
  },
  {
    "path": "demo/src/main/res/layout/activity_tasks_manager_demo.xml",
    "chars": 877,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ Copyright (c) 2015 LingoChamp Inc.\n  ~\n  ~ Licensed under the Apache Lice"
  },
  {
    "path": "demo/src/main/res/layout/item_tasks_manager.xml",
    "chars": 2440,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?><!--\n  ~ Copyright (c) 2015 LingoChamp Inc.\n  ~\n  ~ Licensed under the Apache Lice"
  },
  {
    "path": "demo/src/main/res/menu/menu_main.xml",
    "chars": 327,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"h"
  },
  {
    "path": "demo/src/main/res/values/colors.xml",
    "chars": 208,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"colorPrimary\">#3F51B5</color>\n    <color name=\"color"
  },
  {
    "path": "demo/src/main/res/values/donottranslate.xml",
    "chars": 1639,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n  ~ Copyright (c) 2015 LingoChamp Inc.\n  ~\n  ~ Licensed under the Apache Lic"
  },
  {
    "path": "demo/src/main/res/values/strings.xml",
    "chars": 3552,
    "preview": "<resources>\n    <string name=\"app_name\">FileDownloader Demo</string>\n\n    <string name=\"start\">Start</string>\n    <strin"
  },
  {
    "path": "demo/src/main/res/values/styles.xml",
    "chars": 1381,
    "preview": "<resources>\n\n    <!-- Base application theme. -->\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.DarkActionBar"
  },
  {
    "path": "demo/src/main/res/values-zh/strings.xml",
    "chars": 3307,
    "preview": "<!--\n  ~ Copyright (c) 2015 LingoChamp Inc.\n  ~\n  ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n  ~ "
  },
  {
    "path": "demo/src/main/res/xml/network_security_config.xml",
    "chars": 1321,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<network-security-config>\n    <domain-config cleartextTrafficPermitted=\"true\">\n  "
  },
  {
    "path": "gradle/bintray.gradle",
    "chars": 3330,
    "preview": "/*\n * Copyright (c) 2018 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "gradle/mvn-local.gradle",
    "chars": 1721,
    "preview": "/*\n * Copyright (c) 2018 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "gradle/mvn-push.gradle",
    "chars": 5825,
    "preview": "/*\n * Copyright 2013 Chris Banes\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
  },
  {
    "path": "gradle/wrapper/gradle-wrapper.properties",
    "chars": 233,
    "preview": "#Wed Feb 20 10:49:17 CST 2019\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_"
  },
  {
    "path": "gradle.properties",
    "chars": 636,
    "preview": "VERSION_NAME=1.7.8-SNAPSHOT\nBUILD_TOOLS_VERSION=28.0.3\nCOMPILE_SDK_VERSION=28\n\nGROUP=com.liulishuo.filedownloader\n\nPOM_U"
  },
  {
    "path": "gradlew",
    "chars": 4971,
    "preview": "#!/usr/bin/env bash\n\n##############################################################################\n##\n##  Gradle start "
  },
  {
    "path": "gradlew.bat",
    "chars": 2404,
    "preview": "@if \"%DEBUG%\" == \"\" @echo off\r\n@rem ##########################################################################\r\n@rem\r\n@r"
  },
  {
    "path": "install.sh",
    "chars": 267,
    "preview": "#!/bin/bash\n\nadb install -r demo/build/outputs/apk/demo-debug.apk\n\nif [ \"$1\" == \"y\" ]; then\n\tadb shell am start -n \"com."
  },
  {
    "path": "library/.gitignore",
    "chars": 7,
    "preview": "/build\n"
  },
  {
    "path": "library/LICENSE",
    "chars": 559,
    "preview": "Copyright (c) 2015 LingoChamp Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this"
  },
  {
    "path": "library/build.gradle",
    "chars": 901,
    "preview": "apply plugin: 'com.android.library'\n\nandroid {\n    compileSdkVersion COMPILE_SDK_VERSION as int\n    buildToolsVersion BU"
  },
  {
    "path": "library/gradle.properties",
    "chars": 123,
    "preview": "POM_ARTIFACT_ID=library\nPOM_NAME=FileDownloader\nPOM_DESCRIPTION=Android multi-task file download engine.\nPOM_PACKAGING=a"
  },
  {
    "path": "library/proguard-rules.pro",
    "chars": 671,
    "preview": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /U"
  },
  {
    "path": "library/src/main/AndroidManifest.xml",
    "chars": 607,
    "preview": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"com.liulishuo.filedownloader\">\n\n    <!"
  },
  {
    "path": "library/src/main/aidl/com/liulishuo/filedownloader/i/IFileDownloadIPCCallback.aidl",
    "chars": 197,
    "preview": "package com.liulishuo.filedownloader.i;\n\nimport com.liulishuo.filedownloader.message.MessageSnapshot;\n\ninterface IFileDo"
  },
  {
    "path": "library/src/main/aidl/com/liulishuo/filedownloader/i/IFileDownloadIPCService.aidl",
    "chars": 1730,
    "preview": "package com.liulishuo.filedownloader.i;\n\nimport com.liulishuo.filedownloader.i.IFileDownloadIPCCallback;\nimport com.liul"
  },
  {
    "path": "library/src/main/aidl/com/liulishuo/filedownloader/message/MessageSnapshot.aidl",
    "chars": 74,
    "preview": "package com.liulishuo.filedownloader.message;\n\nparcelable MessageSnapshot;"
  },
  {
    "path": "library/src/main/aidl/com/liulishuo/filedownloader/model/FileDownloadHeader.aidl",
    "chars": 75,
    "preview": "package com.liulishuo.filedownloader.model;\n\nparcelable FileDownloadHeader;"
  },
  {
    "path": "library/src/main/aidl/com/liulishuo/filedownloader/model/FileDownloadTaskAtom.aidl",
    "chars": 77,
    "preview": "package com.liulishuo.filedownloader.model;\n\nparcelable FileDownloadTaskAtom;"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/BaseDownloadTask.java",
    "chars": 25831,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/DownloadSpeedMonitor.java",
    "chars": 2915,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/DownloadTask.java",
    "chars": 18284,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/DownloadTaskHunter.java",
    "chars": 23700,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/FileDownloadConnectListener.java",
    "chars": 2121,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/FileDownloadEventPool.java",
    "chars": 1100,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/FileDownloadLargeFileListener.java",
    "chars": 5252,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/FileDownloadLine.java",
    "chars": 5501,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/FileDownloadLineAsync.java",
    "chars": 1403,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/FileDownloadList.java",
    "chars": 8616,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/FileDownloadListener.java",
    "chars": 6882,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/FileDownloadMessageStation.java",
    "chars": 6917,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/FileDownloadMessenger.java",
    "chars": 14135,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/FileDownloadMonitor.java",
    "chars": 2905,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/FileDownloadQueueSet.java",
    "chars": 7763,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/FileDownloadSampleListener.java",
    "chars": 1399,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/FileDownloadServiceProxy.java",
    "chars": 4875,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/FileDownloadServiceSharedTransmit.java",
    "chars": 7960,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/FileDownloadServiceUIGuard.java",
    "chars": 8932,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/FileDownloadTaskLauncher.java",
    "chars": 5326,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/FileDownloader.java",
    "chars": 30428,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/IDownloadSpeed.java",
    "chars": 1956,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/IFileDownloadMessenger.java",
    "chars": 5009,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/IFileDownloadServiceProxy.java",
    "chars": 1987,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/ILostServiceConnectedHandler.java",
    "chars": 1378,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/IQueuesHandler.java",
    "chars": 1556,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/ITaskHunter.java",
    "chars": 4984,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/IThreadPoolMonitor.java",
    "chars": 929,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/LostServiceConnectedHandler.java",
    "chars": 5666,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/MessageSnapshotGate.java",
    "chars": 4497,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/PauseAllMarker.java",
    "chars": 3957,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/QueuesHandler.java",
    "chars": 10066,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/connection/DefaultConnectionCountAdapter.java",
    "chars": 1831,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/connection/FileDownloadConnection.java",
    "chars": 5242,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/connection/FileDownloadUrlConnection.java",
    "chars": 6818,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/connection/RedirectHandler.java",
    "chars": 4742,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/database/FileDownloadDatabase.java",
    "chars": 7685,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/database/NoDatabaseImpl.java",
    "chars": 7304,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/database/RemitDatabase.java",
    "chars": 9448,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/database/SqliteDatabaseImpl.java",
    "chars": 15112,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/database/SqliteDatabaseOpenHelper.java",
    "chars": 5387,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/download/ConnectTask.java",
    "chars": 7349,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/download/ConnectionProfile.java",
    "chars": 4478,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/download/CustomComponentHolder.java",
    "chars": 11390,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/download/DownloadLaunchRunnable.java",
    "chars": 43941,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/download/DownloadRunnable.java",
    "chars": 9122,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/download/DownloadStatusCallback.java",
    "chars": 19311,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/download/FetchDataTask.java",
    "chars": 11585,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/download/ProcessCallback.java",
    "chars": 1015,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/event/DownloadEventPoolImpl.java",
    "chars": 4646,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/event/DownloadEventSampleListener.java",
    "chars": 1235,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/event/DownloadServiceConnectChangedEvent.java",
    "chars": 1640,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/event/IDownloadEvent.java",
    "chars": 1368,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/event/IDownloadEventPool.java",
    "chars": 1088,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/event/IDownloadListener.java",
    "chars": 1085,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/exception/FileDownloadGiveUpRetryException.java",
    "chars": 1057,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/exception/FileDownloadHttpException.java",
    "chars": 2766,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/exception/FileDownloadNetworkPolicyException.java",
    "chars": 1169,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/exception/FileDownloadOutOfSpaceException.java",
    "chars": 3572,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/exception/FileDownloadSecurityException.java",
    "chars": 894,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/exception/PathConflictException.java",
    "chars": 3200,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/message/BlockCompleteMessage.java",
    "chars": 1864,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/message/IFlowDirectly.java",
    "chars": 879,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/message/IMessageSnapshot.java",
    "chars": 2675,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/message/LargeMessageSnapshot.java",
    "chars": 10689,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/message/MessageSnapshot.java",
    "chars": 7084,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/message/MessageSnapshotFlow.java",
    "chars": 1848,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/message/MessageSnapshotTaker.java",
    "chars": 9058,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/message/MessageSnapshotThreadPool.java",
    "chars": 3865,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/message/SmallMessageSnapshot.java",
    "chars": 10333,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/model/ConnectionModel.java",
    "chars": 2978,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/model/FileDownloadHeader.java",
    "chars": 3494,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/model/FileDownloadModel.java",
    "chars": 9100,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/model/FileDownloadStatus.java",
    "chars": 9193,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/model/FileDownloadTaskAtom.java",
    "chars": 3029,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/notification/BaseNotificationItem.java",
    "chars": 3369,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/notification/FileDownloadNotificationHelper.java",
    "chars": 3803,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/notification/FileDownloadNotificationListener.java",
    "chars": 5857,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/services/BaseFileServiceUIGuard.java",
    "chars": 7696,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/services/DefaultIdGenerator.java",
    "chars": 1469,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/services/DownloadMgrInitialParams.java",
    "chars": 14104,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/services/FDServiceSeparateHandler.java",
    "chars": 5641,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/services/FDServiceSharedHandler.java",
    "chars": 4522,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/services/FileDownloadBroadcastHandler.java",
    "chars": 2260,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/services/FileDownloadManager.java",
    "chars": 12779,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/services/FileDownloadService.java",
    "chars": 4877,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/services/FileDownloadThreadPool.java",
    "chars": 6568,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/services/ForegroundServiceConfig.java",
    "chars": 5591,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/services/IFileDownloadServiceHandler.java",
    "chars": 1754,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/stream/FileDownloadOutputStream.java",
    "chars": 4917,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/stream/FileDownloadRandomAccessFile.java",
    "chars": 2384,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/util/DownloadServiceNotConnectedHelper.java",
    "chars": 4109,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/util/ExtraKeys.java",
    "chars": 738,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/util/FileDownloadExecutors.java",
    "chars": 3396,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/util/FileDownloadHelper.java",
    "chars": 12965,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/util/FileDownloadLog.java",
    "chars": 2505,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/util/FileDownloadProperties.java",
    "chars": 16086,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/util/FileDownloadSerialQueue.java",
    "chars": 6716,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/java/com/liulishuo/filedownloader/util/FileDownloadUtils.java",
    "chars": 35865,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/main/res/values/strings.xml",
    "chars": 247,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <string name=\"default_filedownloader_notification_title\">FileDown"
  },
  {
    "path": "library/src/test/java/com/liulishuo/filedownloader/FileDownloaderTest.java",
    "chars": 1839,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/test/java/com/liulishuo/filedownloader/connection/FileDownloadUrlConnectionTest.java",
    "chars": 2412,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/test/java/com/liulishuo/filedownloader/download/DownloadLaunchRunnableTest.java",
    "chars": 5807,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/test/java/com/liulishuo/filedownloader/download/DownloadRunnableTest.java",
    "chars": 3543,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/test/java/com/liulishuo/filedownloader/util/FileDownloadUtilsTest.java",
    "chars": 5782,
    "preview": "/*\n * Copyright (c) 2015 LingoChamp Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
  },
  {
    "path": "library/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker",
    "chars": 17,
    "preview": "mock-maker-inline"
  },
  {
    "path": "okcat.yml",
    "chars": 3246,
    "preview": "# you can use https://github.com/Jacksgong/okcat for debug filedownloader more gentle\n# we will filter out logs with the"
  },
  {
    "path": "settings.gradle",
    "chars": 28,
    "preview": "include ':demo', ':library'\n"
  }
]

// ... and 3 more files (download for full content)

About this extraction

This page contains the full source code of the lingochamp/FileDownloader GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 189 files (1.1 MB), approximately 286.1k tokens, and a symbol index with 1854 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!