Lifecycling.kt
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package androidx.lifecycle
import androidx.annotation.RestrictTo
import java.lang.reflect.Constructor
import java.lang.reflect.InvocationTargetException
/**
* Internal class to handle lifecycle conversion etc.
*
* @hide
*/
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX)
public object Lifecycling {
private const val REFLECTIVE_CALLBACK = 1
private const val GENERATED_CALLBACK = 2
private val callbackCache: MutableMap<Class<*>, Int> = HashMap()
private val classToAdapters: MutableMap<Class<*>, List<Constructor<out GeneratedAdapter>>> =
HashMap()
@JvmStatic
@Suppress("DEPRECATION")
public fun lifecycleEventObserver(`object`: Any): LifecycleEventObserver {
val isLifecycleEventObserver = `object` is LifecycleEventObserver
val isDefaultLifecycleObserver = `object` is DefaultLifecycleObserver
if (isLifecycleEventObserver && isDefaultLifecycleObserver) {
return DefaultLifecycleObserverAdapter(
`object` as DefaultLifecycleObserver,
`object` as LifecycleEventObserver
)
}
if (isDefaultLifecycleObserver) {
return DefaultLifecycleObserverAdapter(`object` as DefaultLifecycleObserver, null)
}
if (isLifecycleEventObserver) {
return `object` as LifecycleEventObserver
}
val klass: Class<*> = `object`.javaClass
val type = getObserverConstructorType(klass)
if (type == GENERATED_CALLBACK) {
val constructors = classToAdapters[klass]!!
if (constructors.size == 1) {
val generatedAdapter = createGeneratedAdapter(
constructors[0], `object`
)
return SingleGeneratedAdapterObserver(generatedAdapter)
}
val adapters: Array<GeneratedAdapter> = Array(constructors.size) { i ->
createGeneratedAdapter(constructors[i], `object`)
}
return CompositeGeneratedAdaptersObserver(adapters)
}
return ReflectiveGenericLifecycleObserver(`object`)
}
private fun createGeneratedAdapter(
constructor: Constructor<out GeneratedAdapter>,
`object`: Any
): GeneratedAdapter {
return try {
constructor.newInstance(`object`)
} catch (e: IllegalAccessException) {
throw RuntimeException(e)
} catch (e: InstantiationException) {
throw RuntimeException(e)
} catch (e: InvocationTargetException) {
throw RuntimeException(e)
}
}
@Suppress("DEPRECATION")
private fun generatedConstructor(klass: Class<*>): Constructor<out GeneratedAdapter>? {
return try {
val aPackage = klass.getPackage()
val name = klass.canonicalName
val fullPackage = if (aPackage != null) aPackage.name else ""
val adapterName =
getAdapterName(
if (fullPackage.isEmpty()) name
else name.substring(fullPackage.length + 1)
)
@Suppress("UNCHECKED_CAST")
val aClass = Class.forName(
if (fullPackage.isEmpty()) adapterName else "$fullPackage.$adapterName"
) as Class<out GeneratedAdapter>
val constructor = aClass.getDeclaredConstructor(klass)
if (!constructor.isAccessible) {
constructor.isAccessible = true
}
constructor
} catch (e: ClassNotFoundException) {
null
} catch (e: NoSuchMethodException) {
// this should not happen
throw RuntimeException(e)
}
}
private fun getObserverConstructorType(klass: Class<*>): Int {
val callbackCache = callbackCache[klass]
if (callbackCache != null) {
return callbackCache
}
val type = resolveObserverCallbackType(klass)
this.callbackCache[klass] = type
return type
}
private fun resolveObserverCallbackType(klass: Class<*>): Int {
// anonymous class bug:35073837
if (klass.canonicalName == null) {
return REFLECTIVE_CALLBACK
}
val constructor = generatedConstructor(klass)
if (constructor != null) {
classToAdapters[klass] = listOf(constructor)
return GENERATED_CALLBACK
}
@Suppress("DEPRECATION")
val hasLifecycleMethods = ClassesInfoCache.sInstance.hasLifecycleMethods(klass)
if (hasLifecycleMethods) {
return REFLECTIVE_CALLBACK
}
val superclass = klass.superclass
var adapterConstructors: MutableList<Constructor<out GeneratedAdapter>>? = null
if (isLifecycleParent(superclass)) {
if (getObserverConstructorType(superclass) == REFLECTIVE_CALLBACK) {
return REFLECTIVE_CALLBACK
}
adapterConstructors = ArrayList(
classToAdapters[superclass]!!
)
}
for (intrface in klass.interfaces) {
if (!isLifecycleParent(intrface)) {
continue
}
if (getObserverConstructorType(intrface) == REFLECTIVE_CALLBACK) {
return REFLECTIVE_CALLBACK
}
if (adapterConstructors == null) {
adapterConstructors = ArrayList()
}
adapterConstructors.addAll(classToAdapters[intrface]!!)
}
if (adapterConstructors != null) {
classToAdapters[klass] = adapterConstructors
return GENERATED_CALLBACK
}
return REFLECTIVE_CALLBACK
}
private fun isLifecycleParent(klass: Class<*>?): Boolean {
return klass != null && LifecycleObserver::class.java.isAssignableFrom(klass)
}
/**
* Create a name for an adapter class.
*/
@JvmStatic
public fun getAdapterName(className: String): String {
return className.replace(".", "_") + "_LifecycleAdapter"
}
}