ViewBindingPropertyDelegate

repository·master·Indexed 23 days ago

https://github.com/androidbroadcast/viewbindingpropertydelegate

A library that simplifies Android View Binding by managing the lifecycle of binding objects to prevent memory leaks and providing lazy, non-nullable access to views. It offers two variants: 'vbpd' for optimal performance without reflection, and 'vbpd-reflection' which includes additional reflection-based factories.

Tokens
4K
Snippets
13
Records
19
Agent score
80%

What's inside ViewBindingPropertyDelegate

  1. What is ViewBindingPropertyDelegate

    master

    ViewBindingPropertyDelegate is a library designed to simplify working with Android View Binding. It provides three main benefits:

    1. Lifecycle Management: It automatically manages the ViewBinding lifecycle and clears references to prevent memory leaks.
    2. Non-nullable References: It eliminates the need to maintain nullable references to Views or ViewBindings in your Fragments or Activities.
    3. Lazy Initialization: It creates the ViewBinding lazily.

    The library offers two variants:

    • vbpd: The recommended version that does not use reflection for better performance.
    • vbpd-reflection: Includes additional factories that use reflection under the hood.
  2. Configure Kover code coverage in the convention plugin

    master

    To enable code coverage reporting with Kover:

    1. Add the dependency: Add gradleplugins-kover to gradle/libs.versions.toml and include implementation(libs.gradleplugins.kover) in the convention plugin's build.gradle.kts.
    2. Apply the plugin: In vbpdconfig.gradle.kts, add plugins.apply(libs.plugins.kover.get().pluginId).

    Commands:

    • Generate HTML report: ./gradlew koverHtmlReport
    ./gradlew koverHtmlReport
  3. Configure test infrastructure for vbpd-core

    master

    To set up unit testing for the vbpd-core module, you must add the necessary dependencies to vbpd-core/build.gradle.kts and ensure Android resources are enabled in your convention plugin configuration.

    1. Add dependencies

    Add the following to vbpd-core/build.gradle.kts:

    plugins {
        id("vbpdconfig")
    }
    
    dependencies {
        api(libs.androidx.viewbinding)
        implementation(libs.androidx.annotation)
    
        testImplementation(libs.test.junit)
        testImplementation(libs.test.kotlin)
        testImplementation(libs.test.mockk)
        testImplementation(libs.test.robolectric)
        testImplementation(libs.test.androidx.core)
    }

    2. Enable Android resources for unit tests

    In your vbpdconfig.gradle.kts file, ensure the androidLibraryConfig block includes isIncludeAndroidResources = true to allow Robolectric and other tests to access Android resources during unit tests:

    // Inside androidLibraryConfig block
    testOptions {
        unitTests {
            isIncludeAndroidResources = true
        }
    }
    testOptions {
        unitTests {
            isIncludeAndroidResources = true
        }
    }
  4. Configure test dependencies for vbpd module

    master

    To support testing Activity and Fragment lifecycles in the vbpd module, update vbpd/build.gradle.kts with the following dependencies:

    plugins {
        id("vbpdconfig")
    }
    
    dependencies {
        compileOnly(libs.androidx.fragment)
        compileOnly(libs.androidx.activity)
        compileOnly(libs.androidx.recyclerview)
        api(projects.vbpdCore)
    
        testImplementation(libs.test.junit)
        testImplementation(libs.test.kotlin)
        testImplementation(libs.test.mockk)
        testImplementation(libs.test.robolectric)
        testImplementation(libs.test.androidx.core)
        testImplementation(libs.test.androidx.runner)
        testImplementation(libs.androidx.fragment)
        testImplementation(libs.androidx.activity)
        testImplementation(libs.androidx.recyclerview)
        testImplementation(libs.androidx.appcompat)
        // For Fragment testing
        testImplementation(libs.test.fragment)
    }
    dependencies {
        compileOnly(libs.androidx.fragment)
        compileOnly(libs.androidx.activity)
        compileOnly(libs.androidx.recyclerview)
        api(projects.vbpdCore)
    
        testImplementation(libs.test.junit)
        testImplementation(libs.test.kotlin)
        testImplementation(libs.test.mockk)
        testImplementation(libs.test.robolectric)
        testImplementation(libs.test.androidx.core)
        testImplementation(libs.test.androidx.runner)
        testImplementation(libs.androidx.fragment)
        testImplementation(libs.androidx.activity)
        testImplementation(libs.androidx.recyclerview)
        testImplementation(libs.androidx.appcompat)
        testImplementation(libs.test.fragment)
    }
  5. Run the full test suite and generate coverage reports

    master

    To verify the entire project, run the following commands:

    1. Run all tests: ./gradlew testDebugUnitTest
    2. Generate HTML coverage report: ./gradlew koverHtmlReport
    3. Run all quality checks (including detekt and ktlint): ./gradlew check

    Coverage reports can be found in the following locations:

    • vbpd-core/build/reports/kover/html/index.html
    • vbpd/build/reports/kover/html/index.html
    • vbpd-reflection/build/reports/kover/html/index.html
    ./gradlew testDebugUnitTest
    ./gradlew koverHtmlReport
    ./gradlew check
  6. Migrate from version 1.0 to 2.x

    master

    If you are upgrading from version 1.x, you can use both versions in the same project during transition. To complete the migration:

    1. Update Package Names: Replace com.github.kirich1409.viewbindingpropertydelegate with dev.androidbroadcast.vbpd.
    2. Update Lifecycle Handling: Replace the use of onViewDestroyed by moving that logic to the appropriate lifecycle callback, such as Fragment.onDestroyView() or Activity.onDestroy().
  7. Add test dependencies to the version catalog

    master

    To prepare the project for testing, add the necessary versions and library definitions to gradle/libs.versions.toml. This includes versions for Robolectric, MockK, JUnit, and AndroidX Test, along with their corresponding library mappings and plugin IDs for Detekt, ktlint, and Kover.

    # In [versions] section, add:
    detekt = "1.23.8"
    ktlint = "14.0.1"
    kover = "0.9.7"
    robolectric = "4.16.1"
    mockk = "1.14.9"
    androidx-test-core = "1.6.1"
    androidx-test-runner = "1.6.2"
    junit = "4.13.2"
    
    # In [libraries] section, add:
    test-robolectric = { module = "org.robolectric:robolectric", version.ref = "robolectric" }
    test-mockk = { module = "io.mockk:mockk", version.ref = "mockk" }
    test-junit = { module = "junit:junit", version.ref = "junit" }
    test-kotlin = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" }
    test-androidx-core = { module = "androidx.test:core-ktx", version.ref = "androidx-test-core" }
    test-androidx-runner = { module = "androidx.test:runner", version.ref = "androidx-test-runner" }
    test-fragment = { module = "androidx.fragment:fragment-testing", version.ref = "androidx-fragment" }
    
    # In [plugins] section, add:
    detekt = { id = "io.gitlab.arturbosch.detekt", version.ref = "detekt" }
    ktlint = { id = "org.jlleitschuh.gradle.ktlint", version.ref = "ktlint" }
    kover = { id = "org.jetbrains.kotlinx.kover", version.ref = "kover" }
  8. Test ViewBindingCache and Reflection in vbpd-reflection

    master

    The vbpd-reflection module requires specific test dependencies and coverage for its cache and reflection logic.

    Testing ViewBindingCache: Verify that ViewBindingCache.setEnabled(true/false) works without crashing and that ViewBindingCache.clear() behaves correctly even when the cache is empty or when the cache is disabled.

    Testing Reflection (CreateMethod): Verify that the CreateMethod enum contains the expected values BIND and INFLATE and that these values are distinct.

  9. Add ViewBindingPropertyDelegate to your project

    master

    Add the library to your Gradle dependencies. It is recommended to use the vbpd artifact for optimal performance. Ensure mavenCentral() is included in your repositories configuration.

    allprojects {
      repositories {
        mavenCentral()
      }
    }
    
    dependencies {
        // recommended
        implementation("dev.androidbroadcast.vbpd:vbpd:2.0.4")
        
        // additional factories that use reflection under hood
        implementation("dev.androidbroadcast.vbpd:vbpd-reflection:2.0.4")
    }
  10. Configure ktlint code formatting in the convention plugin

    master

    To enforce code formatting using ktlint:

    1. Add the dependency: Add gradleplugins-ktlint to gradle/libs.versions.toml and include implementation(libs.gradleplugins.ktlint) in the convention plugin's build.gradle.kts.
    2. Apply the plugin: In vbpdconfig.gradle.kts, add plugins.apply(libs.plugins.ktlint.get().pluginId).

    Commands:

    • Check formatting: ./gradlew ktlintCheck
    • Auto-fix formatting: ./gradlew ktlintFormat
    ./gradlew ktlintCheck
    ./gradlew ktlintFormat