Getting started

Modules

Module Use it for
bridge-glassbox Diagnostics only — works in any app, including apps on plain WorkManager
bridge-compat Running existing androidx.work-style workers on Bridge via an import change
bridge-runtime The native API: constraint DSL, chunked workers, durable coroutines, diagnostics
bridge-sim JVM tests that script device regimes (Doze, buckets, thermal, thread pressure)

Installation

Two dependencies: the core runtime (which brings bridge-glassbox transitively) and, for tests, the JVM simulator. Served via JitPack:

// settings.gradle.kts
dependencyResolutionManagement {
    repositories {
        maven(url = "https://jitpack.io")
    }
}

// module build.gradle.kts
dependencies {
    // Core: runtime engine + diagnostics
    implementation("com.github.iamjosephmj.bridge:bridge-runtime:0.5.0-rc.6")

    // Test: JVM simulator — device regimes in milliseconds
    testImplementation("com.github.iamjosephmj.bridge:bridge-sim:0.5.0-rc.6")
}

bridge-compat and standalone bridge-glassbox are published under the same group for Tier 1 and Tier 0 adoption respectively.

Initialize

Register worker factories at every process start. Relaunching is the recovery path, so this must run in Application.onCreate — the same reachability rule WorkManager places on its worker classes.

class App : Application() {
    override fun onCreate() {
        super.onCreate()
        Bridge.initializeAsync(this) {
            worker("sync") { SyncWorker() }
        }
    }
}

initializeAsync keeps journal-open and reconciliation off the main thread. enqueue throws if called before init completes — early callers should suspend on Bridge.awaitReady() first (or use the synchronous Bridge.initialize); scope().launch and handle.await() gate on readiness internally.

A first worker

class SyncWorker : BridgeWorker {
    override suspend fun run(ctx: RunContext): RunResult {
        api.sync()
        return RunResult.Success
    }
}

A first enqueue

Bridge.enqueue(workRequest("nightly-sync", "sync") {
    network()
    charging()
})

Enqueue has KEEP semantics per unique name: enqueueing an existing live name is a no-op, so unconditional enqueue-on-startup is safe.

Ask why it isn’t running

Log.i(TAG, Bridge.whyPending("nightly-sync").render(now))
// ENQUEUED 2h 10m — DeferredByDoze(deep) [REPORTED]

From here:


This site uses Just the Docs, a documentation theme for Jekyll.