https://github.com/pubiqq/lifecycleprops
Property delegates that enable you to associate properties with lifecycle-aware components.
https://github.com/pubiqq/lifecycleprops
android android-library android-lifecycle autocleared lifecycle lifecycle-aware lifecycleprops viewbinding
Last synced: about 1 month ago
JSON representation
Property delegates that enable you to associate properties with lifecycle-aware components.
- Host: GitHub
- URL: https://github.com/pubiqq/lifecycleprops
- Owner: pubiqq
- License: apache-2.0
- Created: 2022-04-03T12:17:18.000Z (almost 4 years ago)
- Default Branch: main
- Last Pushed: 2025-06-18T18:46:28.000Z (8 months ago)
- Last Synced: 2025-06-18T19:44:48.222Z (8 months ago)
- Topics: android, android-library, android-lifecycle, autocleared, lifecycle, lifecycle-aware, lifecycleprops, viewbinding
- Language: Kotlin
- Homepage:
- Size: 480 KB
- Stars: 6
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE.txt
Awesome Lists containing this project
README
LifecycleProps
Property delegates that enable you to associate properties with lifecycle-aware components.
## Setup
Add dependency to the module-level `build.gradle` file:
```kotlin
dependencies {
implementation("io.github.pubiqq:lifecycleprops:latest.release")
}
```
Make sure you have `mavenCentral()` repository in the list of repositories.
## Usage
### Lifecycle-aware delegates
To associate a property to the lifecycle of a `LifecycleOwner` object (such as `AppCompatActivity`, `Fragment`,
`NavBackStackEntry`, etc.), use the `lifecycleAware` function:
```kotlin
class MyActivity : AppCompatActivity() {
// Associates the read-only property with the `MyActivity` lifecycle
val locationService: MyLocationService by lifecycleAware(
initializer = { MyLocationService(context, locationCallback) },
onStart = { start() },
onStop = { stop() }
)
// Associates the read/write property with the `MyActivity` lifecycle
var banner: MyBanner by lifecycleAware(
onStart() = { start() },
onResume() = { resume() },
onPause() = { pause() },
onStop() = { stop() }
)
// ...
banner = MyBanner.Builder(context).build() // manual initialization of the read/write property
}
```
To associate a property with the `Fragment`'s view lifecycle, use `viewLifecycleAware`:
```kotlin
class MyFragment : Fragment() {
// Associates the read-only property with the `MyFragment`'s view lifecycle
val locationService: MyLocationService by viewLifecycleAware(
initializer = { MyLocationService(context, locationCallback) },
onStart = { start() },
onStop = { stop() }
)
// Associates the read/write property with the `MyFragment`'s view lifecycle
var banner: MyBanner by viewLifecycleAware(
onStart() = { start() },
onResume() = { resume() },
onPause() = { pause() },
onStop() = { stop() }
)
// ...
banner = MyBanner.Builder(context).build() // manual initialization of a read/write property
}
```
### Custom configurations
> [!IMPORTANT]
> The API that provides configurations support for lifecycle-aware delegates is marked with the
> `ExperimentalConfigurationApi` annotation.
>
> Usages of such API will be reported as warnings unless an explicit opt-in with the `OptIn` annotation, e.g.
> `@OptIn(ExperimentalConfigurationApi::class)`, or with the
> `-opt-in=com.pubiqq.lifecycleprops.ExperimentalConfigurationApi` compiler option is given.
By default, lifecycle-aware delegates for read-only properties:
- Lazily initialize the associated property.
- Close (if [`AutoCloseable`](https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-auto-closeable/#autocloseable)) and
null out the property value when an `ON_DESTROY` event occurs.
Lifecycle-aware delegates for read/write properties:
- Ensure that a value will not be reassigned to an already initialized property (otherwise an
[`IllegalStateException`](https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-illegal-state-exception/#illegalstateexception)
will be thrown).
- Ensure that each provided event handler will be invoked for the property (otherwise an
[`IllegalStateException`](https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-illegal-state-exception/#illegalstateexception)
will be thrown).
- Close (if [`AutoCloseable`](https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-auto-closeable/#autocloseable)) and
null out the property value when an `ON_DESTROY` event occurs.
If you want to change the behavior of the lifecycle-aware property, you can specify your own custom configuration:
```kotlin
@file:OptIn(ExperimentalConfigurationApi::class)
// Custom configuration for read-only properties
class MyLifecycleAwareReadOnlyConfiguration : LifecycleAwareReadOnlyConfiguration {
override val initializationStrategy: LifecycleAwareInitializationStrategy =
LifecycleAwareInitializationStrategy.OnAnyAccess
override val allowSkipHandlerAccessToUninitializedProperty: Boolean = false
override val shouldNullOutTheProperty: Boolean = true
override fun onClear(value: T) = Unit
}
// Custom configuration for read/write properties
class MyLifecycleAwareReadWriteConfiguration : LifecycleAwareReadWriteConfiguration {
override val allowReassign: Boolean = true
override val allowSkipHandlerAccessToUninitializedProperty: Boolean = true
override val shouldNullOutTheProperty: Boolean = true
override fun onClear(value: T) = Unit
}
```
and apply it to the target property:
```kotlin
@file:OptIn(ExperimentalConfigurationApi::class)
class MyActivity : AppCompatActivity() {
// Associates the read-only property with the `MyActivity` lifecycle (`MyLifecycleAwareReadOnlyConfiguration` is used)
val locationService: MyLocationService by lifecycleAware(
configuration = MyLifecycleAwareReadOnlyConfiguration(),
initializer = { MyLocationService(context, locationCallback) },
onStart = { start() },
onStop = { stop() }
)
// Associates the read/write property with the `MyActivity` lifecycle (`MyLifecycleAwareReadWriteConfiguration` is used)
var banner: MyBanner by lifecycleAware(
configuration = MyLifecycleAwareReadWriteConfiguration(),
onStart() = { start() },
onResume() = { resume() },
onPause() = { pause() },
onStop() = { stop() }
)
// ...
banner = MyBanner.Builder(context).build() // manual initialization of the read/write property
}
```
Also, you can set configurations globally, in which case they will be applied to lifecycle-aware properties by default:
```kotlin
@file:OptIn(ExperimentalConfigurationApi::class)
with(LifecycleProps) {
// Sets default configurations for lifecycle-aware properties
setLifecycleAwareConfigurations(
readOnlyPropsConfiguration = MyLifecycleAwareReadOnlyConfiguration(),
readWritePropsConfiguration = MyLifecycleAwareReadWriteConfiguration()
)
}
with(LifecyclePropsAndroid) {
// Sets default configurations for Android-specific lifecycle-aware properties
setViewLifecycleAwareConfigurations(
readOnlyPropsConfiguration = MyLifecycleAwareReadOnlyConfiguration(),
readWritePropsConfiguration = MyLifecycleAwareReadWriteConfiguration()
)
}
```
## Samples
Check out the [sample](https://github.com/pubiqq/lifecycleprops/tree/main/sample) project to see the library in action.
Also see:
- [AutoCleared](./docs/AutoCleared.md)
- [ViewBinding delegates](./docs/ViewBindingDelegates.md)
## License
Copyright 2021 pubiqq
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.