增加允许不使用apt直接通过实现监听器来回调下载进度更新,该功能由[chenfei0928](https://github.com/chenfei0928)提交,感谢他的pr。如果注解不生效,只需要实现接口便可

修复m3u8任务地址错误时,无法删除实体的问题 https://github.com/AriaLyy/Aria/issues/71://github.com/AriaLyy/Aria/issues/712
This commit is contained in:
laoyuyu
2020-08-12 18:30:28 +08:00
parent 5f60b9ed57
commit fed2b4111f
50 changed files with 757 additions and 532 deletions

View File

@@ -27,11 +27,12 @@
</intent-filter>
</activity>
<activity android:name=".core.download.fragment.MultiFragmentActivity"/>
<activity android:name=".core.upload.SFtpUploadActivity" />
<activity android:name=".core.download.SFtpDownloadActivity" />
<activity android:name=".core.download.DownloadActivity" />
<activity android:name=".core.download.SingleTaskActivity" />
<activity android:name=".core.download.mutil.MultiTaskActivity" />
<activity android:name=".core.download.mutil.MultiTaskListActivity" />
<activity android:name=".core.download.fragment.FragmentActivity" />
<activity android:name=".core.download.mutil.MultiDownloadActivity" />
<activity android:name=".core.download.HighestPriorityActivity" />

View File

@@ -20,13 +20,12 @@
<!--普通下载任务-->
<download>
<!--设置http下载获取文件大小是否使用Head请求。true使用head请求false使用默认的get请求-->
<!--设置http下载获取文件大小是否使用Head请求。true使用head请求false使用默认的get请求。默认为false-->
<!--只适用于3.8.11以上的版本-->
<useHeadRequest value="true"/>
<useHeadRequest value="false"/>
<!--设置任务最大下载速度0表示不限速单位为kb-->
<maxSpeed value="128"/>
<maxSpeed value="0"/>
<!--
多线程下载是否使用块下载模式,{@code true}使用,{@code false}不使用
@@ -45,7 +44,7 @@
3、从3.4.1开始如果线程数为1文件初始化时将不再预占用对应长度的空间下载多少byte则占多大的空间
对于采用多线程的任务或旧任务,依然采用原来的文件空间占用方式;
-->
<threadNum value="1"/>
<threadNum value="3"/>
<!--设置下载队列最大任务数, 默认为2-->
<maxTaskNum value="1"/>

View File

@@ -28,7 +28,8 @@ import com.arialyy.simple.R;
import com.arialyy.simple.base.BaseActivity;
import com.arialyy.simple.base.adapter.RvItemClickSupport;
import com.arialyy.simple.common.NormalToAdapter;
import com.arialyy.simple.core.download.mutil.MultiTaskActivity;
import com.arialyy.simple.core.download.fragment.MultiFragmentActivity;
import com.arialyy.simple.core.download.mutil.MultiTaskListActivity;
import com.arialyy.simple.databinding.ActivityDownloadMeanBinding;
import com.arialyy.simple.modlue.CommonModule;
import com.arialyy.simple.to.NormalTo;
@@ -76,7 +77,7 @@ public class DownloadActivity extends BaseActivity<ActivityDownloadMeanBinding>
break;
case 1:
module.startNextActivity(DownloadActivity.this, data.get(position),
MultiTaskActivity.class);
MultiTaskListActivity.class);
break;
case 2:
module.startNextActivity(DownloadActivity.this, data.get(position),
@@ -87,7 +88,9 @@ public class DownloadActivity extends BaseActivity<ActivityDownloadMeanBinding>
KotlinDownloadActivity.class);
break;
case 4:
// 服务中
// 多fragment
module.startNextActivity(DownloadActivity.this, data.get(position),
MultiFragmentActivity.class);
break;
case 5:
// 组件中使用

View File

