Merge pull request #220 from ultrasonic/use-koin-beta

Migrate koin to 1.0.0-beta-3 version.
This commit is contained in:
Yahor Berdnikau 2018-08-03 22:13:44 +02:00 committed by GitHub
commit 881c85a390
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 73 additions and 71 deletions

View File

@ -20,7 +20,7 @@ ext.versions = [
okhttp : "3.10.0", okhttp : "3.10.0",
semver : "1.0.0", semver : "1.0.0",
twitterSerial : "0.1.6", twitterSerial : "0.1.6",
koin : "0.9.3", koin : "1.0.0-beta-3",
picasso : "2.71828", picasso : "2.71828",
junit : "4.12", junit : "4.12",
@ -57,6 +57,7 @@ ext.other = [
semver : "net.swiftzer.semver:semver:$versions.semver", semver : "net.swiftzer.semver:semver:$versions.semver",
twitterSerial : "com.twitter.serial:serial:$versions.twitterSerial", twitterSerial : "com.twitter.serial:serial:$versions.twitterSerial",
koinCore : "org.koin:koin-core:$versions.koin", koinCore : "org.koin:koin-core:$versions.koin",
koinJava : "org.koin:koin-java:$versions.koin",
koinAndroid : "org.koin:koin-android:$versions.koin", koinAndroid : "org.koin:koin-android:$versions.koin",
picasso : "com.squareup.picasso:picasso:$versions.picasso", picasso : "com.squareup.picasso:picasso:$versions.picasso",
] ]
@ -73,4 +74,5 @@ ext.testing = [
apacheCodecs : "commons-codec:commons-codec:$versions.apacheCodecs", apacheCodecs : "commons-codec:commons-codec:$versions.apacheCodecs",
testRunner : "com.android.support.test:runner:$versions.testRunner", testRunner : "com.android.support.test:runner:$versions.testRunner",
robolectric : "org.robolectric:robolectric:$versions.robolectric", robolectric : "org.robolectric:robolectric:$versions.robolectric",
koinTest : "org.koin:koin-test:$versions.koin"
] ]

View File

@ -1,10 +1,10 @@
package org.moire.ultrasonic.api.subsonic.di package org.moire.ultrasonic.api.subsonic.di
import org.koin.dsl.context.Context import org.koin.dsl.context.ModuleDefinition
import org.moire.ultrasonic.api.subsonic.SubsonicAPIClient import org.moire.ultrasonic.api.subsonic.SubsonicAPIClient
const val SUBSONIC_API_CLIENT_CONTEXT = "SubsonicApiClientContext" const val SUBSONIC_API_CLIENT_CONTEXT = "SubsonicApiClientContext"
fun Context.subsonicApiModule() = context(SUBSONIC_API_CLIENT_CONTEXT) { fun ModuleDefinition.subsonicApiModule() = module(SUBSONIC_API_CLIENT_CONTEXT) {
bean { return@bean SubsonicAPIClient(get(), get()) } single { SubsonicAPIClient(get(), get()) }
} }

View File

