parent
e18f992930
commit
4d126dc274
@ -1,4 +1,4 @@ |
||||
package com.bennyhuo.kotlin.coroutines.android.autodisposable |
||||
package com.android.base.utils.coroutines |
||||
|
||||
import android.os.Build |
||||
import android.view.View |
@ -1,4 +1,4 @@ |
||||
package com.bennyhuo.kotlin.coroutines.android.autodisposable |
||||
package com.android.base.utils.coroutines |
||||
|
||||
import android.view.View |
||||
import kotlinx.coroutines.* |
@ -1,22 +0,0 @@ |
||||
*.iml |
||||
.gradle |
||||
/local.properties |
||||
/.idea |
||||
.DS_Store |
||||
/build |
||||
/captures |
||||
.externalNativeBuild |
||||
*.iml |
||||
.idea/ |
||||
.gradle |
||||
/local.properties |
||||
.DS_Store |
||||
/build |
||||
/captures |
||||
*.apk |
||||
*.ap_ |
||||
*.dex |
||||
*.class |
||||
bin/ |
||||
gen/ |
||||
local.properties |
@ -1,3 +0,0 @@ |
||||
# Explanation |
||||
|
||||
modifying from [kotlin-coroutines-android](https://github.com/enbandari/kotlin-coroutines-android) to support AndroidX. |
@ -1,41 +0,0 @@ |
||||
apply plugin: 'com.android.library' |
||||
apply plugin: 'kotlin-android' |
||||
|
||||
android { |
||||
compileSdkVersion rootProject.compileSdkVersion |
||||
buildToolsVersion rootProject.buildToolsVersion |
||||
|
||||
defaultConfig { |
||||
minSdkVersion rootProject.minSdkVersion |
||||
targetSdkVersion rootProject.targetSdkVersion |
||||
versionCode 1 |
||||
versionName "1.0" |
||||
} |
||||
|
||||
kotlinOptions { |
||||
jvmTarget = "1.8" |
||||
} |
||||
|
||||
buildTypes { |
||||
release { |
||||
minifyEnabled false |
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' |
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
dependencies { |
||||
implementation fileTree(dir: 'libs', include: ['*.jar']) |
||||
|
||||
//Kotlin |
||||
api kotlinLibraries.kotlinStdlib |
||||
api kotlinLibraries.kotlinReflect |
||||
api kotlinLibraries.kotlinCoroutines |
||||
api kotlinLibraries.kotlinAndroidCoroutines |
||||
|
||||
//AndroidX |
||||
compileOnly androidLibraries.appcompat |
||||
compileOnly androidLibraries.recyclerView |
||||
compileOnly androidLibraries.material |
||||
} |
@ -1,21 +0,0 @@ |
||||
# Add project specific ProGuard rules here. |
||||
# You can control the set of applied configuration files using the |
||||
# proguardFiles setting in build.gradle. |
||||
# |
||||
# For more details, see |
||||
# http://developer.android.com/guide/developing/tools/proguard.html |
||||
|
||||
# If your project uses WebView with JS, uncomment the following |
||||
# and specify the fully qualified class name to the JavaScript interface |
||||
# class: |
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview { |
||||
# public *; |
||||
#} |
||||
|
||||
# Uncomment this to preserve the line number information for |
||||
# debugging stack traces. |
||||
#-keepattributes SourceFile,LineNumberTable |
||||
|
||||
# If you keep the line number information, uncomment this to |
||||
# hide the original source file name. |
||||
#-renamesourcefileattribute SourceFile |
@ -1,2 +0,0 @@ |
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" |
||||
package="com.bennyhuo.kotlin.coroutines.android.mainscope"/> |
@ -1,50 +0,0 @@ |
||||
package com.bennyhuo.kotlin.coroutines.android.mainscope |
||||
|
||||
import android.app.Application |
||||
import com.bennyhuo.kotlin.coroutines.android.mainscope.internal.ActivityLifecycleCallbackImpl |
||||
import com.bennyhuo.kotlin.coroutines.android.mainscope.job.EmptyInterceptor |
||||
import com.bennyhuo.kotlin.coroutines.android.mainscope.job.EmptyJob |
||||
import com.bennyhuo.kotlin.coroutines.android.mainscope.job.ImmutableCoroutineContext |
||||
import com.bennyhuo.kotlin.coroutines.android.mainscope.utils.Logcat |
||||
import kotlinx.coroutines.CoroutineScope |
||||
import kotlinx.coroutines.Dispatchers |
||||
import kotlinx.coroutines.SupervisorJob |
||||
import kotlin.coroutines.CoroutineContext |
||||
|
||||
interface MainScope : CoroutineScope { |
||||
|
||||
companion object { |
||||
internal var isSetUp = false |
||||
internal var isDebug = false |
||||
|
||||
val isFragmentSupported by lazy { |
||||
try { |
||||
Class.forName("androidx.fragment.app.FragmentManager\$FragmentLifecycleCallbacks") |
||||
Logcat.debug("Fragment enabled.") |
||||
true |
||||
} catch (e: ClassNotFoundException) { |
||||
Logcat.debug("Fragment disabled.") |
||||
Logcat.error(e) |
||||
false |
||||
} |
||||
} |
||||
|
||||
fun setUp(application: Application): Companion { |
||||
application.registerActivityLifecycleCallbacks(ActivityLifecycleCallbackImpl) |
||||
isSetUp = true |
||||
return this |
||||
} |
||||
|
||||
fun enableDebug() { |
||||
isDebug = true |
||||
} |
||||
} |
||||
} |
||||
|
||||
internal class MainScopeImpl : MainScope { |
||||
override val coroutineContext = SupervisorJob() + Dispatchers.Main |
||||
} |
||||
|
||||
internal object EmptyScope : MainScope { |
||||
override val coroutineContext: CoroutineContext = ImmutableCoroutineContext(EmptyJob() + EmptyInterceptor) |
||||
} |
@ -1,5 +0,0 @@ |
||||
package com.bennyhuo.kotlin.coroutines.android.mainscope.exception |
||||
|
||||
class UnsupportedTypeException(type: Class<*>, vararg supportedTypes: String) : Exception("Unsupported type: $type. ${supportedTypes.joinToString()} ${if (supportedTypes.size == 1) "is" else "are"} needed.") |
||||
|
||||
class UnsupportedVersionException(library: String, version: String) : Exception("Unsupported version: $version of $library") |
@ -1,46 +0,0 @@ |
||||
package com.bennyhuo.kotlin.coroutines.android.mainscope.internal |
||||
|
||||
import android.app.Activity |
||||
import android.app.Application |
||||
import android.os.Bundle |
||||
import androidx.fragment.app.FragmentActivity |
||||
import com.bennyhuo.kotlin.coroutines.android.mainscope.MainScope |
||||
import com.bennyhuo.kotlin.coroutines.android.mainscope.scope.MainScoped |
||||
import com.bennyhuo.kotlin.coroutines.android.mainscope.scope.onMainScopeCreate |
||||
import com.bennyhuo.kotlin.coroutines.android.mainscope.scope.onMainScopeDestroy |
||||
import com.bennyhuo.kotlin.coroutines.android.mainscope.utils.Logcat |
||||
|
||||
internal object ActivityLifecycleCallbackImpl : Application.ActivityLifecycleCallbacks { |
||||
|
||||
override fun onActivityPaused(activity: Activity) {} |
||||
|
||||
override fun onActivityResumed(activity: Activity) {} |
||||
|
||||
override fun onActivityStarted(activity: Activity) {} |
||||
|
||||
override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle?) {} |
||||
|
||||
override fun onActivityStopped(activity: Activity) {} |
||||
|
||||
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) { |
||||
(activity as? MainScoped)?.onMainScopeCreate() |
||||
if (MainScope.isFragmentSupported) { |
||||
(activity as? FragmentActivity)?.supportFragmentManager?.registerFragmentLifecycleCallbacks(FragmentLifecycleCallbackImpl, true) |
||||
} |
||||
} |
||||
|
||||
override fun onActivityDestroyed(activity: Activity) { |
||||
(activity as? MainScoped)?.onMainScopeDestroy() |
||||
if (MainScope.isFragmentSupported) { |
||||
Logcat.debug("onActivityDestroyed") |
||||
(activity as? FragmentActivity)?.supportFragmentManager?.let { fragmentManager -> |
||||
fragmentManager.unregisterFragmentLifecycleCallbacks(FragmentLifecycleCallbackImpl) |
||||
//Fragments may not be destroyed, so cancel scope right now. |
||||
fragmentManager.fragments.forEach { fragment -> |
||||
(fragment as? MainScoped)?.onMainScopeDestroy() |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
} |
@ -1,24 +0,0 @@ |
||||
package com.bennyhuo.kotlin.coroutines.android.mainscope.internal |
||||
|
||||
import android.os.Bundle |
||||
import androidx.fragment.app.Fragment |
||||
import androidx.fragment.app.FragmentManager |
||||
import com.bennyhuo.kotlin.coroutines.android.mainscope.scope.MainScoped |
||||
import com.bennyhuo.kotlin.coroutines.android.mainscope.scope.onMainScopeCreate |
||||
import com.bennyhuo.kotlin.coroutines.android.mainscope.scope.onMainScopeDestroy |
||||
import com.bennyhuo.kotlin.coroutines.android.mainscope.utils.Logcat |
||||
|
||||
internal object FragmentLifecycleCallbackImpl: FragmentManager.FragmentLifecycleCallbacks() { |
||||
|
||||
override fun onFragmentCreated(fm: FragmentManager, f: Fragment, savedInstanceState: Bundle?) { |
||||
super.onFragmentCreated(fm, f, savedInstanceState) |
||||
(f as? MainScoped)?.onMainScopeCreate() |
||||
} |
||||
|
||||
override fun onFragmentViewDestroyed(fm: FragmentManager, f: Fragment) { |
||||
super.onFragmentViewDestroyed(fm, f) |
||||
Logcat.debug("onFragmentViewDestroyed") |
||||
(f as? MainScoped)?.onMainScopeDestroy() |
||||
} |
||||
|
||||
} |
@ -1,21 +0,0 @@ |
||||
package com.bennyhuo.kotlin.coroutines.android.mainscope.job |
||||
|
||||
import com.bennyhuo.kotlin.coroutines.android.mainscope.MainScope |
||||
import kotlinx.coroutines.CoroutineStart |
||||
import kotlinx.coroutines.Job |
||||
import kotlinx.coroutines.newCoroutineContext |
||||
import kotlin.coroutines.CoroutineContext |
||||
import kotlin.coroutines.EmptyCoroutineContext |
||||
import kotlinx.coroutines.launch as launchInternal |
||||
|
||||
|
||||
internal fun MainScope.launch( |
||||
context: CoroutineContext = EmptyCoroutineContext, |
||||
start: CoroutineStart = CoroutineStart.DEFAULT, |
||||
block: suspend MainScope.() -> Unit |
||||
): Job { |
||||
val newContext = newCoroutineContext(context) |
||||
val coroutine = StandaloneCoroutineCompat(newContext, true) |
||||
coroutine.start(start, coroutine, block) |
||||
return coroutine |
||||
} |
@ -1,7 +0,0 @@ |
||||
package com.bennyhuo.kotlin.coroutines.android.mainscope.job |
||||
|
||||
import kotlinx.coroutines.DisposableHandle |
||||
|
||||
object EmptyDisposableHandle: DisposableHandle { |
||||
override fun dispose() = Unit |
||||
} |
@ -1,20 +0,0 @@ |
||||
package com.bennyhuo.kotlin.coroutines.android.mainscope.job |
||||
|
||||
import com.bennyhuo.kotlin.coroutines.android.mainscope.utils.Logcat |
||||
import kotlin.coroutines.* |
||||
|
||||
internal object EmptyInterceptor: ContinuationInterceptor, AbstractCoroutineContextElement(ContinuationInterceptor) { |
||||
|
||||
override fun <T> interceptContinuation(continuation: Continuation<T>): Continuation<T> { |
||||
return EmptyContinuation as Continuation<T> |
||||
} |
||||
|
||||
private object EmptyContinuation: Continuation<Any>{ |
||||
override val context: CoroutineContext = EmptyCoroutineContext |
||||
|
||||
override fun resumeWith(result: Result<Any>) { |
||||
Logcat.warn("Intercepted coroutine. won't resume.") |
||||
} |
||||
} |
||||
|
||||
} |
@ -1,63 +0,0 @@ |
||||
package com.bennyhuo.kotlin.coroutines.android.mainscope.job |
||||
|
||||
import kotlinx.coroutines.CancellationException |
||||
import kotlinx.coroutines.CompletionHandler |
||||
import kotlinx.coroutines.InternalCoroutinesApi |
||||
import kotlinx.coroutines.Job |
||||
import kotlinx.coroutines.selects.SelectClause0 |
||||
import kotlinx.coroutines.selects.SelectInstance |
||||
import kotlin.coroutines.CoroutineContext |
||||
import kotlin.coroutines.CoroutineContext.Element |
||||
import kotlin.coroutines.CoroutineContext.Key |
||||
import kotlin.coroutines.EmptyCoroutineContext |
||||
|
||||
internal class EmptyJob : JobCompat(), SelectClause0 { |
||||
|
||||
private val cancellationException = CancellationException("EmptyScope") |
||||
|
||||
override val children: Sequence<Job> = emptySequence() |
||||
|
||||
override val isActive: Boolean = false |
||||
|
||||
override val isCancelled: Boolean = true |
||||
|
||||
override val isCompleted: Boolean = true |
||||
|
||||
override val key: Key<*> = Job |
||||
|
||||
override val onJoin: SelectClause0 = this |
||||
|
||||
@InternalCoroutinesApi |
||||
override fun <R> registerSelectClause0(select: SelectInstance<R>, block: suspend () -> R) = Unit |
||||
|
||||
override fun cancel(cause: Throwable?) = false |
||||
|
||||
override fun cancel(cause: CancellationException?) = Unit |
||||
|
||||
@InternalCoroutinesApi |
||||
override fun getCancellationException() = cancellationException |
||||
|
||||
@InternalCoroutinesApi |
||||
override fun invokeOnCompletion(onCancelling: Boolean, invokeImmediately: Boolean, handler: CompletionHandler) = EmptyDisposableHandle.also { handler.invoke(cancellationException) } |
||||
|
||||
override fun invokeOnCompletion(handler: CompletionHandler) = EmptyDisposableHandle.also { handler.invoke(cancellationException) } |
||||
|
||||
override suspend fun join() = Unit |
||||
|
||||
override fun start() = false |
||||
|
||||
override fun plus(other: Job): Job = this |
||||
|
||||
override fun cancel() = Unit |
||||
|
||||
//region solutions for AbstractMethodError. |
||||
override operator fun <E : Element> get(key: Key<E>): E? = |
||||
if (this.key == key) this as E else null |
||||
|
||||
override fun <R> fold(initial: R, operation: (R, Element) -> R): R = operation(initial, this) |
||||
|
||||
override fun minusKey(key: Key<*>): CoroutineContext = |
||||
if (this.key == key) EmptyCoroutineContext else this |
||||
//endregion |
||||
|
||||
} |
@ -1,15 +0,0 @@ |
||||
package com.bennyhuo.kotlin.coroutines.android.mainscope.job |
||||
|
||||
import kotlin.coroutines.CoroutineContext |
||||
import kotlin.coroutines.CoroutineContext.Element |
||||
import kotlin.coroutines.CoroutineContext.Key |
||||
|
||||
class ImmutableCoroutineContext(private val coroutineContext: CoroutineContext): CoroutineContext { |
||||
override fun <R> fold(initial: R, operation: (R, Element) -> R): R = coroutineContext.fold(initial, operation) |
||||
|
||||
override fun <E : Element> get(key: Key<E>) = coroutineContext[key] |
||||
|
||||
override fun minusKey(key: Key<*>) = this |
||||
|
||||
override fun plus(context: CoroutineContext) = this |
||||
} |
@ -1,37 +0,0 @@ |
||||
package com.bennyhuo.kotlin.coroutines.android.mainscope.job; |
||||
|
||||
import org.jetbrains.annotations.NotNull; |
||||
|
||||
import kotlin.coroutines.CoroutineContext; |
||||
import kotlinx.coroutines.ChildHandle; |
||||
import kotlinx.coroutines.ChildJob; |
||||
import kotlinx.coroutines.Job; |
||||
|
||||
abstract class JobCompat implements Job { |
||||
@NotNull |
||||
@Override |
||||
public final ChildHandle attachChild(@NotNull ChildJob childJob) { |
||||
//Parent is already cancelled. So cancel child directly.
|
||||
childJob.cancel(getCancellationException()); |
||||
return EmptyChildHandle.instance; |
||||
} |
||||
|
||||
private static class EmptyChildHandle implements ChildHandle { |
||||
private static final EmptyChildHandle instance = new EmptyChildHandle(); |
||||
|
||||
@Override |
||||
public boolean childCancelled(@NotNull Throwable throwable) { |
||||
return true; |
||||
} |
||||
|
||||
@Override |
||||
public void dispose() { } |
||||
} |
||||
|
||||
//solutions for AbstractMethodError.
|
||||
@NotNull |
||||
@Override |
||||
public final CoroutineContext plus(@NotNull CoroutineContext coroutineContext) { |
||||
return CoroutineContext.DefaultImpls.plus(this, coroutineContext); |
||||
} |
||||
} |
@ -1,22 +0,0 @@ |
||||
package com.bennyhuo.kotlin.coroutines.android.mainscope.job; |
||||
|
||||
import com.bennyhuo.kotlin.coroutines.android.mainscope.MainScope; |
||||
|
||||
import org.jetbrains.annotations.NotNull; |
||||
|
||||
import kotlin.Unit; |
||||
import kotlin.coroutines.CoroutineContext; |
||||
import kotlinx.coroutines.AbstractCoroutine; |
||||
import kotlinx.coroutines.CoroutineExceptionHandlerKt; |
||||
|
||||
class StandaloneCoroutineCompat extends AbstractCoroutine<Unit> implements MainScope { |
||||
public StandaloneCoroutineCompat(@NotNull CoroutineContext parentContext, boolean active) { |
||||
super(parentContext, active); |
||||
} |
||||
|
||||
@Override |
||||
protected boolean handleJobException(@NotNull Throwable exception) { |
||||
CoroutineExceptionHandlerKt.handleCoroutineException(getContext(), exception); |
||||
return true; |
||||
} |
||||
} |
@ -1,195 +0,0 @@ |
||||
package com.bennyhuo.kotlin.coroutines.android.mainscope.scope |
||||
|
||||
import androidx.appcompat.widget.* |
||||
import com.bennyhuo.kotlin.coroutines.android.mainscope.MainScope |
||||
import com.bennyhuo.kotlin.coroutines.android.mainscope.job.launch |
||||
|
||||
interface AppCompatScoped : BasicScoped { |
||||
|
||||
fun ActionMenuView.onMenuItemClick( |
||||
returnValue: Boolean = false, |
||||
handler: suspend MainScope.(item: android.view.MenuItem?) -> Unit |
||||
) { |
||||
setOnMenuItemClickListener { item -> |
||||
mainScope.launch { |
||||
handler(item) |
||||
} |
||||
returnValue |
||||
} |
||||
} |
||||
|
||||
fun ActivityChooserView.onDismiss( |
||||
handler: suspend MainScope.() -> Unit |
||||
) { |
||||
setOnDismissListener { -> |
||||
mainScope.launch(block = handler) |
||||
} |
||||
} |
||||
|
||||
fun FitWindowsFrameLayout.onFitSystemWindows( |
||||
handler: suspend MainScope.(insets: android.graphics.Rect?) -> Unit |
||||
) { |
||||
setOnFitSystemWindowsListener { insets -> |
||||
mainScope.launch { |
||||
handler(insets) |
||||
} |
||||
} |
||||
} |
||||
|
||||
fun SearchView.onClose( |
||||
returnValue: Boolean = false, |
||||
handler: suspend MainScope.() -> Unit |
||||
) { |
||||
setOnCloseListener { -> |
||||
mainScope.launch(block = handler) |
||||
returnValue |
||||
} |
||||
} |
||||
|
||||
fun SearchView.onQueryTextFocusChange( |
||||
handler: suspend MainScope.(v: android.view.View, hasFocus: Boolean) -> Unit |
||||
) { |
||||
setOnQueryTextFocusChangeListener { v, hasFocus -> |
||||
mainScope.launch { |
||||
handler(v, hasFocus) |
||||
} |
||||
} |
||||
} |
||||
|
||||
fun SearchView.onQueryTextListener( |
||||
init: __SearchView_OnQueryTextListener.() -> Unit |
||||
) { |
||||
val listener = __SearchView_OnQueryTextListener(mainScope) |
||||
listener.init() |
||||
setOnQueryTextListener(listener) |
||||
} |
||||
|
||||
class __SearchView_OnQueryTextListener(private val mainScope: MainScope) : SearchView.OnQueryTextListener { |
||||
|
||||
private var _onQueryTextSubmit: (suspend MainScope.(String?) -> Boolean)? = null |
||||
private var _onQueryTextSubmit_returnValue: Boolean = false |
||||
|
||||
override fun onQueryTextSubmit(query: String?): Boolean { |
||||
val returnValue = _onQueryTextSubmit_returnValue |
||||
val handler = _onQueryTextSubmit ?: return returnValue |
||||
mainScope.launch { |
||||
handler(query) |
||||
} |
||||
return returnValue |
||||
} |
||||
|
||||
fun onQueryTextSubmit( |
||||
returnValue: Boolean = false, |
||||
listener: suspend MainScope.(String?) -> Boolean |
||||
) { |
||||
_onQueryTextSubmit = listener |
||||
_onQueryTextSubmit_returnValue = returnValue |
||||
} |
||||
|
||||
private var _onQueryTextChange: (suspend MainScope.(String?) -> Boolean)? = null |
||||
private var _onQueryTextChange_returnValue: Boolean = false |
||||
|
||||
override fun onQueryTextChange(newText: String?): Boolean { |
||||
val returnValue = _onQueryTextChange_returnValue |
||||
val handler = _onQueryTextChange ?: return returnValue |
||||
mainScope.launch { |
||||
handler(newText) |
||||
} |
||||
return returnValue |
||||
} |
||||
|
||||
fun onQueryTextChange( |
||||
returnValue: Boolean = false, |
||||
listener: suspend MainScope.(String?) -> Boolean |
||||
) { |
||||
_onQueryTextChange = listener |
||||
_onQueryTextChange_returnValue = returnValue |
||||
} |
||||
|
||||
} |
||||
|
||||
fun SearchView.onSearchClick( |
||||
handler: suspend MainScope.(v: android.view.View?) -> Unit |
||||
) { |
||||
setOnSearchClickListener { v -> |
||||
mainScope.launch { |
||||
handler(v) |
||||
} |
||||
} |
||||
} |
||||
|
||||
fun SearchView.onSuggestionListener( |
||||
init: __SearchView_OnSuggestionListener.() -> Unit |
||||
) { |
||||
val listener = __SearchView_OnSuggestionListener(mainScope) |
||||
listener.init() |
||||
setOnSuggestionListener(listener) |
||||
} |
||||
|
||||
class __SearchView_OnSuggestionListener(private val mainScope: MainScope) : SearchView.OnSuggestionListener { |
||||
|
||||
private var _onSuggestionSelect: (suspend MainScope.(Int) -> Boolean)? = null |
||||
private var _onSuggestionSelect_returnValue: Boolean = false |
||||
|
||||
override fun onSuggestionSelect(position: Int): Boolean { |
||||
val returnValue = _onSuggestionSelect_returnValue |
||||
val handler = _onSuggestionSelect ?: return returnValue |
||||
mainScope.launch { |
||||
handler(position) |
||||
} |
||||
return returnValue |
||||
} |
||||
|
||||
fun onSuggestionSelect( |
||||
returnValue: Boolean = false, |
||||
listener: suspend MainScope.(Int) -> Boolean |
||||
) { |
||||
_onSuggestionSelect = listener |
||||
_onSuggestionSelect_returnValue = returnValue |
||||
} |
||||
|
||||
private var _onSuggestionClick: (suspend MainScope.(Int) -> Boolean)? = null |
||||
private var _onSuggestionClick_returnValue: Boolean = false |
||||
|
||||
override fun onSuggestionClick(position: Int): Boolean { |
||||
val returnValue = _onSuggestionClick_returnValue |
||||
val handler = _onSuggestionClick ?: return returnValue |
||||
mainScope.launch { |
||||
handler(position) |
||||
} |
||||
return returnValue |
||||
} |
||||
|
||||
fun onSuggestionClick( |
||||
returnValue: Boolean = false, |
||||
listener: suspend MainScope.(Int) -> Boolean |
||||
) { |
||||
_onSuggestionClick = listener |
||||
_onSuggestionClick_returnValue = returnValue |
||||
} |
||||
|
||||
} |
||||
|
||||
fun Toolbar.onMenuItemClick( |
||||
returnValue: Boolean = false, |
||||
handler: suspend MainScope.(item: android.view.MenuItem?) -> Unit |
||||
) { |
||||
setOnMenuItemClickListener { item -> |
||||
mainScope.launch { |
||||
handler(item) |
||||
} |
||||
returnValue |
||||
} |
||||
} |
||||
|
||||
fun ViewStubCompat.onInflate( |
||||
handler: suspend MainScope.(stub: ViewStubCompat?, inflated: android.view.View?) -> Unit |
||||
) { |
||||
setOnInflateListener { stub, inflated -> |
||||
mainScope.launch { |
||||
handler(stub, inflated) |
||||
} |
||||
} |
||||
} |
||||
|
||||
} |
File diff suppressed because it is too large
Load Diff
@ -1,369 +0,0 @@ |
||||
package com.bennyhuo.kotlin.coroutines.android.mainscope.scope |
||||
|
||||
import com.bennyhuo.kotlin.coroutines.android.mainscope.MainScope |
||||
import com.bennyhuo.kotlin.coroutines.android.mainscope.job.launch |
||||
import com.google.android.material.appbar.AppBarLayout |
||||
import com.google.android.material.bottomnavigation.BottomNavigationView |
||||
import com.google.android.material.chip.ChipGroup |
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton |
||||
import com.google.android.material.tabs.TabLayout |
||||
|
||||
interface DesignScoped : BasicScoped { |
||||
|
||||
fun AppBarLayout.onOffsetChanged( |
||||
handler: suspend MainScope.(appBarLayout: AppBarLayout?, verticalOffset: Int) -> Unit |
||||
) { |
||||
addOnOffsetChangedListener(AppBarLayout.OnOffsetChangedListener { appBarLayout, verticalOffset -> |
||||
mainScope.launch { |
||||
handler(appBarLayout, verticalOffset) |
||||
} |
||||
}) |
||||
} |
||||
|
||||
fun <T : TabLayout.Tab> TabLayout.onTabSelectedListener( |
||||
init: __onTabSelected_TabLayout_BaseOnTabSelectedListener<T>.() -> Unit |
||||
) { |
||||
val listener = __onTabSelected_TabLayout_BaseOnTabSelectedListener<T>(mainScope) |
||||
listener.init() |
||||
addOnTabSelectedListener(listener) |
||||
} |
||||
|
||||
class __onTabSelected_TabLayout_BaseOnTabSelectedListener<T : TabLayout.Tab>(private val mainScope: MainScope) : TabLayout.BaseOnTabSelectedListener<T> { |
||||
|
||||
private var _onTabSelectedWithP0: (suspend MainScope.(T?) -> Unit)? = null |
||||
|
||||
override fun onTabSelected(p0: T?) { |
||||
val handler = _onTabSelectedWithP0 ?: return |
||||
mainScope.launch { |
||||
handler(p0) |
||||
} |
||||
} |
||||
|
||||
fun onTabSelected( |
||||
listener: suspend MainScope.(T?) -> Unit |
||||
) { |
||||
_onTabSelectedWithP0 = listener |
||||
} |
||||
|
||||
private var _onTabUnselectedWithP0: (suspend MainScope.(T?) -> Unit)? = null |
||||
|
||||
override fun onTabUnselected(p0: T?) { |
||||
val handler = _onTabUnselectedWithP0 ?: return |
||||
mainScope.launch { |
||||
handler(p0) |
||||
} |
||||
} |
||||
|
||||
fun onTabUnselected( |
||||
listener: suspend MainScope.(T?) -> Unit |
||||
) { |
||||
_onTabUnselectedWithP0 = listener |
||||
} |
||||
|
||||
private var _onTabReselectedWithP0: (suspend MainScope.(T?) -> Unit)? = null |
||||
|
||||
override fun onTabReselected(p0: T?) { |
||||
val handler = _onTabReselectedWithP0 ?: return |
||||
mainScope.launch { |
||||
handler(p0) |
||||
} |
||||
} |
||||
|
||||
fun onTabReselected( |
||||
listener: suspend MainScope.(T?) -> Unit |
||||
) { |
||||
_onTabReselectedWithP0 = listener |
||||
} |
||||
|
||||
} |
||||
|
||||
fun FloatingActionButton.onShowAnimationListener( |
||||
init: __onShowAnimation_Animator_AnimatorListener.() -> Unit |
||||
) { |
||||
val listener = __onShowAnimation_Animator_AnimatorListener(mainScope) |
||||
listener.init() |
||||
addOnShowAnimationListener(listener) |
||||
} |
||||
|
||||
class __onShowAnimation_Animator_AnimatorListener(private val mainScope: MainScope) : android.animation.Animator.AnimatorListener { |
||||
|
||||
private var _onAnimationStartWithAnimationAndIsReverse: (suspend MainScope.(android.animation.Animator?, Boolean) -> Unit)? = null |
||||
|
||||
override fun onAnimationStart(animation: android.animation.Animator?, isReverse: Boolean) { |
||||
val handler = _onAnimationStartWithAnimationAndIsReverse ?: return |
||||
mainScope.launch { |
||||
handler(animation, isReverse) |
||||
} |
||||
} |
||||
|
||||
fun onAnimationStart( |
||||
listener: suspend MainScope.(android.animation.Animator?, Boolean) -> Unit |
||||
) { |
||||
_onAnimationStartWithAnimationAndIsReverse = listener |
||||
} |
||||
|
||||
private var _onAnimationEndWithAnimationAndIsReverse: (suspend MainScope.(android.animation.Animator?, Boolean) -> Unit)? = null |
||||
|
||||
override fun onAnimationEnd(animation: android.animation.Animator?, isReverse: Boolean) { |
||||
val handler = _onAnimationEndWithAnimationAndIsReverse ?: return |
||||
mainScope.launch { |
||||
handler(animation, isReverse) |
||||
} |
||||
} |
||||
|
||||
fun onAnimationEnd( |
||||
listener: suspend MainScope.(android.animation.Animator?, Boolean) -> Unit |
||||
) { |
||||
_onAnimationEndWithAnimationAndIsReverse = listener |
||||
} |
||||
|
||||
private var _onAnimationStartWithAnimation: (suspend MainScope.(android.animation.Animator?) -> Unit)? = null |
||||
|
||||
|
||||
override fun onAnimationStart(animation: android.animation.Animator?) { |
||||
val handler = _onAnimationStartWithAnimation ?: return |
||||
mainScope.launch { |
||||
handler(animation) |
||||
} |
||||
} |
||||
|
||||
fun onAnimationStart( |
||||
listener: suspend MainScope.(android.animation.Animator?) -> Unit |
||||
) { |
||||
_onAnimationStartWithAnimation = listener |
||||
} |
||||
|
||||
private var _onAnimationEndWithAnimation: (suspend MainScope.(android.animation.Animator?) -> Unit)? = null |
||||
|
||||
|
||||
override fun onAnimationEnd(animation: android.animation.Animator?) { |
||||
val handler = _onAnimationEndWithAnimation ?: return |
||||
mainScope.launch { |
||||
handler(animation) |
||||
} |
||||
} |
||||
|
||||
fun onAnimationEnd( |
||||
listener: suspend MainScope.(android.animation.Animator?) -> Unit |
||||
) { |
||||
_onAnimationEndWithAnimation = listener |
||||
} |
||||
|
||||
private var _onAnimationCancelWithAnimation: (suspend MainScope.(android.animation.Animator?) -> Unit)? = null |
||||
|
||||
|
||||
override fun onAnimationCancel(animation: android.animation.Animator?) { |
||||
val handler = _onAnimationCancelWithAnimation ?: return |
||||
mainScope.launch { |
||||
handler(animation) |
||||
} |
||||
} |
||||
|
||||
fun onAnimationCancel( |
||||
listener: suspend MainScope.(android.animation.Animator?) -> Unit |
||||
) { |
||||
_onAnimationCancelWithAnimation = listener |
||||
} |
||||
|
||||
private var _onAnimationRepeatWithAnimation: (suspend MainScope.(android.animation.Animator?) -> Unit)? = null |
||||
|
||||
|
||||
override fun onAnimationRepeat(animation: android.animation.Animator?) { |
||||
val handler = _onAnimationRepeatWithAnimation ?: return |
||||
mainScope.launch { |
||||
handler(animation) |
||||
} |
||||
} |
||||
|
||||
fun onAnimationRepeat( |
||||
listener: suspend MainScope.(android.animation.Animator?) -> Unit |
||||
) { |
||||
_onAnimationRepeatWithAnimation = listener |
||||
} |
||||
|
||||
} |
||||
|
||||
fun FloatingActionButton.onHideAnimationListener( |
||||
init: __onHideAnimation_Animator_AnimatorListener.() -> Unit |
||||
) { |
||||
val listener = __onHideAnimation_Animator_AnimatorListener(mainScope) |
||||
listener.init() |
||||
addOnHideAnimationListener(listener) |
||||
} |
||||
|
||||
class __onHideAnimation_Animator_AnimatorListener(private val mainScope: MainScope) : android.animation.Animator.AnimatorListener { |
||||
|
||||
private var _onAnimationStartWithAnimationAndIsReverse: (suspend MainScope.(android.animation.Animator?, Boolean) -> Unit)? = null |
||||
|
||||
|
||||
override fun onAnimationStart(animation: android.animation.Animator?, isReverse: Boolean) { |
||||
val handler = _onAnimationStartWithAnimationAndIsReverse ?: return |
||||
mainScope.launch { |
||||
handler(animation, isReverse) |
||||
} |
||||
} |
||||
|
||||
fun onAnimationStart( |
||||
listener: suspend MainScope.(android.animation.Animator?, Boolean) -> Unit |
||||
) { |
||||
_onAnimationStartWithAnimationAndIsReverse = listener |
||||
} |
||||
|
||||
private var _onAnimationEndWithAnimationAndIsReverse: (suspend MainScope.(android.animation.Animator?, Boolean) -> Unit)? = null |
||||
|
||||
|
||||
override fun onAnimationEnd(animation: android.animation.Animator?, isReverse: Boolean) { |
||||
val handler = _onAnimationEndWithAnimationAndIsReverse ?: return |
||||
mainScope.launch { |
||||
handler(animation, isReverse) |
||||
} |
||||
} |
||||
|
||||
fun onAnimationEnd( |
||||
listener: suspend MainScope.(android.animation.Animator?, Boolean) -> Unit |
||||
) { |
||||
_onAnimationEndWithAnimationAndIsReverse = listener |
||||
} |
||||
|
||||
private var _onAnimationStartWithAnimation: (suspend MainScope.(android.animation.Animator?) -> Unit)? = null |
||||
|
||||
|
||||
override fun onAnimationStart(animation: android.animation.Animator?) { |
||||
val handler = _onAnimationStartWithAnimation ?: return |
||||
mainScope.launch { |
||||
handler(animation) |
||||
} |
||||
} |
||||
|
||||
fun onAnimationStart( |
||||
listener: suspend MainScope.(android.animation.Animator?) -> Unit |
||||
) { |
||||
_onAnimationStartWithAnimation = listener |
||||
} |
||||
|
||||
private var _onAnimationEndWithAnimation: (suspend MainScope.(android.animation.Animator?) -> Unit)? = null |
||||
|
||||
|
||||
override fun onAnimationEnd(animation: android.animation.Animator?) { |
||||
val handler = _onAnimationEndWithAnimation ?: return |
||||
mainScope.launch { |
||||
handler(animation) |
||||
} |
||||
} |
||||
|
||||
fun onAnimationEnd( |
||||
listener: suspend MainScope.(android.animation.Animator?) -> Unit |
||||
) { |
||||
_onAnimationEndWithAnimation = listener |
||||
} |
||||
|
||||
private var _onAnimationCancelWithAnimation: (suspend MainScope.(android.animation.Animator?) -> Unit)? = null |
||||
|
||||
|
||||
override fun onAnimationCancel(animation: android.animation.Animator?) { |
||||
val handler = _onAnimationCancelWithAnimation ?: return |
||||
mainScope.launch { |
||||
handler(animation) |
||||
} |
||||
} |
||||
|
||||
fun onAnimationCancel( |
||||
listener: suspend MainScope.(android.animation.Animator?) -> Unit |
||||
) { |
||||
_onAnimationCancelWithAnimation = listener |
||||
} |
||||
|
||||
private var _onAnimationRepeatWithAnimation: (suspend MainScope.(android.animation.Animator?) -> Unit)? = null |
||||
|
||||
|
||||
override fun onAnimationRepeat(animation: android.animation.Animator?) { |
||||
val handler = _onAnimationRepeatWithAnimation ?: return |
||||
mainScope.launch { |
||||
handler(animation) |
||||
} |
||||
} |
||||
|
||||
fun onAnimationRepeat( |
||||
listener: suspend MainScope.(android.animation.Animator?) -> Unit |
||||
) { |
||||
_onAnimationRepeatWithAnimation = listener |
||||
} |
||||
|
||||
} |
||||
|
||||
fun ChipGroup.onCheckedChange( |
||||
handler: suspend MainScope.(p0: ChipGroup?, p1: Int) -> Unit |
||||
) { |
||||
setOnCheckedChangeListener { p0, p1 -> |
||||
mainScope.launch { |
||||
handler(p0, p1) |
||||
} |
||||
} |
||||
} |
||||
|
||||
fun ChipGroup.onHierarchyChangeListener( |
||||
init: __onHierarchyChange_ViewGroup_OnHierarchyChangeListener.() -> Unit |
||||
) { |
||||
val listener = __onHierarchyChange_ViewGroup_OnHierarchyChangeListener(mainScope) |
||||
listener.init() |
||||
setOnHierarchyChangeListener(listener) |
||||
} |
||||
|
||||
class __onHierarchyChange_ViewGroup_OnHierarchyChangeListener(private val mainScope: MainScope) : android.view.ViewGroup.OnHierarchyChangeListener { |
||||
|
||||
private var _onChildViewAddedWithParentAndChild: (suspend MainScope.(android.view.View?, android.view.View?) -> Unit)? = null |
||||
|
||||
|
||||
override fun onChildViewAdded(parent: android.view.View?, child: android.view.View?) { |
||||
val handler = _onChildViewAddedWithParentAndChild ?: return |
||||
mainScope.launch { |
||||
handler(parent, child) |
||||
} |
||||
} |
||||
|
||||
fun onChildViewAdded( |
||||
listener: suspend MainScope.(android.view.View?, android.view.View?) -> Unit |
||||
) { |
||||
_onChildViewAddedWithParentAndChild = listener |
||||
} |
||||
|
||||
private var _onChildViewRemovedWithParentAndChild: (suspend MainScope.(android.view.View?, android.view.View?) -> Unit)? = null |
||||
|
||||
override fun onChildViewRemoved(parent: android.view.View?, child: android.view.View?) { |
||||
val handler = _onChildViewRemovedWithParentAndChild ?: return |
||||
mainScope.launch { |
||||
handler(parent, child) |
||||
} |
||||
} |
||||
|
||||
fun onChildViewRemoved( |
||||
listener: suspend MainScope.(android.view.View?, android.view.View?) -> Unit |
||||
) { |
||||
_onChildViewRemovedWithParentAndChild = listener |
||||
} |
||||
|
||||
} |
||||
|
||||
fun BottomNavigationView.onNavigationItemReselected( |
||||
handler: suspend MainScope.(item: android.view.MenuItem) -> Unit |
||||
) { |
||||
setOnNavigationItemReselectedListener { item -> |
||||
mainScope.launch { |
||||
handler(item) |
||||
} |
||||
} |
||||
} |
||||
|
||||
fun BottomNavigationView.onNavigationItemSelected( |
||||
returnValue: Boolean = false, |
||||
handler: suspend MainScope.(item: android.view.MenuItem) -> Unit |
||||
) { |
||||
setOnNavigationItemSelectedListener { item -> |
||||
mainScope.launch { |
||||
handler(item) |
||||
} |
||||
returnValue |
||||
} |
||||
} |
||||
|
||||
} |
@ -1,73 +0,0 @@ |
||||
package com.bennyhuo.kotlin.coroutines.android.mainscope.scope |
||||
|
||||
import android.app.Activity |
||||
import android.os.Looper |
||||
import androidx.fragment.app.Fragment |
||||
import com.bennyhuo.kotlin.coroutines.android.mainscope.EmptyScope |
||||
import com.bennyhuo.kotlin.coroutines.android.mainscope.MainScope |
||||
import com.bennyhuo.kotlin.coroutines.android.mainscope.MainScopeImpl |
||||
import com.bennyhuo.kotlin.coroutines.android.mainscope.exception.UnsupportedTypeException |
||||
import com.bennyhuo.kotlin.coroutines.android.mainscope.exception.UnsupportedVersionException |
||||
import com.bennyhuo.kotlin.coroutines.android.mainscope.utils.Logcat |
||||
import kotlinx.coroutines.cancel |
||||
import java.util.* |
||||
|
||||
interface MainScoped { |
||||
|
||||
companion object { |
||||
internal val scopeMap = IdentityHashMap<MainScoped, MainScope>() |
||||
} |
||||
|
||||
val mainScope: MainScope |
||||
get() { |
||||
if(!MainScope.isSetUp){ |
||||
throw IllegalStateException("MainScope has not been set up yet! Call `MainScope.setUp(application)` once your customized Application created.") |
||||
} |
||||
if(Thread.currentThread() != Looper.getMainLooper().thread){ |
||||
throw IllegalAccessException("MainScope must be accessed from the UI main thread.") |
||||
} |
||||
return (scopeMap[this]) ?: run { |
||||
if(isDestroyed()){ |
||||
Logcat.debug("Access MainScope when scoped instance:$this is FINISHING. EmptyScope will be returned.") |
||||
EmptyScope |
||||
} else { |
||||
Logcat.warn("Create MainScope for scoped instance: $this") |
||||
MainScopeImpl().also { scopeMap[this] = it } |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
private fun MainScoped.isDestroyed(): Boolean { |
||||
return when{ |
||||
this is Activity ->{ |
||||
this.isFinishing |
||||
} |
||||
MainScope.isFragmentSupported && this is Fragment ->{ |
||||
this.activity?.isFinishing?: true || this.isRemoving ||this.view == null |
||||
} |
||||
else ->{ |
||||
val fragmentClass = try { |
||||
Class.forName("android.support.v4.app.Fragment") |
||||
} catch (e: Exception) { |
||||
null |
||||
} |
||||
fragmentClass?.let { |
||||
if(it.isAssignableFrom(this.javaClass)){ |
||||
throw UnsupportedVersionException("com.android.support:support-fragment", "<25.1.0") |
||||
} |
||||
} |
||||
throw UnsupportedTypeException(this.javaClass, "android.app.Activity", "android.support.v4.app.Fragment") |
||||
} |
||||
} |
||||
} |
||||
|
||||
inline fun <T> MainScoped.withMainScope(block: MainScope.() -> T) = with(mainScope, block) |
||||
|
||||
internal fun MainScoped.onMainScopeCreate() { |
||||
//won't create immediately. |
||||
} |
||||
|
||||
internal fun MainScoped.onMainScopeDestroy() { |
||||
MainScoped.scopeMap.remove(this)?.cancel() |
||||
} |
@ -1,115 +0,0 @@ |
||||
package com.bennyhuo.kotlin.coroutines.android.mainscope.scope |
||||
|
||||
import androidx.recyclerview.widget.RecyclerView |
||||
import com.bennyhuo.kotlin.coroutines.android.mainscope.MainScope |
||||
import com.bennyhuo.kotlin.coroutines.android.mainscope.job.launch |
||||
|
||||
interface RecyclerViewScoped : BasicScoped { |
||||
|
||||
fun RecyclerView.onChildAttachStateChangeListener( |
||||
init: __RecyclerView_OnChildAttachStateChangeListener.() -> Unit |
||||
) { |
||||
val listener = __RecyclerView_OnChildAttachStateChangeListener(mainScope) |
||||
listener.init() |
||||
addOnChildAttachStateChangeListener(listener) |
||||
} |
||||
|
||||
class __RecyclerView_OnChildAttachStateChangeListener(private val mainScope: MainScope) : RecyclerView.OnChildAttachStateChangeListener { |
||||
|
||||
private var _onChildViewAttachedToWindow: (suspend MainScope.(android.view.View) -> Unit)? = null |
||||
|
||||
override fun onChildViewAttachedToWindow(view: android.view.View) { |
||||
val handler = _onChildViewAttachedToWindow ?: return |
||||
mainScope.launch { |
||||
handler(view) |
||||
} |
||||
} |
||||
|
||||
fun onChildViewAttachedToWindow( |
||||
listener: suspend MainScope.(android.view.View) -> Unit |
||||
) { |
||||
_onChildViewAttachedToWindow = listener |
||||
} |
||||
|
||||
private var _onChildViewDetachedFromWindow: (suspend MainScope.(android.view.View) -> Unit)? = null |
||||
|
||||
|
||||
override fun onChildViewDetachedFromWindow(view: android.view.View) { |
||||
val handler = _onChildViewDetachedFromWindow ?: return |
||||
mainScope.launch { |
||||
handler(view) |
||||
} |
||||
} |
||||
|
||||
fun onChildViewDetachedFromWindow( |
||||
listener: suspend MainScope.(android.view.View) -> Unit |
||||
) { |
||||
_onChildViewDetachedFromWindow = listener |
||||
} |
||||
|
||||
} |
||||
|
||||
fun RecyclerView.onItemTouchListener( |
||||
init: __RecyclerView_OnItemTouchListener.() -> Unit |
||||
) { |
||||
val listener = __RecyclerView_OnItemTouchListener(mainScope) |
||||
listener.init() |
||||
addOnItemTouchListener(listener) |
||||
} |
||||
|
||||
class __RecyclerView_OnItemTouchListener(private val mainScope: MainScope) : RecyclerView.OnItemTouchListener { |
||||
|
||||
private var _onInterceptTouchEvent: (suspend MainScope.(RecyclerView, android.view.MotionEvent) -> Boolean)? = null |
||||
private var _onInterceptTouchEvent_returnValue: Boolean = false |
||||
|
||||
override fun onInterceptTouchEvent(rv: RecyclerView, e: android.view.MotionEvent): Boolean { |
||||
val returnValue = _onInterceptTouchEvent_returnValue |
||||
val handler = _onInterceptTouchEvent ?: return returnValue |
||||
mainScope.launch { |
||||
handler(rv, e) |
||||
} |
||||
return returnValue |
||||
} |
||||
|
||||
fun onInterceptTouchEvent( |
||||
returnValue: Boolean = false, |
||||
listener: suspend MainScope.(RecyclerView, android.view.MotionEvent) -> Boolean |
||||
) { |
||||
_onInterceptTouchEvent = listener |
||||
_onInterceptTouchEvent_returnValue = returnValue |
||||
} |
||||
|
||||
private var _onTouchEvent: (suspend MainScope.(RecyclerView, android.view.MotionEvent) -> Unit)? = null |
||||
|
||||
override fun onTouchEvent(rv: RecyclerView, e: android.view.MotionEvent) { |
||||
val handler = _onTouchEvent ?: return |
||||
mainScope.launch { |
||||
handler(rv, e) |
||||
} |
||||
} |
||||
|
||||
fun onTouchEvent( |
||||
listener: suspend MainScope.(RecyclerView, android.view.MotionEvent) -> Unit |
||||
) { |
||||
_onTouchEvent = listener |
||||
} |
||||
|
||||
private var _onRequestDisallowInterceptTouchEvent: (suspend MainScope.(Boolean) -> Unit)? = null |
||||
|
||||
|
||||
override fun onRequestDisallowInterceptTouchEvent(disallowIntercept: Boolean) { |
||||
val handler = _onRequestDisallowInterceptTouchEvent ?: return |
||||
mainScope.launch { |
||||
handler(disallowIntercept) |
||||
} |
||||
} |
||||
|
||||
fun onRequestDisallowInterceptTouchEvent( |
||||
listener: suspend MainScope.(Boolean) -> Unit |
||||
) { |
||||
_onRequestDisallowInterceptTouchEvent = listener |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
@ -1,22 +0,0 @@ |
||||
package com.bennyhuo.kotlin.coroutines.android.mainscope.utils |
||||
|
||||
import android.util.Log |
||||
import com.bennyhuo.kotlin.coroutines.android.mainscope.MainScope |
||||
|
||||
object Logcat { |
||||
|
||||
private const val TAG = "MainScope" |
||||
|
||||
fun debug(log: Any?) = MainScope.isDebug.whenTrue { Log.d(TAG, log.toString()) } |
||||
|
||||
fun warn(log: Any?) = MainScope.isDebug.whenTrue { Log.w(TAG, log.toString()) } |
||||
|
||||
fun error(log: Any?) = MainScope.isDebug.whenTrue { Log.e(TAG, log.toString()) } |
||||
|
||||
private fun Boolean.whenTrue(block: () -> Unit) { |
||||
if (this) { |
||||
block() |
||||
} |
||||
} |
||||
|
||||
} |
Loading…
Reference in new issue