@@ -34,9 +34,10 @@ import com.arialyy.aria.core.Aria;
import com.arialyy.aria.core.common.AbsEntity;
import com.arialyy.aria.core.common.HttpOption;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.inf.IEntity;
import com.arialyy.aria.core.download.DownloadTaskListener;
import com.arialyy.aria.core.listener.ISchedulers;
import com.arialyy.aria.core.processor.IHttpFileLenAdapter;
import com.arialyy.aria.core.scheduler.NormalTaskListenerInterface;
import com.arialyy.aria.core.task.DownloadTask;
import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.CommonUtil;
@@ -165,7 +166,7 @@ public class SingleTaskActivity extends BaseActivity<ActivitySingleBinding> {
}
@Download.onWait
void onWait(DownloadTask task) {
public void onWait(DownloadTask task) {
if (task.getKey().equals(mUrl)) {
Log.d(TAG, "wait ==> " + task.getDownloadEntity().getFileName());
getBinding().pl.setInfo(task.getEntity());
@@ -173,14 +174,18 @@ public class SingleTaskActivity extends BaseActivity<ActivitySingleBinding> {
}
@Download.onPre
protected void onPre(DownloadTask task) {
public void onPre(DownloadTask task) {
if (task.getKey().equals(mUrl)) {
getBinding().pl.setInfo(task.getEntity());
}
}
//@Override public void onTaskPre(DownloadTask task) {
//
//}
@Download.onTaskStart
void taskStart(DownloadTask task) {
public void onTaskStart(DownloadTask task) {
if (task.getKey().equals(mUrl)) {
getBinding().pl.setInfo(task.getEntity());
ALog.d(TAG, "isComplete = " + task.isComplete() + ", state = " + task.getState());
@@ -188,15 +193,19 @@ public class SingleTaskActivity extends BaseActivity<ActivitySingleBinding> {
}
@Download.onTaskRunning
protected void running(DownloadTask task) {
public void onTaskRunning(DownloadTask task) {
if (task.getKey().equals(mUrl)) {
//ALog.d(TAG, "isRunning" + "; state = " + task.getEntity().getState());
getBinding().pl.setInfo(task.getEntity());
}
}
//@Override public void onNoSupportBreakPoint(DownloadTask task) {
//
//}
@Download.onTaskResume
void taskResume(DownloadTask task) {
public void onTaskResume(DownloadTask task) {
if (task.getKey().equals(mUrl)) {
ALog.d(TAG, "resume");
getBinding().pl.setInfo(task.getEntity());
@@ -204,7 +213,7 @@ public class SingleTaskActivity extends BaseActivity<ActivitySingleBinding> {
}
@Download.onTaskStop
void taskStop(DownloadTask task) {
public void onTaskStop(DownloadTask task) {
if (task.getKey().equals(mUrl)) {
ALog.d(TAG, "stop");
getBinding().pl.setInfo(task.getEntity());
@@ -212,7 +221,7 @@ public class SingleTaskActivity extends BaseActivity<ActivitySingleBinding> {
}
@Download.onTaskCancel
void taskCancel(DownloadTask task) {
public void onTaskCancel(DownloadTask task) {
if (task.getKey().equals(mUrl)) {
mTaskId = -1;
Log.d(TAG, "cancel");
@@ -221,7 +230,7 @@ public class SingleTaskActivity extends BaseActivity<ActivitySingleBinding> {
}
@Download.onTaskFail
void taskFail(DownloadTask task, Exception e) {
public void onTaskFail(DownloadTask task, Exception e) {
ALog.d(TAG, "下载失败");
Toast.makeText(SingleTaskActivity.this, getString(R.string.download_fail), Toast.LENGTH_SHORT)
.show();
@@ -231,7 +240,7 @@ public class SingleTaskActivity extends BaseActivity<ActivitySingleBinding> {
}
@Download.onTaskComplete
void taskComplete(DownloadTask task) {
public void onTaskComplete(DownloadTask task) {
if (task.getKey().equals(mUrl)) {
Toast.makeText(SingleTaskActivity.this, getString(R.string.download_success),
Toast.LENGTH_SHORT).show();

View File

@@ -19,24 +19,20 @@ package com.arialyy.simple.core.download.fragment;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.Button;
import com.arialyy.annotations.Download;
import com.arialyy.aria.core.Aria;
import com.arialyy.aria.core.common.AbsEntity;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.inf.IEntity;
import com.arialyy.aria.core.task.DownloadTask;
import com.arialyy.aria.util.CommonUtil;
import com.arialyy.frame.core.AbsFragment;
import com.arialyy.simple.R;
import com.arialyy.simple.databinding.FragmentDownloadBinding;
import com.arialyy.simple.widget.ProgressLayout;
/**
* Created by lyy on 2017/1/4.
*/
public class DownloadFragment extends AbsFragment<FragmentDownloadBinding>
implements View.OnClickListener {
Button mStart;
Button mCancel;
public class DownloadFragment extends AbsFragment<FragmentDownloadBinding> {
private long mTaskId = -1;
private static final String DOWNLOAD_URL =
@@ -44,82 +40,58 @@ public class DownloadFragment extends AbsFragment<FragmentDownloadBinding>
private static final String FILE_NAME = "王者军团";
@Override protected void init(Bundle savedInstanceState) {
mStart = mRootView.findViewById(R.id.start);
mCancel = mRootView.findViewById(R.id.cancel);
mStart.setOnClickListener(this);
mCancel.setOnClickListener(this);
DownloadEntity entity = Aria.download(this).getFirstDownloadEntity(DOWNLOAD_URL);
if (entity != null) {
getBinding().setFileSize(CommonUtil.formatFileSize(entity.getFileSize()));
getBinding().setProgress(entity.getPercent());
if (entity.getState() == IEntity.STATE_RUNNING) {
getBinding().setStateStr(getString(R.string.stop));
} else {
getBinding().setStateStr(getString(R.string.resume));
}
mTaskId = entity.getId();
} else {
getBinding().setStateStr(getString(R.string.start));
}
getBinding().setUrl(DOWNLOAD_URL);
getBinding().setFileName(FILE_NAME);
Aria.download(this).register();
}
public void onClick(View view) {
switch (view.getId()) {
case R.id.start:
if (mTaskId == -1) {
mTaskId = Aria.download(this)
.load(DOWNLOAD_URL)
.setFilePath(
Environment.getExternalStorageDirectory().getPath() + String.format("/%s.apk",
FILE_NAME))
.create();
getBinding().setStateStr(getString(R.string.stop));
break;
}
if (Aria.download(this).load(mTaskId).isRunning()) {
Aria.download(this).load(mTaskId).stop();
getBinding().setStateStr(getString(R.string.resume));
} else {
Aria.download(this).load(mTaskId).resume();
getBinding().setStateStr(getString(R.string.stop));
}
break;
case R.id.cancel:
Aria.download(this).load(mTaskId).cancel();
getBinding().setStateStr(getString(R.string.start));
mTaskId = -1;
break;
DownloadEntity entity = Aria.download(this).getFirstDownloadEntity(DOWNLOAD_URL);
if (entity == null){
entity = new DownloadEntity();
entity.setUrl(DOWNLOAD_URL);
}
getBinding().pl.setInfo(entity);
getBinding().pl.setBtListener(new ProgressLayout.OnProgressLayoutBtListener() {
@Override public void create(View v, AbsEntity entity) {
mTaskId = Aria.download(this)
.load(DOWNLOAD_URL)
.setFilePath(
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
.getPath() + String.format("/%s.apk",
FILE_NAME))
.create();
}
@Override public void stop(View v, AbsEntity entity) {
Aria.download(this)
.load(mTaskId)
.stop();
}
@Override public void resume(View v, AbsEntity entity) {
Aria.download(this).load(mTaskId)
//.updateUrl(mUrl)
.resume();
}
@Override public void cancel(View v, AbsEntity entity) {
Aria.download(this).load(mTaskId).cancel(false);
mTaskId = -1;
}
});
}
@Download.onTaskPre public void onTaskPre(DownloadTask task) {
getBinding().setFileSize(task.getConvertFileSize());
getBinding().pl.setInfo(task.getEntity());
}
@Download.onTaskStop public void onTaskStop(DownloadTask task) {
getBinding().setSpeed("");
getBinding().setStateStr(getString(R.string.resume));
getBinding().pl.setInfo(task.getEntity());
}
@Download.onTaskCancel public void onTaskCancel(DownloadTask task) {
getBinding().setProgress(0);
getBinding().setSpeed("");
getBinding().setStateStr(getString(R.string.cancel));
getBinding().pl.setInfo(task.getEntity());
}
@Download.onTaskRunning public void onTaskRunning(DownloadTask task) {
long len = task.getFileSize();
if (len == 0) {
getBinding().setProgress(0);
} else {
getBinding().setProgress(task.getPercent());
}
getBinding().setSpeed(task.getConvertSpeed());
getBinding().pl.setInfo(task.getEntity());
}
@Override protected void onDelayLoad() {

View File

@@ -0,0 +1,56 @@
package com.arialyy.simple.core.download.fragment
import android.os.Bundle
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentPagerAdapter
import com.arialyy.simple.R
import com.arialyy.simple.base.BaseActivity
import com.arialyy.simple.databinding.ActivityMultiFragmentActivityBinding
class MultiFragmentActivity : BaseActivity<ActivityMultiFragmentActivityBinding>() {
private val urls = arrayListOf(
"http://cpsdown.muzhiwan.com/2020/07/23/com.suyou.xjhx.syad_5f195b471dff6.apk",
"http://60.174.135.183:88/sdkdown.muzhiwan.com/2020/01/13/com.supercell.clashroyale.ewan.mzw_5e1bc4eb4313e.apk",
"http://60.174.135.183:88/sdkdown.muzhiwan.com/openfile/2020/08/06/com.maoer.m282_5f2b79232a8b1.apk"
)
private val names = arrayListOf(
"星界幻想",
"皇室战争",
"无双帝国"
)
override fun setLayoutId(): Int {
return R.layout.activity_multi_fragment_activity
}
override fun init(savedInstanceState: Bundle?) {
super.init(savedInstanceState)
val fragmentList = arrayListOf<MultiItemFragment>()
urls.forEachIndexed { index, url ->
fragmentList.add(MultiItemFragment(url, names[index]))
}
binding.vpPage.adapter = PGAdapter(fragmentList, supportFragmentManager, FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT)
binding.tabLayout.setupWithViewPager(binding.vpPage)
binding.tabLayout.getTabAt(0)!!.text = "fm1"
binding.tabLayout.getTabAt(1)!!.text = "fm2"
binding.tabLayout.getTabAt(2)!!.text = "fm3"
}
private class PGAdapter(
val fragments: List<MultiItemFragment>,
fm: FragmentManager,
state: Int
) : FragmentPagerAdapter(fm, state) {
override fun getItem(position: Int): Fragment {
return fragments[position]
}
override fun getCount(): Int {
return fragments.size
}
}
}

View File

@@ -0,0 +1,124 @@
/*
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
*
* 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.
*/
package com.arialyy.simple.core.download.fragment;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import com.arialyy.annotations.Download;
import com.arialyy.aria.core.Aria;
import com.arialyy.aria.core.common.AbsEntity;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.task.DownloadTask;
import com.arialyy.frame.core.AbsFragment;
import com.arialyy.simple.R;
import com.arialyy.simple.databinding.FragmentDownloadBinding;
import com.arialyy.simple.widget.ProgressLayout;
/**
* Created by lyy on 2017/1/4.
*/
public class MultiItemFragment extends AbsFragment<FragmentDownloadBinding> {
private long mTaskId = -1;
private String DOWNLOAD_URL;
private String FILE_NAME;
public MultiItemFragment(String url, String fileName) {
DOWNLOAD_URL = url;
FILE_NAME = fileName;
}
@Override protected void init(Bundle savedInstanceState) {
Aria.download(this).register();
DownloadEntity entity = Aria.download(this).getFirstDownloadEntity(DOWNLOAD_URL);
if (entity == null) {
entity = new DownloadEntity();
entity.setUrl(DOWNLOAD_URL);
}
getBinding().pl.setInfo(entity);
getBinding().pl.setBtListener(new ProgressLayout.OnProgressLayoutBtListener() {
@Override public void create(View v, AbsEntity entity) {
mTaskId = Aria.download(this)
.load(DOWNLOAD_URL)
.setFilePath(
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
.getPath() + String.format("/%s.apk",
FILE_NAME))
.create();
}
@Override public void stop(View v, AbsEntity entity) {
Aria.download(this)
.load(mTaskId)
.stop();
}
@Override public void resume(View v, AbsEntity entity) {
Aria.download(this).load(mTaskId)
//.updateUrl(mUrl)
.resume();
}
@Override public void cancel(View v, AbsEntity entity) {
Aria.download(this).load(mTaskId).cancel(false);
mTaskId = -1;
}
});
}
@Download.onTaskPre public void onTaskPre(DownloadTask task) {
if (!task.getKey().equals(DOWNLOAD_URL)){
return;
}
getBinding().pl.setInfo(task.getEntity());
}
@Download.onTaskStop public void onTaskStop(DownloadTask task) {
if (!task.getKey().equals(DOWNLOAD_URL)){
return;
}
getBinding().pl.setInfo(task.getEntity());
}
@Download.onTaskCancel public void onTaskCancel(DownloadTask task) {
if (!task.getKey().equals(DOWNLOAD_URL)){
return;
}
getBinding().pl.setInfo(task.getEntity());
}
@Download.onTaskRunning public void onTaskRunning(DownloadTask task) {
if (!task.getKey().equals(DOWNLOAD_URL)){
return;
}
long len = task.getFileSize();
getBinding().pl.setInfo(task.getEntity());
}
@Override protected void onDelayLoad() {
}
@Override protected int setLayoutId() {
return R.layout.fragment_download;
}
@Override protected void dataCallback(int result, Object obj) {
}
}

View File

@@ -31,6 +31,7 @@ import com.arialyy.annotations.Download;
import com.arialyy.annotations.M3U8;
import com.arialyy.aria.core.Aria;
import com.arialyy.aria.core.common.AbsEntity;
import com.arialyy.aria.core.common.HttpOption;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.M3U8Entity;
import com.arialyy.aria.core.download.m3u8.M3U8VodOption;
@@ -309,7 +310,7 @@ public class M3U8VodDLoadActivity extends BaseActivity<ActivityM3u8VodBinding> {
//.merge(true)
//.setVodTsUrlConvert(new VodTsUrlConverter());
//.setMergeHandler(new TsMergeHandler());
option.setUseDefConvert(false);
option.setUseDefConvert(true);
option.setKeyUrlConverter(new KeyUrlConverter());
option.setVodTsUrlConvert(new VodTsUrlConverter());
option.setBandWidthUrlConverter(new BandWidthUrlConverter());

View File

@@ -34,8 +34,7 @@ public class M3U8VodModule extends BaseViewModule {
// m3u8测试集合http://www.voidcn.com/article/p-snaliarm-ct.html
//private final String defUrl = "https://www.gaoya123.cn/2019/1557993797897.m3u8";
// 多码率地址:
//private final String defUrl = "http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8";
private final String defUrl = "http://mgjx.awu1k.cn:8000/parse/player.m3u8?target=eb2d3ca5198516269cf356463be86573";
private final String defUrl = "http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u811";
//private final String defUrl = "http://youku.cdn7-okzy.com/20200123/16815_fbe419ed/index.m3u8";
//private final String defUrl = "https://cn7.kankia.com/hls/20200108/e1eaec074274c64fe46a3bdb5d2ba487/1578488360/index.m3u8";

View File

@@ -26,6 +26,7 @@ import com.arialyy.annotations.Download;
import com.arialyy.annotations.DownloadGroup;
import com.arialyy.aria.core.Aria;
import com.arialyy.aria.core.common.AbsEntity;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.task.DownloadGroupTask;
import com.arialyy.aria.core.task.DownloadTask;
import com.arialyy.aria.util.ALog;
@@ -100,6 +101,10 @@ public class MultiDownloadActivity extends BaseActivity<ActivityMultiDownloadBin
@Download.onTaskCancel void taskCancel(DownloadTask task) {
mAdapter.updateState(task.getEntity());
List<DownloadEntity> tasks = Aria.download(this).getAllNotCompleteTask();
if (tasks != null){
ALog.d(TAG, "未完成的任务数:" + tasks.size());
}
}
@Download.onTaskFail void taskFail(DownloadTask task) {

View File

@@ -42,7 +42,7 @@ import java.util.List;
/**
* Created by Lyy on 2016/9/27.
*/
public class MultiTaskActivity extends BaseActivity<ActivityMultiBinding> {
public class MultiTaskListActivity extends BaseActivity<ActivityMultiBinding> {
RecyclerView mList;
Toolbar mBar;
private FileListAdapter mAdapter;

View File

@@ -99,7 +99,7 @@ public class ProgressLayout extends RelativeLayout implements View.OnClickListen
@Override public void onClick(View v) {
if (listener == null) {
ALog.d(TAG, "没有设置OnProgressLayoutBtListener");
ALog.e(TAG, "没有设置OnProgressLayoutBtListener");
return;
}
if (entity == null) {

View File

@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="fm1" />
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="fm2" />
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="fm3" />
</com.google.android.material.tabs.TabLayout>
<androidx.viewpager.widget.ViewPager
android:id="@+id/vpPage"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
</layout>

View File

@@ -1,60 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:bind="http://schemas.android.com/apk/res-auto"
>
<data>
<variable
name="fileSize"
type="String"
/>
<variable
name="speed"
type="String"
/>
<variable
name="progress"
type="int"
/>
<variable
name="stateStr"
type="String"
/>
<variable
name="file_name"
type="String"
/>
<variable
name="url"
type="String"
/>
</data>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
<com.arialyy.simple.widget.ProgressLayout
android:id="@+id/pl"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{@string/file_name(file_name)}"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{@string/url(url)}"
/>
<include
layout="@layout/layout_content_single"
bind:fileSize="@{fileSize}"
bind:progress="@{progress}"
bind:speed="@{speed}"
bind:stateStr="@{stateStr}"
/>
android:layout_margin="16dp" />
</LinearLayout>
</layout>

View File

@@ -68,7 +68,7 @@
<item>多任务下载</item>
<item>高优先级任务</item>
<item>kotlin</item>
<item>Service中使用</item>
<item>多fragment</item>
<item>组件中使用</item>
</string-array>