@ -63,6 +63,7 @@ dependencies {
implementation other.kotlinStdlib implementation other.kotlinStdlib
implementation other.koinAndroid implementation other.koinAndroid
implementation other.koinJava
testImplementation other.kotlinReflect testImplementation other.kotlinReflect
testImplementation testing.junit testImplementation testing.junit

View File

@ -38,15 +38,17 @@ import android.view.View.OnTouchListener;
import android.widget.*; import android.widget.*;
import net.simonvt.menudrawer.MenuDrawer; import net.simonvt.menudrawer.MenuDrawer;
import net.simonvt.menudrawer.Position; import net.simonvt.menudrawer.Position;
import org.koin.java.standalone.KoinJavaComponent;
import org.moire.ultrasonic.R; import org.moire.ultrasonic.R;
import org.moire.ultrasonic.app.UApp;
import org.moire.ultrasonic.domain.MusicDirectory; import org.moire.ultrasonic.domain.MusicDirectory;
import org.moire.ultrasonic.domain.MusicDirectory.Entry; import org.moire.ultrasonic.domain.MusicDirectory.Entry;
import org.moire.ultrasonic.domain.PlayerState; import org.moire.ultrasonic.domain.PlayerState;
import org.moire.ultrasonic.domain.Share; import org.moire.ultrasonic.domain.Share;
import org.moire.ultrasonic.featureflags.Feature; import org.moire.ultrasonic.featureflags.Feature;
import org.moire.ultrasonic.featureflags.FeatureStorage;
import org.moire.ultrasonic.service.*; import org.moire.ultrasonic.service.*;
import org.moire.ultrasonic.subsonic.SubsonicImageLoaderProxy; import org.moire.ultrasonic.subsonic.SubsonicImageLoaderProxy;
import org.moire.ultrasonic.subsonic.loader.image.SubsonicImageLoader;
import org.moire.ultrasonic.util.*; import org.moire.ultrasonic.util.*;
import java.io.File; import java.io.File;
@ -808,12 +810,12 @@ public class SubsonicTabActivity extends ResultActivity implements OnClickListen
Util.getImageLoaderConcurrency(this) Util.getImageLoaderConcurrency(this)
); );
boolean isNewImageLoaderEnabled = ((UApp) getApplication()).getFeaturesStorage() boolean isNewImageLoaderEnabled = KoinJavaComponent.get(FeatureStorage.class)
.isFeatureEnabled(Feature.NEW_IMAGE_DOWNLOADER); .isFeatureEnabled(Feature.NEW_IMAGE_DOWNLOADER);
if (isNewImageLoaderEnabled) { if (isNewImageLoaderEnabled) {
IMAGE_LOADER = new SubsonicImageLoaderProxy( IMAGE_LOADER = new SubsonicImageLoaderProxy(
legacyImageLoader, legacyImageLoader,
((UApp) getApplication()).getSubsonicImageLoader() KoinJavaComponent.get(SubsonicImageLoader.class)
); );
} else { } else {
IMAGE_LOADER = legacyImageLoader; IMAGE_LOADER = legacyImageLoader;

View File

@ -9,10 +9,10 @@ import android.provider.SearchRecentSuggestions;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
import org.koin.java.standalone.KoinJavaComponent;
import org.moire.ultrasonic.R; import org.moire.ultrasonic.R;
import org.moire.ultrasonic.activity.ServerSettingsActivity; import org.moire.ultrasonic.activity.ServerSettingsActivity;
import org.moire.ultrasonic.activity.SubsonicTabActivity; import org.moire.ultrasonic.activity.SubsonicTabActivity;
import org.moire.ultrasonic.app.UApp;
import org.moire.ultrasonic.featureflags.Feature; import org.moire.ultrasonic.featureflags.Feature;
import org.moire.ultrasonic.featureflags.FeatureStorage; import org.moire.ultrasonic.featureflags.FeatureStorage;
import org.moire.ultrasonic.provider.SearchSuggestionProvider; import org.moire.ultrasonic.provider.SearchSuggestionProvider;
@ -175,7 +175,7 @@ public class SettingsFragment extends PreferenceFragment
CheckBoxPreference ffImageLoader = (CheckBoxPreference) findPreference( CheckBoxPreference ffImageLoader = (CheckBoxPreference) findPreference(
Constants.PREFERENCES_KEY_FF_IMAGE_LOADER); Constants.PREFERENCES_KEY_FF_IMAGE_LOADER);
final FeatureStorage featureStorage = ((UApp) getActivity().getApplication()).getFeaturesStorage(); final FeatureStorage featureStorage = KoinJavaComponent.get(FeatureStorage.class);
if (ffImageLoader != null) { if (ffImageLoader != null) {
ffImageLoader.setChecked(featureStorage.isFeatureEnabled(Feature.NEW_IMAGE_DOWNLOADER)); ffImageLoader.setChecked(featureStorage.isFeatureEnabled(Feature.NEW_IMAGE_DOWNLOADER));
ffImageLoader.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { ffImageLoader.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {

View File

@ -1,40 +1,29 @@
package org.moire.ultrasonic.app package org.moire.ultrasonic.app
import android.app.Application import android.app.Application
import org.koin.android.ext.android.get
import org.koin.android.ext.android.startKoin import org.koin.android.ext.android.startKoin
import org.moire.ultrasonic.di.DiProperties
import org.moire.ultrasonic.di.appPermanentStorage
import org.moire.ultrasonic.di.baseNetworkModule import org.moire.ultrasonic.di.baseNetworkModule
import org.moire.ultrasonic.di.directoriesModule import org.moire.ultrasonic.di.directoriesModule
import org.moire.ultrasonic.di.featureFlagsModule import org.moire.ultrasonic.di.featureFlagsModule
import org.moire.ultrasonic.di.musicServiceModule import org.moire.ultrasonic.di.musicServiceModule
import org.moire.ultrasonic.featureflags.FeatureStorage
import org.moire.ultrasonic.subsonic.loader.image.SubsonicImageLoader
import org.moire.ultrasonic.util.Util
class UApp : Application() { class UApp : Application() {
override fun onCreate() { override fun onCreate() {
super.onCreate() super.onCreate()
val sharedPreferences = Util.getPreferences(this) startKoin(this,
startKoin(this, listOf( listOf(
directoriesModule, directoriesModule,
appPermanentStorage,
baseNetworkModule, baseNetworkModule,
featureFlagsModule(this), featureFlagsModule,
musicServiceModule(sharedPreferences, this) musicServiceModule
)) ),
} extraProperties = mapOf(
DiProperties.APP_CONTEXT to applicationContext
/** )
* Temporary method to get subsonic image loader from java code. )
*/
fun getSubsonicImageLoader(): SubsonicImageLoader {
return get()
}
/**
* Temporary method to get features storage.
*/
fun getFeaturesStorage(): FeatureStorage {
return get()
} }
} }

View File

@ -0,0 +1,10 @@
package org.moire.ultrasonic.di
import org.koin.dsl.module.module
import org.moire.ultrasonic.util.Util
const val SP_NAME = "Default_SP"
val appPermanentStorage = module {
single(name = SP_NAME) { Util.getPreferences(getProperty(DiProperties.APP_CONTEXT)) }
}

View File

@ -1,11 +1,11 @@
package org.moire.ultrasonic.di package org.moire.ultrasonic.di
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import org.koin.dsl.module.applicationContext import org.koin.dsl.module.module
/** /**
* Provides base network dependencies. * Provides base network dependencies.
*/ */
val baseNetworkModule = applicationContext { val baseNetworkModule = module {
bean { OkHttpClient.Builder().build() } single { OkHttpClient.Builder().build() }
} }

View File

@ -0,0 +1,5 @@
package org.moire.ultrasonic.di
object DiProperties {
const val APP_CONTEXT = "app_context"
}

View File

@ -1,9 +1,9 @@
package org.moire.ultrasonic.di package org.moire.ultrasonic.di
import org.koin.dsl.module.applicationContext import org.koin.dsl.module.module
import org.moire.ultrasonic.cache.AndroidDirectories import org.moire.ultrasonic.cache.AndroidDirectories
import org.moire.ultrasonic.cache.Directories import org.moire.ultrasonic.cache.Directories
val directoriesModule = applicationContext { val directoriesModule = module {
bean { AndroidDirectories(get()) } bind Directories::class single { AndroidDirectories(get()) } bind Directories::class
} }

View File

@ -1,11 +1,8 @@
package org.moire.ultrasonic.di package org.moire.ultrasonic.di
import android.content.Context import org.koin.dsl.module.module
import org.koin.dsl.module.applicationContext
import org.moire.ultrasonic.featureflags.FeatureStorage import org.moire.ultrasonic.featureflags.FeatureStorage
fun featureFlagsModule( val featureFlagsModule = module {
context: Context factory { FeatureStorage(getProperty(DiProperties.APP_CONTEXT)) }
) = applicationContext {
factory { FeatureStorage(context) }
} }

View File

@ -1,10 +1,9 @@
@file:JvmName("MusicServiceModule") @file:JvmName("MusicServiceModule")
package org.moire.ultrasonic.di package org.moire.ultrasonic.di
import android.content.Context
import android.content.SharedPreferences import android.content.SharedPreferences
import android.util.Log import android.util.Log
import org.koin.dsl.module.applicationContext import org.koin.dsl.module.module
import org.moire.ultrasonic.BuildConfig import org.moire.ultrasonic.BuildConfig
import org.moire.ultrasonic.api.subsonic.SubsonicAPIClient import org.moire.ultrasonic.api.subsonic.SubsonicAPIClient
import org.moire.ultrasonic.api.subsonic.SubsonicAPIVersions import org.moire.ultrasonic.api.subsonic.SubsonicAPIVersions
@ -26,40 +25,38 @@ private const val DEFAULT_SERVER_INSTANCE = 1
private const val UNKNOWN_SERVER_URL = "not-exists" private const val UNKNOWN_SERVER_URL = "not-exists"
private const val LOG_TAG = "MusicServiceModule" private const val LOG_TAG = "MusicServiceModule"
fun musicServiceModule( val musicServiceModule = module(MUSIC_SERVICE_CONTEXT) {
sp: SharedPreferences,
context: Context
) = applicationContext {
context(MUSIC_SERVICE_CONTEXT) {
subsonicApiModule() subsonicApiModule()
bean(name = "ServerInstance") { single(name = "ServerInstance") {
return@bean sp.getInt( return@single get<SharedPreferences>(SP_NAME).getInt(
Constants.PREFERENCES_KEY_SERVER_INSTANCE, Constants.PREFERENCES_KEY_SERVER_INSTANCE,
DEFAULT_SERVER_INSTANCE DEFAULT_SERVER_INSTANCE
) )
} }
bean(name = "ServerID") { single(name = "ServerID") {
val serverInstance = get<Int>(name = "ServerInstance") val serverInstance = get<Int>(name = "ServerInstance")
val sp: SharedPreferences = get(SP_NAME)
val serverUrl = sp.getString( val serverUrl = sp.getString(
Constants.PREFERENCES_KEY_SERVER_URL + serverInstance, Constants.PREFERENCES_KEY_SERVER_URL + serverInstance,
null null
) )
return@bean if (serverUrl == null) { return@single if (serverUrl == null) {
UNKNOWN_SERVER_URL UNKNOWN_SERVER_URL
} else { } else {
abs("$serverUrl$serverInstance".hashCode()).toString() abs("$serverUrl$serverInstance".hashCode()).toString()
} }
} }
bean { single {
val serverId = get<String>(name = "ServerID") val serverId = get<String>(name = "ServerID")
return@bean PermanentFileStorage(get(), serverId, BuildConfig.DEBUG) return@single PermanentFileStorage(get(), serverId, BuildConfig.DEBUG)
} }
bean { single {
val instance = get<Int>(name = "ServerInstance") val instance = get<Int>(name = "ServerInstance")
val sp: SharedPreferences = get(SP_NAME)
val serverUrl = sp.getString(Constants.PREFERENCES_KEY_SERVER_URL + instance, null) val serverUrl = sp.getString(Constants.PREFERENCES_KEY_SERVER_URL + instance, null)
val username = sp.getString(Constants.PREFERENCES_KEY_USERNAME + instance, null) val username = sp.getString(Constants.PREFERENCES_KEY_USERNAME + instance, null)
val password = sp.getString(Constants.PREFERENCES_KEY_PASSWORD + instance, null) val password = sp.getString(Constants.PREFERENCES_KEY_PASSWORD + instance, null)
@ -77,7 +74,7 @@ fun musicServiceModule(
password == null password == null
) { ) {
Log.i(LOG_TAG, "Server credentials is not available") Log.i(LOG_TAG, "Server credentials is not available")
return@bean SubsonicClientConfiguration( return@single SubsonicClientConfiguration(
baseUrl = "http://localhost", baseUrl = "http://localhost",
username = "", username = "",
password = "", password = "",
@ -90,7 +87,7 @@ fun musicServiceModule(
debug = BuildConfig.DEBUG debug = BuildConfig.DEBUG
) )
} else { } else {
return@bean SubsonicClientConfiguration( return@single SubsonicClientConfiguration(
baseUrl = serverUrl, baseUrl = serverUrl,
username = username, username = username,
password = password, password = password,
@ -105,16 +102,15 @@ fun musicServiceModule(
} }
} }
bean { return@bean SubsonicAPIClient(get()) } single { SubsonicAPIClient(get()) }
bean<MusicService>(name = ONLINE_MUSIC_SERVICE) { single<MusicService>(name = ONLINE_MUSIC_SERVICE) {
return@bean CachedMusicService(RESTMusicService(get(), get())) CachedMusicService(RESTMusicService(get(), get()))
} }
bean<MusicService>(name = OFFLINE_MUSIC_SERVICE) { single<MusicService>(name = OFFLINE_MUSIC_SERVICE) {
return@bean OfflineMusicService(get(), get()) OfflineMusicService(get(), get())
} }
bean { return@bean SubsonicImageLoader(context, get()) } single { SubsonicImageLoader(getProperty(DiProperties.APP_CONTEXT), get()) }
} }
}

View File

@ -21,7 +21,7 @@ package org.moire.ultrasonic.service
import android.content.Context import android.content.Context
import org.koin.standalone.KoinComponent import org.koin.standalone.KoinComponent
import org.koin.standalone.get import org.koin.standalone.get
import org.koin.standalone.releaseContext import org.koin.standalone.release
import org.moire.ultrasonic.cache.Directories import org.moire.ultrasonic.cache.Directories
import org.moire.ultrasonic.di.MUSIC_SERVICE_CONTEXT import org.moire.ultrasonic.di.MUSIC_SERVICE_CONTEXT
import org.moire.ultrasonic.di.OFFLINE_MUSIC_SERVICE import org.moire.ultrasonic.di.OFFLINE_MUSIC_SERVICE
@ -45,7 +45,7 @@ object MusicServiceFactory : KoinComponent {
*/ */
@JvmStatic @JvmStatic
fun resetMusicService() { fun resetMusicService() {
releaseContext(MUSIC_SERVICE_CONTEXT) release(MUSIC_SERVICE_CONTEXT)
} }
@JvmStatic @JvmStatic