From c046d218f62205648b70542ec344d47fbb2a9080 Mon Sep 17 00:00:00 2001 From: zzf Date: Fri, 7 Jun 2019 18:43:18 +0800 Subject: [PATCH] trans to RxJava2 --- README.md | 45 +-- app/build.gradle | 33 +- .../java/io/github/ryanhoo/music/RxBus.java | 26 +- .../music/data/source/AppContract.java | 6 +- .../music/data/source/AppLocalDataSource.java | 133 +++---- .../music/data/source/AppRepository.java | 14 +- .../ryanhoo/music/player/PlaybackService.java | 2 +- .../ryanhoo/music/ui/base/BaseActivity.java | 25 +- .../ryanhoo/music/ui/base/BaseFragment.java | 29 +- .../ui/details/PlayListDetailsPresenter.java | 111 +++--- .../ui/local/all/AllLocalMusicFragment.java | 17 +- .../ui/local/all/LocalMusicPresenter.java | 90 ++--- .../local/filesystem/FileSystemActivity.java | 64 ++-- .../music/ui/local/folder/FolderFragment.java | 32 +- .../ui/local/folder/FolderPresenter.java | 350 +++++++++--------- .../music/ui/music/MusicPlayerFragment.java | 20 +- .../music/ui/music/MusicPlayerPresenter.java | 55 +-- .../playlist/AddToPlayListDialogFragment.java | 11 +- .../music/ui/playlist/PlayListFragment.java | 31 +- .../music/ui/playlist/PlayListPresenter.java | 220 ++++++----- .../github/ryanhoo/music/utils/FileUtils.java | 14 +- build.gradle | 25 +- gradle/wrapper/gradle-wrapper.jar | Bin 53636 -> 54329 bytes gradle/wrapper/gradle-wrapper.properties | 4 +- gradlew | 72 ++-- gradlew.bat | 14 +- 26 files changed, 742 insertions(+), 701 deletions(-) diff --git a/README.md b/README.md index 3a9eb00..1dcdcf4 100644 --- a/README.md +++ b/README.md @@ -1,44 +1 @@ -# A Stylish Music Player - -[![license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/ryanhoo/StylishMusicPlayer#license) -[![platform](https://img.shields.io/badge/platform-Android-yellow.svg)](https://www.android.com) -[![API](https://img.shields.io/badge/API-16%2B-brightgreen.svg?style=flat)](https://android-arsenal.com/api?level=16) -[![gitter](https://img.shields.io/gitter/room/nwjs/nw.js.svg)](https://gitter.im/stylist-music-player/bug-report) -[![PRs Welcome](https://img.shields.io/badge/prs-welcome-brightgreen.svg)](http://makeapullrequest.com) - -![Artboard](materials/Artboard.png) - -## TODO - -- Lyric Support -- Settings - -## Acknowledgements - -Thanks to these projects and libraries: - -**Libraries** - -- [RxJava](https://github.com/ReactiveX/RxJava) -- [RxAndroid](https://github.com/ReactiveX/RxAndroid) -- [Retrofit](https://github.com/square/retrofit) -- [Butter Knife](https://github.com/JakeWharton/butterknife) -- [Calligraphy](https://github.com/chrisjenx/Calligraphy) -- [LiteOrm](https://github.com/litesuits/android-lite-orm) - -**Design** - -- [Material icons](https://design.google.com/icons/) - - -## License - -> The MIT License (MIT) - -> Copyright (c) 2016 Ryan Hoo - -> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -> The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +fork from stylish music player \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 137cde5..a1395dc 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,16 +1,15 @@ import java.text.SimpleDateFormat apply plugin: 'com.android.application' -apply plugin: 'android-apt' android { - compileSdkVersion 24 - buildToolsVersion '24.0.2' + compileSdkVersion 27 + buildToolsVersion '27.0.3' defaultConfig { applicationId 'io.github.ryanhoo.music' - minSdkVersion 16 - targetSdkVersion 22 + minSdkVersion 22 + targetSdkVersion 26 versionCode getVersionCode("$BUILD") versionName "$VERSION" vectorDrawables.useSupportLibrary = true @@ -24,18 +23,18 @@ android { } dependencies { - compile fileTree(dir: 'libs', include: ['*.jar']) - testCompile 'junit:junit:4.12' - compile 'com.android.support:appcompat-v7:24.2.0' - compile 'com.android.support:design:24.2.0' - compile 'com.android.support:recyclerview-v7:24.2.0' - - compile 'io.reactivex:rxjava:1.1.9' - compile 'io.reactivex:rxandroid:1.2.1' - compile 'com.jakewharton:butterknife:8.4.0' - apt 'com.jakewharton:butterknife-compiler:8.4.0' - - compile 'uk.co.chrisjenx:calligraphy:2.2.0' + implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation 'com.android.support:appcompat-v7:27.1.1' + implementation 'com.android.support:design:27.1.1' + implementation 'com.android.support:recyclerview-v7:27.1.1' + + implementation 'io.reactivex.rxjava2:rxjava:2.1.1' + implementation 'io.reactivex.rxjava2:rxandroid:2.0.1' + + implementation 'com.jakewharton:butterknife:8.8.1' + annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1' + + implementation 'uk.co.chrisjenx:calligraphy:2.2.0' } def getVersionCode(build) { diff --git a/app/src/main/java/io/github/ryanhoo/music/RxBus.java b/app/src/main/java/io/github/ryanhoo/music/RxBus.java index 8f8c704..91c8be6 100644 --- a/app/src/main/java/io/github/ryanhoo/music/RxBus.java +++ b/app/src/main/java/io/github/ryanhoo/music/RxBus.java @@ -1,9 +1,14 @@ package io.github.ryanhoo.music; import android.util.Log; -import rx.Observable; -import rx.Subscriber; -import rx.subjects.PublishSubject; + +import org.reactivestreams.Subscriber; +import org.reactivestreams.Subscription; + +import io.reactivex.Observable; +import io.reactivex.disposables.Disposable; +import io.reactivex.observers.DisposableObserver; +import io.reactivex.subjects.PublishSubject; /** * Created with Android Studio. @@ -59,16 +64,21 @@ public Observable toObservable() { * A simple logger for RxBus which can also prevent * potential crash(OnErrorNotImplementedException) caused by error in the workflow. */ - public static Subscriber defaultSubscriber() { - return new Subscriber() { + public static DisposableObserver defaultSubscriber() { + return new DisposableObserver() { @Override - public void onCompleted() { + public void onError(Throwable e) { + Log.e(TAG, "What is this? Please solve this as soon as possible!", e); + } + + @Override + public void onComplete() { Log.d(TAG, "Duty off!!!"); } @Override - public void onError(Throwable e) { - Log.e(TAG, "What is this? Please solve this as soon as possible!", e); + protected void onStart() { + super.onStart(); } @Override diff --git a/app/src/main/java/io/github/ryanhoo/music/data/source/AppContract.java b/app/src/main/java/io/github/ryanhoo/music/data/source/AppContract.java index b5fee93..b568472 100644 --- a/app/src/main/java/io/github/ryanhoo/music/data/source/AppContract.java +++ b/app/src/main/java/io/github/ryanhoo/music/data/source/AppContract.java @@ -1,11 +1,11 @@ package io.github.ryanhoo.music.data.source; +import java.util.List; + import io.github.ryanhoo.music.data.model.Folder; import io.github.ryanhoo.music.data.model.PlayList; import io.github.ryanhoo.music.data.model.Song; -import rx.Observable; - -import java.util.List; +import io.reactivex.Observable; /** * Created with Android Studio. diff --git a/app/src/main/java/io/github/ryanhoo/music/data/source/AppLocalDataSource.java b/app/src/main/java/io/github/ryanhoo/music/data/source/AppLocalDataSource.java index 49846d3..8c17428 100644 --- a/app/src/main/java/io/github/ryanhoo/music/data/source/AppLocalDataSource.java +++ b/app/src/main/java/io/github/ryanhoo/music/data/source/AppLocalDataSource.java @@ -1,22 +1,26 @@ package io.github.ryanhoo.music.data.source; import android.content.Context; +import android.support.annotation.NonNull; import android.util.Log; + import com.litesuits.orm.LiteOrm; import com.litesuits.orm.db.assit.QueryBuilder; import com.litesuits.orm.db.model.ConflictAlgorithm; -import io.github.ryanhoo.music.data.model.Folder; -import io.github.ryanhoo.music.data.model.PlayList; -import io.github.ryanhoo.music.data.model.Song; -import io.github.ryanhoo.music.utils.DBUtils; -import rx.Observable; -import rx.Subscriber; import java.io.File; import java.util.Date; import java.util.Iterator; import java.util.List; +import io.github.ryanhoo.music.data.model.Folder; +import io.github.ryanhoo.music.data.model.PlayList; +import io.github.ryanhoo.music.data.model.Song; +import io.github.ryanhoo.music.utils.DBUtils; +import io.reactivex.Observable; +import io.reactivex.ObservableEmitter; +import io.reactivex.ObservableOnSubscribe; + /** * Created with Android Studio. * User: ryan.hoo.j@gmail.com @@ -40,9 +44,9 @@ public AppLocalDataSource(Context context, LiteOrm orm) { @Override public Observable> playLists() { - return Observable.create(new Observable.OnSubscribe>() { + return Observable.create(new ObservableOnSubscribe>() { @Override - public void call(Subscriber> subscriber) { + public void subscribe(@NonNull ObservableEmitter> e) { List playLists = mLiteOrm.query(PlayList.class); if (playLists.isEmpty()) { // First query, create the default play list @@ -51,8 +55,8 @@ public void call(Subscriber> subscriber) { Log.d(TAG, "Create default playlist(Favorite) with " + (result == 1 ? "success" : "failure")); playLists.add(playList); } - subscriber.onNext(playLists); - subscriber.onCompleted(); + e.onNext(playLists); + e.onComplete(); } }); } @@ -64,54 +68,55 @@ public List cachedPlayLists() { @Override public Observable create(final PlayList playList) { - return Observable.create(new Observable.OnSubscribe() { + return Observable.create(new ObservableOnSubscribe() { @Override - public void call(Subscriber subscriber) { + public void subscribe(@NonNull ObservableEmitter e) { Date now = new Date(); playList.setCreatedAt(now); playList.setUpdatedAt(now); long result = mLiteOrm.save(playList); if (result > 0) { - subscriber.onNext(playList); + e.onNext(playList); } else { - subscriber.onError(new Exception("Create play list failed")); + e.onError(new Exception("Create play list failed")); } - subscriber.onCompleted(); + e.onComplete(); } }); + } @Override public Observable update(final PlayList playList) { - return Observable.create(new Observable.OnSubscribe() { + return Observable.create(new ObservableOnSubscribe() { @Override - public void call(Subscriber subscriber) { + public void subscribe(@NonNull ObservableEmitter e) { playList.setUpdatedAt(new Date()); long result = mLiteOrm.update(playList); if (result > 0) { - subscriber.onNext(playList); + e.onNext(playList); } else { - subscriber.onError(new Exception("Update play list failed")); + e.onError(new Exception("Update play list failed")); } - subscriber.onCompleted(); + e.onComplete(); } }); } @Override public Observable delete(final PlayList playList) { - return Observable.create(new Observable.OnSubscribe() { + return Observable.create(new ObservableOnSubscribe() { @Override - public void call(Subscriber subscriber) { + public void subscribe(@NonNull ObservableEmitter e) { long result = mLiteOrm.delete(playList); if (result > 0) { - subscriber.onNext(playList); + e.onNext(playList); } else { - subscriber.onError(new Exception("Delete play list failed")); + e.onError(new Exception("Delete play list failed")); } - subscriber.onCompleted(); + e.onComplete(); } }); } @@ -120,9 +125,9 @@ public void call(Subscriber subscriber) { @Override public Observable> folders() { - return Observable.create(new Observable.OnSubscribe>() { + return Observable.create(new ObservableOnSubscribe>() { @Override - public void call(Subscriber> subscriber) { + public void subscribe(@NonNull ObservableEmitter> e) { if (PreferenceManager.isFirstQueryFolders(mContext)) { List defaultFolders = DBUtils.generateDefaultFolders(); long result = mLiteOrm.save(defaultFolders); @@ -132,35 +137,35 @@ public void call(Subscriber> subscriber) { List folders = mLiteOrm.query( QueryBuilder.create(Folder.class).appendOrderAscBy(Folder.COLUMN_NAME) ); - subscriber.onNext(folders); - subscriber.onCompleted(); + e.onNext(folders); + e.onComplete(); } }); } @Override public Observable create(final Folder folder) { - return Observable.create(new Observable.OnSubscribe() { + return Observable.create(new ObservableOnSubscribe() { @Override - public void call(Subscriber subscriber) { + public void subscribe(@NonNull ObservableEmitter e) { folder.setCreatedAt(new Date()); long result = mLiteOrm.save(folder); if (result > 0) { - subscriber.onNext(folder); + e.onNext(folder); } else { - subscriber.onError(new Exception("Create folder failed")); + e.onError(new Exception("Create folder failed")); } - subscriber.onCompleted(); + e.onComplete(); } }); } @Override public Observable> create(final List folders) { - return Observable.create(new Observable.OnSubscribe>() { + return Observable.create(new ObservableOnSubscribe>() { @Override - public void call(Subscriber> subscriber) { + public void subscribe(@NonNull ObservableEmitter> e) { Date now = new Date(); for (Folder folder : folders) { folder.setCreatedAt(now); @@ -171,53 +176,53 @@ public void call(Subscriber> subscriber) { List allNewFolders = mLiteOrm.query( QueryBuilder.create(Folder.class).appendOrderAscBy(Folder.COLUMN_NAME) ); - subscriber.onNext(allNewFolders); + e.onNext(allNewFolders); } else { - subscriber.onError(new Exception("Create folders failed")); + e.onError(new Exception("Create folders failed")); } - subscriber.onCompleted(); + e.onComplete(); } }); } @Override public Observable update(final Folder folder) { - return Observable.create(new Observable.OnSubscribe() { + return Observable.create(new ObservableOnSubscribe() { @Override - public void call(Subscriber subscriber) { + public void subscribe(@NonNull ObservableEmitter e) { mLiteOrm.delete(folder); long result = mLiteOrm.save(folder); if (result > 0) { - subscriber.onNext(folder); + e.onNext(folder); } else { - subscriber.onError(new Exception("Update folder failed")); + e.onError(new Exception("Update folder failed")); } - subscriber.onCompleted(); + e.onComplete(); } }); } @Override public Observable delete(final Folder folder) { - return Observable.create(new Observable.OnSubscribe() { + return Observable.create(new ObservableOnSubscribe() { @Override - public void call(Subscriber subscriber) { + public void subscribe(@NonNull ObservableEmitter e) { long result = mLiteOrm.delete(folder); if (result > 0) { - subscriber.onNext(folder); + e.onNext(folder); } else { - subscriber.onError(new Exception("Delete folder failed")); + e.onError(new Exception("Delete folder failed")); } - subscriber.onCompleted(); + e.onComplete(); } }); } @Override public Observable> insert(final List songs) { - return Observable.create(new Observable.OnSubscribe>() { + return Observable.create(new ObservableOnSubscribe>() { @Override - public void call(Subscriber> subscriber) { + public void subscribe(@NonNull ObservableEmitter> e) { for (Song song : songs) { mLiteOrm.insert(song, ConflictAlgorithm.Abort); } @@ -232,33 +237,33 @@ public void call(Subscriber> subscriber) { mLiteOrm.delete(song); } } - subscriber.onNext(allSongs); - subscriber.onCompleted(); + e.onNext(allSongs); + e.onComplete(); } }); } @Override public Observable update(final Song song) { - return Observable.create(new Observable.OnSubscribe() { + return Observable.create(new ObservableOnSubscribe() { @Override - public void call(Subscriber subscriber) { + public void subscribe(@NonNull ObservableEmitter e) { int result = mLiteOrm.update(song); if (result > 0) { - subscriber.onNext(song); + e.onNext(song); } else { - subscriber.onError(new Exception("Update song failed")); + e.onError(new Exception("Update song failed")); } - subscriber.onCompleted(); + e.onComplete(); } }); } @Override public Observable setSongAsFavorite(final Song song, final boolean isFavorite) { - return Observable.create(new Observable.OnSubscribe() { + return Observable.create(new ObservableOnSubscribe() { @Override - public void call(Subscriber subscriber) { + public void subscribe(@NonNull ObservableEmitter e) { List playLists = mLiteOrm.query( QueryBuilder.create(PlayList.class).whereEquals(PlayList.COLUMN_FAVORITE, String.valueOf(true)) ); @@ -278,15 +283,15 @@ public void call(Subscriber subscriber) { mLiteOrm.insert(song, ConflictAlgorithm.Replace); long result = mLiteOrm.insert(favorite, ConflictAlgorithm.Replace); if (result > 0) { - subscriber.onNext(song); + e.onNext(song); } else { if (isFavorite) { - subscriber.onError(new Exception("Set song as favorite failed")); + e.onError(new Exception("Set song as favorite failed")); } else { - subscriber.onError(new Exception("Set song as unfavorite failed")); + e.onError(new Exception("Set song as unfavorite failed")); } } - subscriber.onCompleted(); + e.onComplete(); } }); } diff --git a/app/src/main/java/io/github/ryanhoo/music/data/source/AppRepository.java b/app/src/main/java/io/github/ryanhoo/music/data/source/AppRepository.java index b6fb8ec..ade4ddd 100644 --- a/app/src/main/java/io/github/ryanhoo/music/data/source/AppRepository.java +++ b/app/src/main/java/io/github/ryanhoo/music/data/source/AppRepository.java @@ -1,15 +1,15 @@ package io.github.ryanhoo.music.data.source; +import java.util.ArrayList; +import java.util.List; + import io.github.ryanhoo.music.Injection; import io.github.ryanhoo.music.data.model.Folder; import io.github.ryanhoo.music.data.model.PlayList; import io.github.ryanhoo.music.data.model.Song; import io.github.ryanhoo.music.data.source.db.LiteOrmHelper; -import rx.Observable; -import rx.functions.Action1; - -import java.util.ArrayList; -import java.util.List; +import io.reactivex.Observable; +import io.reactivex.functions.Consumer; /** * Created with Android Studio. @@ -46,9 +46,9 @@ public static AppRepository getInstance() { @Override public Observable> playLists() { return mLocalDataSource.playLists() - .doOnNext(new Action1>() { + .doOnNext(new Consumer>() { @Override - public void call(List playLists) { + public void accept(List playLists) { mCachedPlayLists = playLists; } }); diff --git a/app/src/main/java/io/github/ryanhoo/music/player/PlaybackService.java b/app/src/main/java/io/github/ryanhoo/music/player/PlaybackService.java index f9586ed..3de23a1 100644 --- a/app/src/main/java/io/github/ryanhoo/music/player/PlaybackService.java +++ b/app/src/main/java/io/github/ryanhoo/music/player/PlaybackService.java @@ -8,7 +8,7 @@ import android.os.Binder; import android.os.IBinder; import android.support.annotation.Nullable; -import android.support.v7.app.NotificationCompat; +import android.support.v4.app.NotificationCompat; import android.widget.RemoteViews; import io.github.ryanhoo.music.R; import io.github.ryanhoo.music.data.model.PlayList; diff --git a/app/src/main/java/io/github/ryanhoo/music/ui/base/BaseActivity.java b/app/src/main/java/io/github/ryanhoo/music/ui/base/BaseActivity.java index 749a12b..692f7bc 100644 --- a/app/src/main/java/io/github/ryanhoo/music/ui/base/BaseActivity.java +++ b/app/src/main/java/io/github/ryanhoo/music/ui/base/BaseActivity.java @@ -12,10 +12,11 @@ import android.util.DisplayMetrics; import android.view.MenuItem; import android.view.Window; + import io.github.ryanhoo.music.R; import io.github.ryanhoo.music.utils.GradientUtils; -import rx.Subscription; -import rx.subscriptions.CompositeSubscription; +import io.reactivex.disposables.CompositeDisposable; +import io.reactivex.disposables.Disposable; import uk.co.chrisjenx.calligraphy.CalligraphyContextWrapper; /** @@ -27,7 +28,7 @@ */ public abstract class BaseActivity extends AppCompatActivity { - private CompositeSubscription mSubscriptions; + private CompositeDisposable mDisposables; @Override protected void attachBaseContext(Context newBase) { @@ -58,14 +59,14 @@ public void onAttachedToWindow() { protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); - addSubscription(subscribeEvents()); + addDisposable(subscribeEvents()); } @Override protected void onDestroy() { super.onDestroy(); - if (mSubscriptions != null) { - mSubscriptions.clear(); + if (mDisposables != null) { + mDisposables.clear(); } } @@ -95,15 +96,15 @@ protected ActionBar supportActionBar(Toolbar toolbar) { return actionBar; } - protected void addSubscription(Subscription subscription) { - if (subscription == null) return; - if (mSubscriptions == null) { - mSubscriptions = new CompositeSubscription(); + protected void addDisposable(Disposable disposable) { + if (disposable == null) return; + if (mDisposables == null) { + mDisposables = new CompositeDisposable(); } - mSubscriptions.add(subscription); + mDisposables.add(disposable); } - protected Subscription subscribeEvents() { + protected Disposable subscribeEvents() { return null; } } diff --git a/app/src/main/java/io/github/ryanhoo/music/ui/base/BaseFragment.java b/app/src/main/java/io/github/ryanhoo/music/ui/base/BaseFragment.java index fa87010..3b765b8 100644 --- a/app/src/main/java/io/github/ryanhoo/music/ui/base/BaseFragment.java +++ b/app/src/main/java/io/github/ryanhoo/music/ui/base/BaseFragment.java @@ -5,8 +5,9 @@ import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.view.View; -import rx.Subscription; -import rx.subscriptions.CompositeSubscription; + +import io.reactivex.disposables.CompositeDisposable; +import io.reactivex.disposables.Disposable; /** * Created with Android Studio. @@ -17,7 +18,7 @@ */ public abstract class BaseFragment extends Fragment { - private CompositeSubscription mSubscriptions; + private CompositeDisposable mDisposables; @Override public void onAttach(Context context) { @@ -27,26 +28,26 @@ public void onAttach(Context context) { @Override public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); - addSubscription(subscribeEvents()); + addDisposable(subscribeEvents()); } @Override public void onDestroyView() { super.onDestroyView(); - if (mSubscriptions != null) { - mSubscriptions.clear(); + if (mDisposables != null) { + mDisposables.clear(); } } - protected Subscription subscribeEvents() { - return null; + protected void addDisposable(Disposable disposable) { + if (disposable == null) return; + if (mDisposables == null) { + mDisposables = new CompositeDisposable(); + } + mDisposables.add(disposable); } - protected void addSubscription(Subscription subscription) { - if (subscription == null) return; - if (mSubscriptions == null) { - mSubscriptions = new CompositeSubscription(); - } - mSubscriptions.add(subscription); + protected Disposable subscribeEvents() { + return null; } } diff --git a/app/src/main/java/io/github/ryanhoo/music/ui/details/PlayListDetailsPresenter.java b/app/src/main/java/io/github/ryanhoo/music/ui/details/PlayListDetailsPresenter.java index b962b2a..c67b185 100644 --- a/app/src/main/java/io/github/ryanhoo/music/ui/details/PlayListDetailsPresenter.java +++ b/app/src/main/java/io/github/ryanhoo/music/ui/details/PlayListDetailsPresenter.java @@ -5,11 +5,10 @@ import io.github.ryanhoo.music.data.model.Song; import io.github.ryanhoo.music.data.source.AppRepository; import io.github.ryanhoo.music.event.PlayListUpdatedEvent; -import rx.Subscriber; -import rx.Subscription; -import rx.android.schedulers.AndroidSchedulers; -import rx.schedulers.Schedulers; -import rx.subscriptions.CompositeSubscription; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.CompositeDisposable; +import io.reactivex.observers.DisposableObserver; +import io.reactivex.schedulers.Schedulers; /** * Created with Android Studio. @@ -22,12 +21,12 @@ public class PlayListDetailsPresenter implements PlayListDetailsContract.Present private PlayListDetailsContract.View mView; private AppRepository mRepository; - private CompositeSubscription mSubscriptions; + private CompositeDisposable mDisposables; public PlayListDetailsPresenter(AppRepository repository, PlayListDetailsContract.View view) { mView = view; mRepository = repository; - mSubscriptions = new CompositeSubscription(); + mDisposables = new CompositeDisposable(); mView.setPresenter(this); } @@ -39,72 +38,70 @@ public void subscribe() { @Override public void unsubscribe() { mView = null; - mSubscriptions.clear(); + mDisposables.clear(); } @Override - public void addSongToPlayList(Song song, PlayList playList) { + public void addSongToPlayList(Song song, final PlayList playList) { if (playList.isFavorite()) { song.setFavorite(true); } playList.addSong(song, 0); - Subscription subscription = mRepository.update(playList) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(new Subscriber() { - @Override - public void onStart() { - mView.showLoading(); - } + DisposableObserver disposableObserver = new DisposableObserver() { + @Override + protected void onStart() { + mView.showLoading(); + } - @Override - public void onCompleted() { - mView.hideLoading(); - } + @Override + public void onNext(Object o) { + RxBus.getInstance().post(new PlayListUpdatedEvent(playList)); + } - @Override - public void onError(Throwable e) { - mView.hideLoading(); - mView.handleError(e); - } + @Override + public void onError(Throwable e) { + mView.hideLoading(); + mView.handleError(e); + } - @Override - public void onNext(PlayList playList) { - RxBus.getInstance().post(new PlayListUpdatedEvent(playList)); - } - }); - mSubscriptions.add(subscription); + @Override + public void onComplete() { + mView.hideLoading(); + } + }; + mRepository.update(playList) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(disposableObserver); + mDisposables.add(disposableObserver); } @Override - public void delete(final Song song, PlayList playList) { + public void delete(final Song song, final PlayList playList) { playList.removeSong(song); - Subscription subscription = mRepository.update(playList) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(new Subscriber() { - @Override - public void onStart() { - mView.showLoading(); - } + DisposableObserver disposableObserver = new DisposableObserver() { + @Override + protected void onStart() { + mView.showLoading(); + } - @Override - public void onCompleted() { - mView.hideLoading(); - } + @Override + public void onNext(Object o) { + mView.onSongDeleted(song); + RxBus.getInstance().post(new PlayListUpdatedEvent(playList)); + } - @Override - public void onError(Throwable e) { - mView.hideLoading(); - mView.handleError(e); - } + @Override + public void onError(Throwable e) { + mView.hideLoading(); + mView.handleError(e); + } - @Override - public void onNext(PlayList playList) { - mView.onSongDeleted(song); - RxBus.getInstance().post(new PlayListUpdatedEvent(playList)); - } - }); - mSubscriptions.add(subscription); + @Override + public void onComplete() { + mView.hideLoading(); + } + }; + mDisposables.add(disposableObserver); } } diff --git a/app/src/main/java/io/github/ryanhoo/music/ui/local/all/AllLocalMusicFragment.java b/app/src/main/java/io/github/ryanhoo/music/ui/local/all/AllLocalMusicFragment.java index 929f43f..7504b64 100644 --- a/app/src/main/java/io/github/ryanhoo/music/ui/local/all/AllLocalMusicFragment.java +++ b/app/src/main/java/io/github/ryanhoo/music/ui/local/all/AllLocalMusicFragment.java @@ -8,6 +8,9 @@ import android.view.ViewGroup; import android.widget.ProgressBar; import android.widget.Toast; + +import java.util.List; + import butterknife.BindView; import butterknife.ButterKnife; import io.github.ryanhoo.music.R; @@ -20,11 +23,9 @@ import io.github.ryanhoo.music.ui.base.adapter.OnItemClickListener; import io.github.ryanhoo.music.ui.common.DefaultDividerDecoration; import io.github.ryanhoo.music.ui.widget.RecyclerViewFastScroller; -import rx.Subscription; -import rx.android.schedulers.AndroidSchedulers; -import rx.functions.Action1; - -import java.util.List; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Consumer; /** * Created with Android Studio. @@ -77,12 +78,12 @@ public void onItemClick(int position) { // RxBus Events @Override - protected Subscription subscribeEvents() { + protected Disposable subscribeEvents() { return RxBus.getInstance().toObservable() .observeOn(AndroidSchedulers.mainThread()) - .doOnNext(new Action1() { + .doOnNext(new Consumer() { @Override - public void call(Object o) { + public void accept(Object o) throws Exception { if (o instanceof PlayListUpdatedEvent) { mPresenter.loadLocalMusic(); } diff --git a/app/src/main/java/io/github/ryanhoo/music/ui/local/all/LocalMusicPresenter.java b/app/src/main/java/io/github/ryanhoo/music/ui/local/all/LocalMusicPresenter.java index 5251f3a..94ba3cf 100644 --- a/app/src/main/java/io/github/ryanhoo/music/ui/local/all/LocalMusicPresenter.java +++ b/app/src/main/java/io/github/ryanhoo/music/ui/local/all/LocalMusicPresenter.java @@ -8,17 +8,6 @@ import android.support.v4.content.CursorLoader; import android.support.v4.content.Loader; import android.util.Log; -import io.github.ryanhoo.music.data.model.Song; -import io.github.ryanhoo.music.data.source.AppRepository; -import io.github.ryanhoo.music.utils.FileUtils; -import rx.Observable; -import rx.Subscriber; -import rx.Subscription; -import rx.android.schedulers.AndroidSchedulers; -import rx.functions.Action1; -import rx.functions.Func1; -import rx.schedulers.Schedulers; -import rx.subscriptions.CompositeSubscription; import java.io.File; import java.util.ArrayList; @@ -26,6 +15,17 @@ import java.util.Comparator; import java.util.List; +import io.github.ryanhoo.music.data.model.Song; +import io.github.ryanhoo.music.data.source.AppRepository; +import io.github.ryanhoo.music.utils.FileUtils; +import io.reactivex.Observable; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.CompositeDisposable; +import io.reactivex.functions.Consumer; +import io.reactivex.functions.Function; +import io.reactivex.observers.DisposableObserver; +import io.reactivex.schedulers.Schedulers; + /** * Created with Android Studio. * User: ryan.hoo.j@gmail.com @@ -35,7 +35,7 @@ */ public class LocalMusicPresenter implements LocalMusicContract.Presenter, LoaderManager.LoaderCallbacks { - private static final String TAG = "LocalMusicPresenter"; + public static final String TAG = "LocalMusicPresenter"; private static final int URL_LOAD_LOCAL_MUSIC = 0; private static final Uri MEDIA_URI = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; @@ -58,12 +58,12 @@ public class LocalMusicPresenter implements LocalMusicContract.Presenter, Loader private LocalMusicContract.View mView; private AppRepository mRepository; - private CompositeSubscription mSubscriptions; + private CompositeDisposable mDisposables; public LocalMusicPresenter(AppRepository repository, LocalMusicContract.View view) { mView = view; mRepository = repository; - mSubscriptions = new CompositeSubscription(); + mDisposables = new CompositeDisposable(); mView.setPresenter(this); } @@ -75,7 +75,7 @@ public void subscribe() { @Override public void unsubscribe() { mView = null; - mSubscriptions.clear(); + mDisposables.clear(); } @Override @@ -100,10 +100,33 @@ public Loader onCreateLoader(int id, Bundle args) { @Override public void onLoadFinished(Loader loader, Cursor cursor) { - Subscription subscription = Observable.just(cursor) - .flatMap(new Func1>>() { + DisposableObserver disposableObserver = new DisposableObserver>() { + @Override + protected void onStart() { + mView.showProgress(); + } + + @Override + public void onNext(List songs) { + mView.onLocalMusicLoaded(songs); + mView.emptyView(songs.isEmpty()); + } + + @Override + public void onError(Throwable e) { + mView.hideProgress(); + Log.e(TAG, "onError: ", e); + } + + @Override + public void onComplete() { + mView.hideProgress(); + } + }; + Observable.just(cursor) + .flatMap(new Function>>() { @Override - public Observable> call(Cursor cursor) { + public Observable> apply(Cursor cursor) { List songs = new ArrayList<>(); if (cursor != null && cursor.getCount() > 0) { cursor.moveToFirst(); @@ -115,9 +138,9 @@ public Observable> call(Cursor cursor) { return mRepository.insert(songs); } }) - .doOnNext(new Action1>() { + .doOnNext(new Consumer>() { @Override - public void call(List songs) { + public void accept(List songs) throws Exception { Log.d(TAG, "onLoadFinished: " + songs.size()); Collections.sort(songs, new Comparator() { @Override @@ -125,35 +148,12 @@ public int compare(Song left, Song right) { return left.getDisplayName().compareTo(right.getDisplayName()); } }); - } }) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) - .subscribe(new Subscriber>() { - @Override - public void onStart() { - mView.showProgress(); - } - - @Override - public void onCompleted() { - mView.hideProgress(); - } - - @Override - public void onError(Throwable throwable) { - mView.hideProgress(); - Log.e(TAG, "onError: ", throwable); - } - - @Override - public void onNext(List songs) { - mView.onLocalMusicLoaded(songs); - mView.emptyView(songs.isEmpty()); - } - }); - mSubscriptions.add(subscription); + .subscribe(disposableObserver); + mDisposables.add(disposableObserver); } @Override diff --git a/app/src/main/java/io/github/ryanhoo/music/ui/local/filesystem/FileSystemActivity.java b/app/src/main/java/io/github/ryanhoo/music/ui/local/filesystem/FileSystemActivity.java index ddd6feb..a313046 100644 --- a/app/src/main/java/io/github/ryanhoo/music/ui/local/filesystem/FileSystemActivity.java +++ b/app/src/main/java/io/github/ryanhoo/music/ui/local/filesystem/FileSystemActivity.java @@ -9,6 +9,15 @@ import android.view.Menu; import android.view.MenuItem; import android.view.View; + +import java.io.File; +import java.util.ArrayList; + +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + import butterknife.BindView; import butterknife.ButterKnife; import io.github.ryanhoo.music.R; @@ -18,15 +27,11 @@ import io.github.ryanhoo.music.ui.base.adapter.OnItemClickListener; import io.github.ryanhoo.music.ui.base.adapter.OnItemLongClickListener; import io.github.ryanhoo.music.ui.common.DefaultDividerDecoration; -import rx.Observable; -import rx.Subscriber; -import rx.Subscription; -import rx.android.schedulers.AndroidSchedulers; -import rx.functions.Func1; -import rx.schedulers.Schedulers; - -import java.io.File; -import java.util.*; +import io.reactivex.Observable; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.functions.Function; +import io.reactivex.observers.DisposableObserver; +import io.reactivex.schedulers.Schedulers; /** * Created with Android Studio. @@ -166,10 +171,26 @@ private String getToolbarTitle(File parent) { // Load files private void loadFiles(final File parent) { - Subscription subscription = Observable.just(parent) - .flatMap(new Func1>>() { + DisposableObserver disposableObserver = new DisposableObserver>() { + @Override + public void onNext(List files) { + onFilesLoaded(parent, files); + } + + @Override + public void onError(Throwable e) { + Log.e(TAG, "onError: ", e); + } + + @Override + public void onComplete() { + toggleEmptyViewVisibility(); + } + }; + Observable.just(parent) + .flatMap(new Function>>() { @Override - public Observable> call(File parent) { + public Observable> apply(File parent) { List files = Arrays.asList(parent.listFiles(SystemFileFilter.DEFAULT_INSTANCE)); Collections.sort(files, new Comparator() { @Override @@ -193,23 +214,8 @@ public int compare(File f1, File f2) { }) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) - .subscribe(new Subscriber>() { - @Override - public void onCompleted() { - toggleEmptyViewVisibility(); - } - - @Override - public void onError(Throwable throwable) { - Log.e(TAG, "onError: ", throwable); - } - - @Override - public void onNext(List files) { - onFilesLoaded(parent, files); - } - }); - addSubscription(subscription); + .subscribe(disposableObserver); + addDisposable(disposableObserver); } private void onFilesLoaded(File parent, List files) { diff --git a/app/src/main/java/io/github/ryanhoo/music/ui/local/folder/FolderFragment.java b/app/src/main/java/io/github/ryanhoo/music/ui/local/folder/FolderFragment.java index 2e6d7a2..31d0ab2 100644 --- a/app/src/main/java/io/github/ryanhoo/music/ui/local/folder/FolderFragment.java +++ b/app/src/main/java/io/github/ryanhoo/music/ui/local/folder/FolderFragment.java @@ -5,9 +5,17 @@ import android.support.annotation.Nullable; import android.support.v7.widget.PopupMenu; import android.support.v7.widget.RecyclerView; -import android.view.*; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; import android.widget.ProgressBar; import android.widget.Toast; + +import java.io.File; +import java.util.List; + import butterknife.BindView; import butterknife.ButterKnife; import io.github.ryanhoo.music.R; @@ -24,12 +32,10 @@ import io.github.ryanhoo.music.ui.local.filesystem.FileSystemActivity; import io.github.ryanhoo.music.ui.playlist.AddToPlayListDialogFragment; import io.github.ryanhoo.music.ui.playlist.EditPlayListDialogFragment; -import rx.Subscription; -import rx.android.schedulers.AndroidSchedulers; -import rx.functions.Action1; - -import java.io.File; -import java.util.List; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Consumer; +import io.reactivex.observers.DisposableObserver; /** * Created with Android Studio. @@ -87,18 +93,20 @@ public void onDestroyView() { // RxBus Events @Override - protected Subscription subscribeEvents() { - return RxBus.getInstance().toObservable() + protected Disposable subscribeEvents() { + DisposableObserver disposableObserver = RxBus.defaultSubscriber(); + RxBus.getInstance().toObservable() .observeOn(AndroidSchedulers.mainThread()) - .doOnNext(new Action1() { + .doOnNext(new Consumer() { @Override - public void call(Object o) { + public void accept(Object o) { if (o instanceof AddFolderEvent) { onAddFolders((AddFolderEvent) o); } } }) - .subscribe(RxBus.defaultSubscriber()); + .subscribe(disposableObserver); + return disposableObserver; } private void onAddFolders(AddFolderEvent event) { diff --git a/app/src/main/java/io/github/ryanhoo/music/ui/local/folder/FolderPresenter.java b/app/src/main/java/io/github/ryanhoo/music/ui/local/folder/FolderPresenter.java index ebe9cd3..5e914d1 100644 --- a/app/src/main/java/io/github/ryanhoo/music/ui/local/folder/FolderPresenter.java +++ b/app/src/main/java/io/github/ryanhoo/music/ui/local/folder/FolderPresenter.java @@ -1,5 +1,10 @@ package io.github.ryanhoo.music.ui.local.folder; +import java.io.File; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + import io.github.ryanhoo.music.RxBus; import io.github.ryanhoo.music.data.model.Folder; import io.github.ryanhoo.music.data.model.PlayList; @@ -7,19 +12,14 @@ import io.github.ryanhoo.music.data.source.AppRepository; import io.github.ryanhoo.music.event.PlayListUpdatedEvent; import io.github.ryanhoo.music.utils.FileUtils; -import rx.Observable; -import rx.Subscriber; -import rx.Subscription; -import rx.android.schedulers.AndroidSchedulers; -import rx.functions.Action1; -import rx.functions.Func1; -import rx.schedulers.Schedulers; -import rx.subscriptions.CompositeSubscription; - -import java.io.File; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; +import io.reactivex.Observable; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.CompositeDisposable; +import io.reactivex.functions.Consumer; +import io.reactivex.functions.Function; +import io.reactivex.functions.Predicate; +import io.reactivex.observers.DisposableObserver; +import io.reactivex.schedulers.Schedulers; /** * Created with Android Studio. @@ -32,12 +32,12 @@ public class FolderPresenter implements FolderContract.Presenter { private FolderContract.View mView; private AppRepository mRepository; - private CompositeSubscription mSubscriptions; + private CompositeDisposable mDisposables; public FolderPresenter(AppRepository repository, FolderContract.View view) { mView = view; mRepository = repository; - mSubscriptions = new CompositeSubscription(); + mDisposables = new CompositeDisposable(); mView.setPresenter(this); } @@ -49,16 +49,38 @@ public void subscribe() { @Override public void unsubscribe() { mView = null; - mSubscriptions.clear(); + mDisposables.clear(); } @Override public void loadFolders() { - Subscription subscription = mRepository.folders() + DisposableObserver disposableObserver = new DisposableObserver>() { + @Override + protected void onStart() { + mView.showLoading(); + } + + @Override + public void onNext(List folders) { + mView.onFoldersLoaded(folders); + } + + @Override + public void onError(Throwable e) { + mView.hideLoading(); + mView.handleError(e); + } + + @Override + public void onComplete() { + mView.hideLoading(); + } + }; + mRepository.folders() .subscribeOn(Schedulers.io()) - .doOnNext(new Action1>() { + .doOnNext(new Consumer>() { @Override - public void call(List folders) { + public void accept(List folders) { Collections.sort(folders, new Comparator() { @Override public int compare(Folder f1, Folder f2) { @@ -68,37 +90,38 @@ public int compare(Folder f1, Folder f2) { } }) .observeOn(AndroidSchedulers.mainThread()) - .subscribe(new Subscriber>() { - @Override - public void onStart() { - mView.showLoading(); - } - - @Override - public void onCompleted() { - mView.hideLoading(); - } - - @Override - public void onError(Throwable e) { - mView.hideLoading(); - mView.handleError(e); - } - - @Override - public void onNext(List folders) { - mView.onFoldersLoaded(folders); - } - }); - mSubscriptions.add(subscription); + .subscribe(disposableObserver); + mDisposables.add(disposableObserver); } @Override public void addFolders(List folders, final List existedFolders) { - Subscription subscription = Observable.from(folders) - .filter(new Func1() { + DisposableObserver disposableObserver = new DisposableObserver>() { + @Override + protected void onStart() { + mView.showLoading(); + } + + @Override + public void onNext(List allNewFolders) { + mView.onFoldersAdded(allNewFolders); + } + + @Override + public void onError(Throwable e) { + mView.hideLoading(); + mView.handleError(e); + } + + @Override + public void onComplete() { + mView.hideLoading(); + } + }; + Observable.fromIterable(folders) + .filter(new Predicate() { @Override - public Boolean call(File file) { + public boolean test(File file) throws Exception { for (Folder folder : existedFolders) { if (file.getAbsolutePath().equals(folder.getPath())) { return false; @@ -107,9 +130,9 @@ public Boolean call(File file) { return true; } }) - .flatMap(new Func1>() { + .flatMap(new Function>() { @Override - public Observable call(File file) { + public Observable apply(File file) { Folder folder = new Folder(); folder.setName(file.getName()); folder.setPath(file.getAbsolutePath()); @@ -120,15 +143,16 @@ public Observable call(File file) { } }) .toList() - .flatMap(new Func1, Observable>>() { + .toObservable() + .flatMap(new Function, Observable>>() { @Override - public Observable> call(List folders) { + public Observable> apply(List folders) { return mRepository.create(folders); } }) - .doOnNext(new Action1>() { + .doOnNext(new Consumer>() { @Override - public void call(List folders) { + public void accept(List folders) { Collections.sort(folders, new Comparator() { @Override public int compare(Folder f1, Folder f2) { @@ -139,37 +163,38 @@ public int compare(Folder f1, Folder f2) { }) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) - .subscribe(new Subscriber>() { - @Override - public void onStart() { - mView.showLoading(); - } - - @Override - public void onCompleted() { - mView.hideLoading(); - } - - @Override - public void onError(Throwable e) { - mView.hideLoading(); - mView.handleError(e); - } - - @Override - public void onNext(List allNewFolders) { - mView.onFoldersAdded(allNewFolders); - } - }); - mSubscriptions.add(subscription); + .subscribe(disposableObserver); + mDisposables.add(disposableObserver); } @Override public void refreshFolder(final Folder folder) { - Subscription subscription = Observable.just(FileUtils.musicFiles(new File(folder.getPath()))) - .flatMap(new Func1, Observable>() { + DisposableObserver disposableObserver = new DisposableObserver() { + @Override + protected void onStart() { + mView.showLoading(); + } + + @Override + public void onNext(Folder folder) { + mView.onFolderUpdated(folder); + } + + @Override + public void onError(Throwable e) { + mView.hideLoading(); + mView.handleError(e); + } + + @Override + public void onComplete() { + mView.hideLoading(); + } + }; + Observable.just(FileUtils.musicFiles(new File(folder.getPath()))) + .flatMap(new Function, Observable>() { @Override - public Observable call(List songs) { + public Observable apply(List songs) { folder.setSongs(songs); folder.setNumOfSongs(songs.size()); return mRepository.update(folder); @@ -177,90 +202,73 @@ public Observable call(List songs) { }) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) - .subscribe(new Subscriber() { - @Override - public void onStart() { - mView.showLoading(); - } - - @Override - public void onCompleted() { - mView.hideLoading(); - } - - @Override - public void onError(Throwable e) { - mView.hideLoading(); - mView.handleError(e); - } - - @Override - public void onNext(Folder folder) { - mView.onFolderUpdated(folder); - } - }); - mSubscriptions.add(subscription); + .subscribe(disposableObserver); + mDisposables.add(disposableObserver); } @Override public void deleteFolder(Folder folder) { - Subscription subscription = mRepository.delete(folder) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(new Subscriber() { - @Override - public void onStart() { - mView.showLoading(); - } + DisposableObserver disposableObserver = new DisposableObserver() { + @Override + protected void onStart() { + mView.showLoading(); + } - @Override - public void onCompleted() { - mView.hideLoading(); - } + @Override + public void onNext(Folder folder) { + mView.onFolderDeleted(folder); + } - @Override - public void onError(Throwable e) { - mView.hideLoading(); - mView.handleError(e); - } + @Override + public void onError(Throwable e) { + mView.hideLoading(); + mView.handleError(e); + } - @Override - public void onNext(Folder folder) { - mView.onFolderDeleted(folder); - } - }); - mSubscriptions.add(subscription); + @Override + public void onComplete() { + mView.hideLoading(); + } + }; + + mRepository.delete(folder) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(disposableObserver); + mDisposables.add(disposableObserver); } @Override public void createPlayList(PlayList playList) { - Subscription subscription = mRepository - .create(playList) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(new Subscriber() { - @Override - public void onStart() { - mView.showLoading(); - } + DisposableObserver disposableObserver = new DisposableObserver() { + @Override + protected void onStart() { + mView.showLoading(); + } - @Override - public void onCompleted() { - mView.hideLoading(); - } + @Override + public void onNext(PlayList playList) { + mView.onPlayListCreated(playList); + } - @Override - public void onError(Throwable e) { - mView.hideLoading(); - mView.handleError(e); - } + @Override + public void onError(Throwable e) { + mView.hideLoading(); + mView.handleError(e); + } - @Override - public void onNext(PlayList playList) { - mView.onPlayListCreated(playList); - } - }); - mSubscriptions.add(subscription); + @Override + public void onComplete() { + mView.hideLoading(); + } + }; + + mRepository + .create(playList) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(disposableObserver); + mDisposables.add(disposableObserver); } @Override @@ -273,31 +281,33 @@ public void addFolderToPlayList(final Folder folder, PlayList playList) { } } playList.addSong(folder.getSongs(), 0); - Subscription subscription = mRepository.update(playList) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(new Subscriber() { - @Override - public void onStart() { - mView.showLoading(); - } - @Override - public void onCompleted() { - mView.hideLoading(); - } + DisposableObserver disposableObserver = new DisposableObserver() { + @Override + protected void onStart() { + mView.showLoading(); + } - @Override - public void onError(Throwable e) { - mView.hideLoading(); - mView.handleError(e); - } + @Override + public void onNext(PlayList playList) { + RxBus.getInstance().post(new PlayListUpdatedEvent(playList)); + } - @Override - public void onNext(PlayList playList) { - RxBus.getInstance().post(new PlayListUpdatedEvent(playList)); - } - }); - mSubscriptions.add(subscription); + @Override + public void onError(Throwable e) { + mView.hideLoading(); + mView.handleError(e); + } + + @Override + public void onComplete() { + mView.hideLoading(); + } + }; + mRepository.update(playList) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(disposableObserver); + mDisposables.add(disposableObserver); } } diff --git a/app/src/main/java/io/github/ryanhoo/music/ui/music/MusicPlayerFragment.java b/app/src/main/java/io/github/ryanhoo/music/ui/music/MusicPlayerFragment.java index 228ced1..3fc627c 100644 --- a/app/src/main/java/io/github/ryanhoo/music/ui/music/MusicPlayerFragment.java +++ b/app/src/main/java/io/github/ryanhoo/music/ui/music/MusicPlayerFragment.java @@ -13,6 +13,7 @@ import android.widget.SeekBar; import android.widget.TextView; import android.widget.Toast; + import butterknife.BindView; import butterknife.ButterKnife; import butterknife.OnClick; @@ -31,9 +32,10 @@ import io.github.ryanhoo.music.ui.widget.ShadowImageView; import io.github.ryanhoo.music.utils.AlbumUtils; import io.github.ryanhoo.music.utils.TimeUtils; -import rx.Subscription; -import rx.android.schedulers.AndroidSchedulers; -import rx.functions.Action1; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Consumer; +import io.reactivex.observers.DisposableObserver; /** * Created with Android Studio. @@ -207,12 +209,13 @@ public void onFavoriteToggleAction(View view) { // RXBus Events @Override - protected Subscription subscribeEvents() { - return RxBus.getInstance().toObservable() + protected Disposable subscribeEvents() { + DisposableObserver disposableObserver = RxBus.defaultSubscriber(); + RxBus.getInstance().toObservable() .observeOn(AndroidSchedulers.mainThread()) - .doOnNext(new Action1() { + .doOnNext(new Consumer() { @Override - public void call(Object o) { + public void accept(Object o) { if (o instanceof PlaySongEvent) { onPlaySongEvent((PlaySongEvent) o); } else if (o instanceof PlayListNowEvent) { @@ -220,7 +223,8 @@ public void call(Object o) { } } }) - .subscribe(RxBus.defaultSubscriber()); + .subscribe(disposableObserver); + return disposableObserver; } private void onPlaySongEvent(PlaySongEvent event) { diff --git a/app/src/main/java/io/github/ryanhoo/music/ui/music/MusicPlayerPresenter.java b/app/src/main/java/io/github/ryanhoo/music/ui/music/MusicPlayerPresenter.java index 312056e..d3f6093 100644 --- a/app/src/main/java/io/github/ryanhoo/music/ui/music/MusicPlayerPresenter.java +++ b/app/src/main/java/io/github/ryanhoo/music/ui/music/MusicPlayerPresenter.java @@ -5,6 +5,7 @@ import android.content.Intent; import android.content.ServiceConnection; import android.os.IBinder; + import io.github.ryanhoo.music.RxBus; import io.github.ryanhoo.music.data.model.Song; import io.github.ryanhoo.music.data.source.AppRepository; @@ -12,11 +13,10 @@ import io.github.ryanhoo.music.event.FavoriteChangeEvent; import io.github.ryanhoo.music.player.PlayMode; import io.github.ryanhoo.music.player.PlaybackService; -import rx.Subscriber; -import rx.Subscription; -import rx.android.schedulers.AndroidSchedulers; -import rx.schedulers.Schedulers; -import rx.subscriptions.CompositeSubscription; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.CompositeDisposable; +import io.reactivex.observers.DisposableObserver; +import io.reactivex.schedulers.Schedulers; /** * Created with Android Studio. @@ -30,7 +30,7 @@ public class MusicPlayerPresenter implements MusicPlayerContract.Presenter { private Context mContext; private MusicPlayerContract.View mView; private AppRepository mRepository; - private CompositeSubscription mSubscriptions; + private CompositeDisposable mDisposables; private PlaybackService mPlaybackService; private boolean mIsServiceBound; @@ -61,7 +61,7 @@ public MusicPlayerPresenter(Context context, AppRepository repository, MusicPlay mContext = context; mView = view; mRepository = repository; - mSubscriptions = new CompositeSubscription(); + mDisposables = new CompositeDisposable(); mView.setPresenter(this); } @@ -85,7 +85,7 @@ public void unsubscribe() { // Release context reference mContext = null; mView = null; - mSubscriptions.clear(); + mDisposables.clear(); } @Override @@ -96,27 +96,28 @@ public void retrieveLastPlayMode() { @Override public void setSongAsFavorite(Song song, boolean favorite) { - Subscription subscription = mRepository.setSongAsFavorite(song, favorite) + DisposableObserver disposableObserver = new DisposableObserver() { + + @Override + public void onNext(Song song) { + mView.onSongSetAsFavorite(song); + RxBus.getInstance().post(new FavoriteChangeEvent(song)); + } + + @Override + public void onError(Throwable e) { + mView.handleError(e); + } + + @Override + public void onComplete() { + } + }; + mRepository.setSongAsFavorite(song, favorite) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) - .subscribe(new Subscriber() { - @Override - public void onCompleted() { - // Empty - } - - @Override - public void onError(Throwable e) { - mView.handleError(e); - } - - @Override - public void onNext(Song song) { - mView.onSongSetAsFavorite(song); - RxBus.getInstance().post(new FavoriteChangeEvent(song)); - } - }); - mSubscriptions.add(subscription); + .subscribe(disposableObserver); + mDisposables.add(disposableObserver); } @Override diff --git a/app/src/main/java/io/github/ryanhoo/music/ui/playlist/AddToPlayListDialogFragment.java b/app/src/main/java/io/github/ryanhoo/music/ui/playlist/AddToPlayListDialogFragment.java index a09259e..4d8647b 100644 --- a/app/src/main/java/io/github/ryanhoo/music/ui/playlist/AddToPlayListDialogFragment.java +++ b/app/src/main/java/io/github/ryanhoo/music/ui/playlist/AddToPlayListDialogFragment.java @@ -10,6 +10,9 @@ import android.support.v7.widget.RecyclerView; import android.view.View; import android.view.ViewGroup; + +import java.util.List; + import io.github.ryanhoo.music.R; import io.github.ryanhoo.music.data.model.PlayList; import io.github.ryanhoo.music.data.source.AppRepository; @@ -17,9 +20,7 @@ import io.github.ryanhoo.music.ui.base.adapter.ListAdapter; import io.github.ryanhoo.music.ui.base.adapter.OnItemClickListener; import io.github.ryanhoo.music.ui.common.DefaultDividerDecoration; -import rx.subscriptions.CompositeSubscription; - -import java.util.List; +import io.reactivex.disposables.CompositeDisposable; /** * Created with Android Studio. @@ -32,7 +33,7 @@ public class AddToPlayListDialogFragment extends BaseDialogFragment implements O RecyclerView recyclerView; - CompositeSubscription mSubscriptions = new CompositeSubscription(); + CompositeDisposable mDisposables = new CompositeDisposable(); AddPlayListAdapter mAdapter; Callback mCallback; @@ -58,7 +59,7 @@ public Dialog onCreateDialog(Bundle savedInstanceState) { @Override public void onDestroyView() { - mSubscriptions.clear(); + mDisposables.clear(); super.onDestroyView(); } diff --git a/app/src/main/java/io/github/ryanhoo/music/ui/playlist/PlayListFragment.java b/app/src/main/java/io/github/ryanhoo/music/ui/playlist/PlayListFragment.java index 5ad3778..bf82746 100644 --- a/app/src/main/java/io/github/ryanhoo/music/ui/playlist/PlayListFragment.java +++ b/app/src/main/java/io/github/ryanhoo/music/ui/playlist/PlayListFragment.java @@ -4,9 +4,16 @@ import android.support.annotation.Nullable; import android.support.v7.widget.PopupMenu; import android.support.v7.widget.RecyclerView; -import android.view.*; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; import android.widget.ProgressBar; import android.widget.Toast; + +import java.util.List; + import butterknife.BindView; import butterknife.ButterKnife; import io.github.ryanhoo.music.R; @@ -17,15 +24,15 @@ import io.github.ryanhoo.music.event.PlayListCreatedEvent; import io.github.ryanhoo.music.event.PlayListNowEvent; import io.github.ryanhoo.music.event.PlayListUpdatedEvent; +import io.github.ryanhoo.music.event.PlaySongEvent; import io.github.ryanhoo.music.ui.base.BaseFragment; import io.github.ryanhoo.music.ui.base.adapter.OnItemClickListener; import io.github.ryanhoo.music.ui.common.DefaultDividerDecoration; import io.github.ryanhoo.music.ui.details.PlayListDetailsActivity; -import rx.Subscription; -import rx.android.schedulers.AndroidSchedulers; -import rx.functions.Action1; - -import java.util.List; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Consumer; +import io.reactivex.observers.DisposableObserver; /** * Created with Android Studio. @@ -82,12 +89,13 @@ public void onDestroyView() { // RxBus Events @Override - protected Subscription subscribeEvents() { - return RxBus.getInstance().toObservable() + protected Disposable subscribeEvents() { + DisposableObserver disposableObserver = RxBus.defaultSubscriber(); + RxBus.getInstance().toObservable() .observeOn(AndroidSchedulers.mainThread()) - .doOnNext(new Action1() { + .doOnNext(new Consumer() { @Override - public void call(Object o) { + public void accept(Object o) { if (o instanceof PlayListCreatedEvent) { onPlayListCreatedEvent((PlayListCreatedEvent) o); } else if (o instanceof FavoriteChangeEvent) { @@ -97,7 +105,8 @@ public void call(Object o) { } } }) - .subscribe(RxBus.defaultSubscriber()); + .subscribe(disposableObserver); + return disposableObserver; } private void onPlayListCreatedEvent(PlayListCreatedEvent event) { diff --git a/app/src/main/java/io/github/ryanhoo/music/ui/playlist/PlayListPresenter.java b/app/src/main/java/io/github/ryanhoo/music/ui/playlist/PlayListPresenter.java index 0b89aff..3175cb8 100644 --- a/app/src/main/java/io/github/ryanhoo/music/ui/playlist/PlayListPresenter.java +++ b/app/src/main/java/io/github/ryanhoo/music/ui/playlist/PlayListPresenter.java @@ -1,14 +1,13 @@ package io.github.ryanhoo.music.ui.playlist; +import java.util.List; + import io.github.ryanhoo.music.data.model.PlayList; import io.github.ryanhoo.music.data.source.AppRepository; -import rx.Subscriber; -import rx.Subscription; -import rx.android.schedulers.AndroidSchedulers; -import rx.schedulers.Schedulers; -import rx.subscriptions.CompositeSubscription; - -import java.util.List; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.CompositeDisposable; +import io.reactivex.observers.DisposableObserver; +import io.reactivex.schedulers.Schedulers; /** * Created with Android Studio. @@ -21,12 +20,12 @@ public class PlayListPresenter implements PlayListContract.Presenter { private PlayListContract.View mView; private AppRepository mRepository; - private CompositeSubscription mSubscriptions; + private CompositeDisposable mDisposables; public PlayListPresenter(AppRepository repository, PlayListContract.View view) { mView = view; mRepository = repository; - mSubscriptions = new CompositeSubscription(); + mDisposables = new CompositeDisposable(); mView.setPresenter(this); } @@ -38,128 +37,127 @@ public void subscribe() { @Override public void unsubscribe() { mView = null; - mSubscriptions.clear(); + mDisposables.clear(); } @Override public void loadPlayLists() { - Subscription subscription = mRepository.playLists() + DisposableObserver disposableObserver = new DisposableObserver>() { + @Override + protected void onStart() { + mView.showLoading(); + } + + @Override + public void onNext(List playLists) { + mView.onPlayListsLoaded(playLists); + } + + @Override + public void onError(Throwable e) { + mView.hideLoading(); + mView.handleError(e); + } + + @Override + public void onComplete() { + mView.hideLoading(); + } + }; + mRepository.playLists() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) - .subscribe(new Subscriber>() { - @Override - public void onStart() { - mView.showLoading(); - } - - @Override - public void onCompleted() { - mView.hideLoading(); - } - - @Override - public void onError(Throwable e) { - mView.hideLoading(); - mView.handleError(e); - } - - @Override - public void onNext(List playLists) { - mView.onPlayListsLoaded(playLists); - } - }); - mSubscriptions.add(subscription); + .subscribe(disposableObserver); + mDisposables.add(disposableObserver); } @Override public void createPlayList(PlayList playList) { - Subscription subscription = mRepository - .create(playList) + DisposableObserver disposableObserver = new DisposableObserver() { + @Override + protected void onStart() { + mView.showLoading(); + } + + @Override + public void onNext(PlayList result) { + mView.onPlayListCreated(result); + } + + @Override + public void onError(Throwable e) { + mView.hideLoading(); + mView.handleError(e); + } + + @Override + public void onComplete() { + mView.hideLoading(); + } + }; + mRepository.create(playList) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) - .subscribe(new Subscriber() { - @Override - public void onStart() { - mView.showLoading(); - } - - @Override - public void onCompleted() { - mView.hideLoading(); - } - - @Override - public void onError(Throwable e) { - mView.hideLoading(); - mView.handleError(e); - } - - @Override - public void onNext(PlayList result) { - mView.onPlayListCreated(result); - } - }); - mSubscriptions.add(subscription); + .subscribe(disposableObserver); + mDisposables.add(disposableObserver); } @Override public void editPlayList(PlayList playList) { - Subscription subscription = mRepository - .update(playList) + DisposableObserver disposableObserver = new DisposableObserver() { + @Override + protected void onStart() { + mView.showLoading(); + } + + @Override + public void onNext(PlayList result) { + mView.onPlayListEdited(result); + } + + @Override + public void onError(Throwable e) { + mView.hideLoading(); + mView.handleError(e); + } + + @Override + public void onComplete() { + mView.hideLoading(); + } + }; + + mRepository.update(playList) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) - .subscribe(new Subscriber() { - @Override - public void onStart() { - mView.showLoading(); - } - - @Override - public void onCompleted() { - mView.hideLoading(); - } - - @Override - public void onError(Throwable e) { - mView.hideLoading(); - mView.handleError(e); - } - - @Override - public void onNext(PlayList result) { - mView.onPlayListEdited(result); - } - }); - mSubscriptions.add(subscription); + .subscribe(disposableObserver); + mDisposables.add(disposableObserver); } @Override - public void deletePlayList(PlayList playList) { - Subscription subscription = mRepository.delete(playList) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(new Subscriber() { - @Override - public void onStart() { - mView.showLoading(); - } - - @Override - public void onCompleted() { - mView.hideLoading(); - } - - @Override - public void onError(Throwable e) { - mView.hideLoading(); - mView.handleError(e); - } - - @Override - public void onNext(PlayList playList) { - mView.onPlayListDeleted(playList); - } - }); - mSubscriptions.add(subscription); + public void deletePlayList(final PlayList playList) { + DisposableObserver disposableObserver = new DisposableObserver() { + @Override + protected void onStart() { + mView.showLoading(); + } + + @Override + public void onNext(Object o) { + mView.onPlayListDeleted(playList); + } + + @Override + public void onError(Throwable e) { + mView.hideLoading(); + mView.handleError(e); + } + + @Override + public void onComplete() { + mView.hideLoading(); + } + }; + mDisposables.add(disposableObserver); } } diff --git a/app/src/main/java/io/github/ryanhoo/music/utils/FileUtils.java b/app/src/main/java/io/github/ryanhoo/music/utils/FileUtils.java index fd42e3d..4c4a765 100644 --- a/app/src/main/java/io/github/ryanhoo/music/utils/FileUtils.java +++ b/app/src/main/java/io/github/ryanhoo/music/utils/FileUtils.java @@ -2,8 +2,11 @@ import android.media.MediaMetadataRetriever; import android.text.TextUtils; +import android.util.Log; + import io.github.ryanhoo.music.data.model.Folder; import io.github.ryanhoo.music.data.model.Song; +import io.github.ryanhoo.music.ui.local.all.LocalMusicPresenter; import java.io.File; import java.io.FileFilter; @@ -77,8 +80,13 @@ public static Song fileToMusic(File file) { if (file.length() == 0) return null; MediaMetadataRetriever metadataRetriever = new MediaMetadataRetriever(); - metadataRetriever.setDataSource(file.getAbsolutePath()); - + try {//add s + metadataRetriever.setDataSource(file.getAbsolutePath()); + } catch (Exception e) { + metadataRetriever.release(); + Log.d(LocalMusicPresenter.TAG, "metadataRetriever--Exception--" + e); + return null; + }//add end final int duration; String keyDuration = metadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION); @@ -99,6 +107,8 @@ public static Song fileToMusic(File file) { song.setAlbum(album); song.setDuration(duration); song.setSize((int) file.length()); + + metadataRetriever.release(); return song; } diff --git a/build.gradle b/build.gradle index b0898ac..2ceea80 100644 --- a/build.gradle +++ b/build.gradle @@ -1,24 +1,41 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { + repositories { + maven { + url "https://maven.google.com" + } + maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' } jcenter() + mavenCentral() + google() + } dependencies { - classpath 'com.android.tools.build:gradle:2.2.0' - + classpath 'com.android.tools.build:gradle:3.1.3' +// classpath 'com.jakewharton:butterknife-gradle-plugin:8.4.0' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files - classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8' } } allprojects { repositories { + maven { + url "https://maven.google.com" + } + + mavenCentral() jcenter() + google() + flatDir { + dirs 'libs' + } + maven { url "https://jitpack.io" } } } task clean(type: Delete) { delete rootProject.buildDir -} +} \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 13372aef5e24af05341d49695ee84e5f9b594659..f6b961fd5a86aa5fbfe90f707c3138408be7c718 100644 GIT binary patch delta 41595 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 delta 41017 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 YJa(A^3rM$<$}NaSLW+iF*?#ixe-7>3SpWb4 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 7194a24..d58e3f3 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Wed Aug 24 17:00:21 CST 2016 +#Wed Jun 05 09:12:21 CST 2019 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip diff --git a/gradlew b/gradlew index 9d82f78..cccdd3d 100755 --- a/gradlew +++ b/gradlew @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/usr/bin/env sh ############################################################################## ## @@ -6,20 +6,38 @@ ## ############################################################################## -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null APP_NAME="Gradle" APP_BASE_NAME=`basename "$0"` +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" -warn ( ) { +warn () { echo "$*" } -die ( ) { +die () { echo echo "$*" echo @@ -30,6 +48,7 @@ die ( ) { cygwin=false msys=false darwin=false +nonstop=false case "`uname`" in CYGWIN* ) cygwin=true @@ -40,26 +59,11 @@ case "`uname`" in MINGW* ) msys=true ;; + NONSTOP* ) + nonstop=true + ;; esac -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null - CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -85,7 +89,7 @@ location of your Java installation." fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then MAX_FD_LIMIT=`ulimit -H -n` if [ $? -eq 0 ] ; then if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then @@ -150,11 +154,19 @@ if $cygwin ; then esac fi -# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules -function splitJvmOpts() { - JVM_OPTS=("$@") +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " } -eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS -JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi -exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index aec9973..e95643d 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -8,14 +8,14 @@ @rem Set local scope for the variables with windows NT shell if "%OS%"=="Windows_NT" setlocal -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - set DIRNAME=%~dp0 if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome @@ -46,10 +46,9 @@ echo location of your Java installation. goto fail :init -@rem Get command-line arguments, handling Windowz variants +@rem Get command-line arguments, handling Windows variants if not "%OS%" == "Windows_NT" goto win9xME_args -if "%@eval[2+2]" == "4" goto 4NT_args :win9xME_args @rem Slurp the command line arguments. @@ -60,11 +59,6 @@ set _SKIP=2 if "x%~1" == "x" goto execute set CMD_LINE_ARGS=%* -goto execute - -:4NT_args -@rem Get arguments from the 4NT Shell from JP Software -set CMD_LINE_ARGS=%$ :execute @rem Setup the command line