实现暂停,取消,等待下载逻辑

pull/1/head
jsyjst 6 years ago
parent 3d2c37a4f5
commit fe1cb3b903

@ -2,7 +2,7 @@
<litepal>
<dbname value="SongList" />
<version value="23" />
<version value="26" />
<list>
<mapping class="com.example.musicplayer.entiy.OnlineSong" />

@ -73,4 +73,5 @@ public class Constant {
public final static int TYPE_DOWNLOAD_SUCCESS = 3;
public final static int TYPE_DOWNLOAD_FAILED = 4;
public final static int TYPE_DOWNLOADED = 5;
public final static int TYPE_DOWNLOAD_ADD=6;
}

@ -11,6 +11,7 @@ import org.litepal.crud.LitePalSupport;
*/
public class DownloadInfo extends LitePalSupport {
private long id;
private String songName;
private String singer;
private String url;
@ -19,6 +20,7 @@ public class DownloadInfo extends LitePalSupport {
private long currentSize;
private long totalSize;
private Song song;
private int position;//正在下载歌曲列表中的位置
public String getSongName() {
return songName;
@ -83,4 +85,16 @@ public class DownloadInfo extends LitePalSupport {
public void setSong(Song song) {
this.song = song;
}
public int getPosition() {
return position;
}
public void setPosition(int position) {
this.position = position;
}
public long getId() {
return id;
}
}

@ -11,6 +11,8 @@ import java.io.Serializable;
public class Song extends LitePalSupport implements Serializable {
private static final long serialVersionUID=1L;
private long id;
private String songId; //歌曲id
private String qqId;//专属本地音乐本地音乐在qq音乐中的songId
private String mediaId;//播放id,下载需要用到
@ -19,7 +21,7 @@ public class Song extends LitePalSupport implements Serializable {
private String songName; //歌曲名字
private String url; //歌曲url
private long currentTime; //歌曲播放时长位置
private int current;//在音乐列表的位置
private int position;//在音乐列表的位置
private String imgUrl; //歌曲照片
private boolean isOnline; //是否为网络歌曲
private int listType; //歌曲列表类别,0表示当前没有列表即可能在播放网络歌曲
@ -90,12 +92,12 @@ public class Song extends LitePalSupport implements Serializable {
this.currentTime = currentTime;
}
public int getCurrent() {
return current;
public int getPosition() {
return position;
}
public void setCurrent(int current) {
this.current = current;
public void setPosition(int position) {
this.position = position;
}
public String getImgUrl() {
@ -130,9 +132,13 @@ public class Song extends LitePalSupport implements Serializable {
isDownload = download;
}
public long getId() {
return id;
}
public String toString(){
return "songName="+songName+",singer="+singer+",url="+url+",imgUrl="+imgUrl
+",duration="+duration+",currentTime="+currentTime+",current="+current
+",duration="+duration+",currentTime="+currentTime+",position="+ position
+",songId="+songId+",isOnline="+isOnline+",listType="+listType;
}

@ -24,7 +24,6 @@ import com.example.musicplayer.entiy.DownloadInfo;
import com.example.musicplayer.entiy.DownloadSong;
import com.example.musicplayer.entiy.Song;
import com.example.musicplayer.event.DownloadEvent;
import com.example.musicplayer.event.SongDownloadedEvent;
import com.example.musicplayer.event.SongListNumEvent;
import com.example.musicplayer.util.CommonUtil;
import com.example.musicplayer.view.MainActivity;
@ -33,8 +32,8 @@ import org.greenrobot.eventbus.EventBus;
import org.litepal.LitePal;
import java.io.File;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import static com.example.musicplayer.app.Constant.TYPE_DOWNLOADING;
@ -52,6 +51,8 @@ public class DownloadService extends Service {
private String downloadUrl;
private DownloadBinder downloadBinder = new DownloadBinder();
private LinkedList<Song> downloadQueue = new LinkedList<>();//等待队列
private int position = 0;//下载歌曲在下载歌曲列表的位置
private int currentPosition;//当前下载的位置
private DownloadListener listener = new DownloadListener() {
@Override
public void onProgress(DownloadInfo downloadInfo) {
@ -62,8 +63,9 @@ public class DownloadService extends Service {
@Override
public void onSuccess() {
downloadTask = null;
saveToDb(); //下载成功,则保存数据到数据库,顺便从下载数据库中移除
start();//下载队列中的其它歌曲
Song song = downloadQueue.poll();
operateDb(song); //操作数据库
start(song.getPosition());//下载队列中的其它歌曲
//下载成功通知前台服务通知关闭,并创建一个下载成功的通知
stopForeground(true);
getNotificationManager().notify(1, getNotification("下载成功", -1));
@ -88,8 +90,7 @@ public class DownloadService extends Service {
@Override
public void onPaused() {
downloadTask = null;
downloadQueue.poll();//从下载列表中移除该歌曲
start();//下载下载列表中的歌曲
start(downloadQueue.poll().getPosition());;//从下载列表中移除该歌曲,并且下载下载列表中的歌曲
EventBus.getDefault().post(new DownloadEvent(Constant.TYPE_DOWNLOAD_PAUSED)); //下载暂停
Toast.makeText(DownloadService.this, "下载已暂停", Toast.LENGTH_SHORT).show();
}
@ -121,7 +122,7 @@ public class DownloadService extends Service {
CommonUtil.showToast(DownloadService.this, "已经加入下载队列");
} else {
CommonUtil.showToast(DownloadService.this, "开始下载");
start();
start(downloadQueue.peek().getPosition());
}
}
@ -131,22 +132,19 @@ public class DownloadService extends Service {
}
}
public void resumeDownload() {
start();
}
public void cancelDownload(String downloadUrl,String songId) {
public void cancelDownload(String downloadUrl, String songId) {
//如果该歌曲正在下载则需要将downloadTask置为null
if (downloadTask != null&&downloadQueue.peek().getSongId().equals(songId)) {
if (downloadTask != null && downloadQueue.peek().getSongId().equals(songId)) {
downloadTask.cancelDownload();
}
//将该歌曲从下载队列中移除
for (int i = 0; i < downloadQueue.size(); i++) {
Song song = downloadQueue.get(i);
if(song.getSongId().equals(songId)) downloadQueue.remove(i);
if (song.getSongId().equals(songId)) downloadQueue.remove(i);
}
//将该歌曲从正在下载的数据库中移除
LitePal.deleteAll(DownloadInfo.class, "songId=?", songId);//删除已下载歌曲的相关列
updateDb(songId);
deleteDb(songId);
//通知正在下载列表
EventBus.getDefault().post(new DownloadEvent(Constant.TYPE_DOWNLOAD_CANCELED));
//取消下载需要将文件删除并将通知关闭
@ -154,7 +152,7 @@ public class DownloadService extends Service {
String fileName = downloadUrl.substring(downloadUrl.lastIndexOf("/") + 1, downloadUrl.indexOf("?"));
File downloadFile = new File(Api.STORAGE_SONG_FILE);
String directory = String.valueOf(downloadFile);
File file = new File(fileName ,directory);
File file = new File(fileName, directory);
if (file.exists()) {
file.delete();
}
@ -165,9 +163,9 @@ public class DownloadService extends Service {
}
}
}
private void start() {
private void start(int position) {
if (downloadTask == null && !downloadQueue.isEmpty()) {
Song song = downloadQueue.peek();
DownloadInfo downloadInfo = new DownloadInfo();
@ -176,6 +174,7 @@ public class DownloadService extends Service {
downloadInfo.setSongName(song.getSongName());
downloadInfo.setSinger(song.getSinger());
downloadInfo.setSong(song);
downloadInfo.setPosition(position);
downloadUrl = song.getUrl();
downloadTask = new DownloadTask(listener);
downloadTask.execute(downloadInfo);
@ -219,10 +218,32 @@ public class DownloadService extends Service {
}
}
private void saveToDb() {
Song song = downloadQueue.poll();
LitePal.deleteAll(DownloadInfo.class, "songId=?", song.getSongId());//删除已下载歌曲的相关列
LitePal.deleteAll(Song.class, "songId=?", song.getSongId());//删除已下载歌曲的关联表中的相关列
private void operateDb(Song song) {
updateDb(song.getSongId());
deleteDb(song.getSongId());
saveDb(song);
EventBus.getDefault().post(new DownloadEvent(Constant.TYPE_DOWNLOAD_SUCCESS));//通知已下载列表
EventBus.getDefault().post(new SongListNumEvent(Constant.LIST_TYPE_DOWNLOAD)); //通知主界面的下载个数需要改变
}
//更新数据库中歌曲列表的位置即下载完成歌曲后的位置都要减去1
private void updateDb(String songId) {
long id = LitePal.select("id").where("songId = ?", songId).find(Song.class).get(0).getId();
List<Song> songIdList = LitePal.select("id", "position").where("id > ?", id + "").find(Song.class);
for (Song song : songIdList) {
song.setPosition(song.getPosition() - 1);
song.save();
}
}
//下载完成时要删除下载歌曲表中的数据以及关联表中的数据
private void deleteDb(String songId) {
LitePal.deleteAll(DownloadInfo.class, "songId=?", songId);//删除已下载歌曲的相关列
LitePal.deleteAll(Song.class, "songId=?", songId);//删除已下载歌曲的关联表中的相关列
}
//歌曲下载完成时保存歌曲信息到已下载歌曲表
private void saveDb(Song song) {
DownloadSong downloadSong = new DownloadSong();
downloadSong.setName(song.getSongName());
downloadSong.setSongId(song.getSongId());
@ -232,11 +253,13 @@ public class DownloadService extends Service {
downloadSong.setMediaId(song.getMediaId());
downloadSong.setUrl(Api.STORAGE_SONG_FILE + "C400" + song.getMediaId() + ".m4a");
downloadSong.save();
EventBus.getDefault().post(new DownloadEvent(Constant.TYPE_DOWNLOAD_SUCCESS));//通知已下载列表
EventBus.getDefault().post(new SongListNumEvent(Constant.LIST_TYPE_DOWNLOAD)); //通知主界面的下载个数需要改变
}
private void postDownloadEvent(Song song) {
//如果需要下载的表中有该条歌曲,则跳过
if (LitePal.where("songId=?", song.getSongId()).find(DownloadInfo.class).size() != 0)
return;
position = LitePal.findAll(DownloadInfo.class).size();
DownloadInfo downloadInfo = new DownloadInfo();
downloadInfo.setSongName(song.getSongName());
downloadInfo.setSongId(song.getSongId());
@ -244,7 +267,10 @@ public class DownloadService extends Service {
downloadInfo.setProgress(0);
downloadInfo.setSinger(song.getSinger());
downloadInfo.setSong(song);
downloadInfo.setPosition(position);
song.setPosition(position);
song.save();
downloadInfo.save();
EventBus.getDefault().post(new DownloadEvent(Constant.TYPE_DOWNLOAD_ADD));
}
}

@ -75,7 +75,7 @@ public class PlayerService extends Service {
mHistoryList = orderHistoryList(LitePal.findAll(HistorySong.class));
//保证最近播放列表一开始总是第一个
Song song = FileUtil.getSong();
song.setCurrent(0);
song.setPosition(0);
FileUtil.saveSong(song);
}else if(mListType == Constant.LIST_TYPE_DOWNLOAD){
mDownloadList = orderDownloadList(LitePal.findAll(DownloadSong.class));
@ -86,7 +86,7 @@ public class PlayerService extends Service {
public IBinder onBind(Intent arg0) {
mediaPlayer.setOnCompletionListener(mp -> {
EventBus.getDefault().post(new SongStatusEvent(Constant.SONG_PAUSE));//暂停广播
mCurrent = FileUtil.getSong().getCurrent();
mCurrent = FileUtil.getSong().getPosition();
//将歌曲的信息保存起来
if (mListType == Constant.LIST_TYPE_LOCAL) {
mCurrent=getNextCurrent(mCurrent, mPlayMode, mLocalSongList.size()); //根据播放模式来播放下一曲
@ -130,7 +130,7 @@ public class PlayerService extends Service {
mHistoryList = orderHistoryList(LitePal.findAll(HistorySong.class));
//保证最近播放列表一开始总是第一个
Song song = FileUtil.getSong();
song.setCurrent(0);
song.setPosition(0);
FileUtil.saveSong(song);
}
@ -158,7 +158,7 @@ public class PlayerService extends Service {
mDownloadList = orderDownloadList(LitePal.findAll(DownloadSong.class));
EventBus.getDefault().post(new SongDownloadedEvent()); //发送下载歌曲改变的消息
}
mCurrent = FileUtil.getSong().getCurrent();
mCurrent = FileUtil.getSong().getPosition();
mediaPlayer.reset();//把各项参数恢复到初始状态
if (mListType == Constant.LIST_TYPE_LOCAL) {
mediaPlayer.setDataSource(mLocalSongList.get(mCurrent).getUrl());
@ -225,7 +225,7 @@ public class PlayerService extends Service {
public void next() {
EventBus.getDefault().post(new SongStatusEvent(Constant.SONG_RESUME));
mCurrent = FileUtil.getSong().getCurrent();
mCurrent = FileUtil.getSong().getPosition();
if (mListType == Constant.LIST_TYPE_LOCAL) {
mCurrent=getNextCurrent(mCurrent, mPlayMode, mLocalSongList.size()); //根据播放模式来播放下一曲
saveLocalSongInfo(mCurrent);
@ -247,7 +247,7 @@ public class PlayerService extends Service {
public void last() {
EventBus.getDefault().post(new SongStatusEvent(Constant.SONG_RESUME));//暂停广播
mCurrent = FileUtil.getSong().getCurrent();
mCurrent = FileUtil.getSong().getPosition();
if (mListType == Constant.LIST_TYPE_LOCAL) {
mCurrent = getLastCurrent(mCurrent,mPlayMode,mLocalSongList.size());
saveLocalSongInfo(mCurrent);
@ -321,7 +321,7 @@ public class PlayerService extends Service {
mLocalSongList = LitePal.findAll(LocalSong.class);
Song song = new Song();
LocalSong localSong = mLocalSongList.get(current);
song.setCurrent(current);
song.setPosition(current);
song.setSongName(localSong.getName());
song.setSinger(localSong.getSinger());
song.setDuration(localSong.getDuration());
@ -338,7 +338,7 @@ public class PlayerService extends Service {
private void saveOnlineSongInfo(int current) {
mSongList = LitePal.findAll(OnlineSong.class);
Song song = new Song();
song.setCurrent(current);
song.setPosition(current);
song.setSongId(mSongList.get(current).getSongId());
song.setSongName(mSongList.get(current).getName());
song.setSinger(mSongList.get(current).getSinger());
@ -356,7 +356,7 @@ public class PlayerService extends Service {
mLoveList = orderList(LitePal.findAll(Love.class));
Love love = mLoveList.get(current);
Song song = new Song();
song.setCurrent(current);
song.setPosition(current);
song.setSongId(love.getSongId());
song.setQqId(love.getQqId());
song.setSongName(love.getName());
@ -376,7 +376,7 @@ public class PlayerService extends Service {
private void saveDownloadInfo(int current){
DownloadSong downloadSong = mDownloadList.get(current);
Song song = new Song();
song.setCurrent(current);
song.setPosition(current);
song.setSongId(downloadSong.getSongId());
song.setSongName(downloadSong.getName());
song.setSinger(downloadSong.getSinger());
@ -394,7 +394,7 @@ public class PlayerService extends Service {
private void saveHistoryInfo(int current) {
HistorySong historySong = mHistoryList.get(current);
Song song = new Song();
song.setCurrent(current);
song.setPosition(current);
song.setSongId(historySong.getSongId());
song.setQqId(historySong.getQqId());
song.setSongName(historySong.getName());

@ -94,7 +94,7 @@ public class CollectionFragment extends Fragment {
mAdapter.notifyDataSetChanged();
if(songCollectionEvent.isLove()){//定位歌曲
if (FileUtil.getSong() != null) {
mManager.scrollToPositionWithOffset(FileUtil.getSong().getCurrent() + 4, mRecycler.getHeight());
mManager.scrollToPositionWithOffset(FileUtil.getSong().getPosition() + 4, mRecycler.getHeight());
}
}
}
@ -118,7 +118,7 @@ public class CollectionFragment extends Fragment {
song.setOnline(love.isOnline());
song.setUrl(love.getUrl());
song.setImgUrl(love.getPic());
song.setCurrent(position);
song.setPosition(position);
song.setDuration(love.getDuration());
song.setMediaId(love.getMediaId());
song.setListType(Constant.LIST_TYPE_LOVE);

@ -105,7 +105,7 @@ public class DownloadMusicFragment extends Fragment {
song.setOnline(false);
song.setUrl(downloadSong.getUrl());
song.setImgUrl(downloadSong.getPic());
song.setCurrent(position);
song.setPosition(position);
song.setDuration(downloadSong.getDuration());
song.setListType(Constant.LIST_TYPE_DOWNLOAD);
song.setMediaId(downloadSong.getMediaId());

@ -23,6 +23,7 @@ import com.example.musicplayer.R;
import com.example.musicplayer.adapter.DownloadingAdapter;
import com.example.musicplayer.app.Constant;
import com.example.musicplayer.entiy.DownloadInfo;
import com.example.musicplayer.entiy.Song;
import com.example.musicplayer.event.DownloadEvent;
import com.example.musicplayer.service.DownloadService;
@ -98,7 +99,7 @@ public class DownloadingFragment extends Fragment {
mDownloadInfoList = new LinkedList<>();
mDownloadSongId = new ArrayList<>();
mDownloadSongId.add("");
mDownloadInfoList.addAll(orderList(LitePal.findAll(DownloadInfo.class,true)));
mDownloadInfoList.addAll(LitePal.findAll(DownloadInfo.class,true));
songDowningRecycle.setItemAnimator(null); //解决进度刷新闪屏问题
mLinearLayoutManager = new LinearLayoutManager(getActivity());
mAdapter = new DownloadingAdapter(mDownloadInfoList,mDownloadSongId);
@ -111,7 +112,8 @@ public class DownloadingFragment extends Fragment {
if(downloadInfo.getSongId().equals(mDownloadSongId.get(0))){
mDownloadBinder.pauseDownload();
}else {
mDownloadBinder.startDownload(mDownloadInfoList.get(position).getSong());
Song song = mDownloadInfoList.get(position).getSong();
mDownloadBinder.startDownload(song);
}
});
@ -132,24 +134,25 @@ public class DownloadingFragment extends Fragment {
@Subscribe(threadMode = ThreadMode.MAIN)
public void onDownloadingMessage(DownloadEvent event) {
int status = event.getDownloadStatus();
if (status == Constant.TYPE_DOWNLOADING) {
if (status == Constant.TYPE_DOWNLOADING) {//进度条更新
DownloadInfo downloadInfo = event.getDownloadInfo();
mDownloadSongId.clear();
mDownloadSongId.add(event.getDownloadInfo().getSongId());
((LinkedList)mDownloadInfoList).poll();
((LinkedList)mDownloadInfoList).addFirst(event.getDownloadInfo());
mAdapter.notifyItemChanged(0);
}else if(status == Constant.TYPE_DOWNLOAD_SUCCESS){
mDownloadInfoList.clear();
mDownloadInfoList.addAll(orderList(LitePal.findAll(DownloadInfo.class,true)));
mDownloadSongId.add(downloadInfo.getSongId());
mDownloadInfoList.remove(downloadInfo.getPosition());
mDownloadInfoList.add(downloadInfo.getPosition(),downloadInfo);
mAdapter.notifyItemChanged(downloadInfo.getPosition());
}else if(status == Constant.TYPE_DOWNLOAD_SUCCESS){//歌曲下载成功
resetDownloadInfoList();
mAdapter.notifyDataSetChanged();
}else if(status == Constant.TYPE_DOWNLOAD_PAUSED){
}else if(status == Constant.TYPE_DOWNLOAD_PAUSED){//当前歌曲下载暂停
mDownloadSongId.clear();
mDownloadSongId.add("");
mAdapter.notifyDataSetChanged();
}else if(status == Constant.TYPE_DOWNLOAD_CANCELED){
mDownloadInfoList.clear();
mDownloadInfoList.addAll(orderList(LitePal.findAll(DownloadInfo.class,true)));
}else if(status == Constant.TYPE_DOWNLOAD_CANCELED){//下载取消
resetDownloadInfoList();
mAdapter.notifyDataSetChanged();
}else if(status == Constant.TYPE_DOWNLOAD_ADD){//添加了正在下载歌曲
resetDownloadInfoList();
}
}
@ -163,6 +166,17 @@ public class DownloadingFragment extends Fragment {
return downloadInfos;
}
//重新从数据库中读取需要下载的歌曲
private void resetDownloadInfoList(){
mDownloadInfoList.clear();
List<DownloadInfo> temp = LitePal.findAll(DownloadInfo.class,true);
if(temp.size()!=0){
mDownloadInfoList.addAll(temp);
}
}
@Override
public void onDestroyView() {
super.onDestroyView();

@ -117,7 +117,7 @@ public class HistoryFragment extends Fragment {
song.setOnline(history.isOnline());
song.setUrl(history.getUrl());
song.setImgUrl(history.getPic());
song.setCurrent(position);
song.setPosition(position);
song.setDuration(history.getDuration());
song.setMediaId(history.getMediaId());
song.setListType(Constant.LIST_TYPE_HISTORY);

@ -97,7 +97,7 @@ public class LocalFragment extends BaseMvpFragment<LocalPresenter> implements IL
public void onMessageEvent(SongLocalEvent event){
songAdapter.notifyDataSetChanged();
if (FileUtil.getSong() != null) {
layoutManager.scrollToPositionWithOffset(FileUtil.getSong().getCurrent() + 4, mRecycler.getHeight());
layoutManager.scrollToPositionWithOffset(FileUtil.getSong().getPosition() + 4, mRecycler.getHeight());
}
}
@ -137,7 +137,7 @@ public class LocalFragment extends BaseMvpFragment<LocalPresenter> implements IL
song.setSinger(mp3Info.getSinger());
song.setUrl(mp3Info.getUrl());
song.setDuration(mp3Info.getDuration());
song.setCurrent(position);
song.setPosition(position);
song.setOnline(false);
song.setSongId(mp3Info.getSongId());
song.setListType(Constant.LIST_TYPE_LOCAL);
@ -179,7 +179,7 @@ public class LocalFragment extends BaseMvpFragment<LocalPresenter> implements IL
songAdapter = new SongAdapter(mActivity, mLocalSongsList);
mRecycler.setAdapter(songAdapter);
if (FileUtil.getSong() != null) {
layoutManager.scrollToPositionWithOffset(FileUtil.getSong().getCurrent() - 4, mRecycler.getHeight());
layoutManager.scrollToPositionWithOffset(FileUtil.getSong().getPosition() - 4, mRecycler.getHeight());
}
songAdapter.setOnItemClickListener(position -> {
//将点击的序列化到本地
@ -189,7 +189,7 @@ public class LocalFragment extends BaseMvpFragment<LocalPresenter> implements IL
song.setSinger(mp3Info.getSinger());
song.setUrl(mp3Info.getUrl());
song.setDuration(mp3Info.getDuration());
song.setCurrent(position);
song.setPosition(position);
song.setOnline(false);
song.setSongId(mp3Info.getSongId());
song.setListType(Constant.LIST_TYPE_LOCAL);

@ -191,7 +191,7 @@ public class AlbumSongFragment extends BaseMvpFragment<AlbumSongPresenter> imple
song.setSongId(dataBean.getSongmid());
song.setSinger(getSinger(dataBean));
song.setSongName(dataBean.getSongname());
song.setCurrent(position);
song.setPosition(position);
song.setDuration(dataBean.getInterval());
song.setOnline(true);
song.setListType(Constant.LIST_TYPE_ONLINE);

@ -167,7 +167,6 @@ public class SearchContentFragment extends BaseLoadingFragment<SearchContentPres
song.setSinger(getSinger(dataBean));
song.setSongName(dataBean.getSongname());
song.setImgUrl(Api.ALBUM_PIC+dataBean.getAlbummid()+Api.JPG);
song.setCurrent(position);
song.setDuration(dataBean.getInterval());
song.setOnline(true);
song.setMediaId(dataBean.getStrMediaMid());

@ -5,7 +5,7 @@
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# http://www.gradle.org/docs/position/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
@ -13,6 +13,6 @@ org.gradle.jvmargs=-Xmx1536m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# http://www.gradle.org/docs/position/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true

Loading…
Cancel
Save