Skip to content

build: update AndroidX, Material, Gson, coroutines, guava, desugar#10

Merged
hawkff merged 2 commits into
mainfrom
maintenance/update-androidx-misc
Jun 15, 2026
Merged

build: update AndroidX, Material, Gson, coroutines, guava, desugar#10
hawkff merged 2 commits into
mainfrom
maintenance/update-androidx-misc

Conversation

@hawkff

@hawkff hawkff commented Jun 15, 2026

Copy link
Copy Markdown
Owner

Summary

Routine app-dependency bumps (third of the split dependency PRs). All chosen to remain
compatible with the current compileSdk 35.

Dependency Before After
kotlinx-coroutines-android 1.6.4 1.8.1
androidx.core:core-ktx 1.9.0 1.13.1
androidx.recyclerview 1.3.0 1.3.2
androidx.fragment:fragment-ktx 1.5.6 1.8.5
androidx.browser 1.5.0 1.8.0
androidx.constraintlayout 2.1.4 2.2.0
androidx.navigation:*-ktx 2.5.3 2.8.5
androidx.preference:preference-ktx 1.2.0 1.2.1
androidx.appcompat 1.6.1 1.7.0
androidx.work:work-* 2.8.1 2.9.1
com.google.android.material 1.8.0 1.12.0
com.google.code.gson 2.9.0 2.11.0
com.google.guava 31.0.1-android 33.4.0-android
desugar_jdk_libs 2.0.3 2.1.3

Source change required

WorkManager 2.9 replaced Configuration.Provider.getWorkManagerConfiguration() (method)
with a workManagerConfiguration (property). Updated SagerNet.kt accordingly. This was
the only API break across all the bumps.

Intentionally held

  • kryo 5.2.1 — backs profile serialization wire format; not bumped to avoid data-format risk.
  • activity-ktx 1.10.1 — already current.
  • swiperefreshlayout 1.1.0 — latest stable.
  • ini4j, process-phoenix, zxing-lite, blacksquircle.*, material-about-library
    left as-is to keep the surface controlled.
  • AndroidX versions were chosen to stay compileSdk 35-compatible (newer core/appcompat/work
    releases that require compileSdk 36 were avoided).

Verification (AWS Linux builder)

  • ./gradlew app:assembleOssDebug — BUILD SUCCESSFUL.
  • ./gradlew app:assembleOssRelease — BUILD SUCCESSFUL (R8 minify, lintVital with
    warningsAsErrors=true, resource shrinking, desugaring all pass).
  • Local CodeRabbit review: 0 findings.

Scope

  • app/build.gradle.kts (14 version bumps) + SagerNet.kt (WorkManager API adaptation).
    No compileSdk/Kotlin/AGP/Gradle changes, no kryo/serialization changes.

Runtime testing note

Build-verified only (emulator blocked by EC2 vCPU quota; increase pending). These are
UI/utility libraries; batched runtime QA planned once emulator capacity exists.

hawkff added 2 commits June 15, 2026 15:07
Routine dependency bumps (compileSdk 35-compatible):
- kotlinx-coroutines 1.6.4 -> 1.8.1
- core-ktx 1.9.0 -> 1.13.1
- recyclerview 1.3.0 -> 1.3.2
- fragment-ktx 1.5.6 -> 1.8.5
- browser 1.5.0 -> 1.8.0
- constraintlayout 2.1.4 -> 2.2.0
- navigation 2.5.3 -> 2.8.5
- preference-ktx 1.2.0 -> 1.2.1
- appcompat 1.6.1 -> 1.7.0
- work 2.8.1 -> 2.9.1
- material 1.8.0 -> 1.12.0
- gson 2.9.0 -> 2.11.0
- guava 31.0.1 -> 33.4.0-android
- desugar_jdk_libs 2.0.3 -> 2.1.3

Held: kryo (profile serialization), ini4j, process-phoenix, zxing-lite,
blacksquircle, material-about-library, swiperefreshlayout, activity-ktx.
WorkManager 2.9 replaced the getWorkManagerConfiguration() method with a
workManagerConfiguration property on Configuration.Provider.
@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

Pull request was closed or merged during review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e4573df1-aac4-44d7-9735-4decff2d4996

📥 Commits

Reviewing files that changed from the base of the PR and between 27af635 and 17dcc0d.

📒 Files selected for processing (2)
  • app/build.gradle.kts
  • app/src/main/java/io/nekohasekai/sagernet/SagerNet.kt

📝 Walkthrough

Summary by CodeRabbit

  • Chores
    • Updated multiple Android/Kotlin libraries and framework dependencies to newer stable releases (including Kotlin coroutines, AndroidX components, Material, JSON parsing, and background processing), and refreshed Java compatibility desugaring for improved platform alignment.

Walkthrough

Dependency versions in app/build.gradle.kts are bumped for Kotlin coroutines, multiple AndroidX libraries, Material, Gson, Guava, and desugar_jdk_libs. In SagerNet.kt, the WorkConfiguration.Provider override is migrated from a method (getWorkManagerConfiguration()) to a property (workManagerConfiguration).

Changes

Dependency and WorkManager Updates

Layer / File(s) Summary
Android/Kotlin dependency version bumps
app/build.gradle.kts
Bumps coroutines, AndroidX core/UI/navigation/preference/appcompat/work, Material, Gson, Guava (31.0.133.4.0), and desugar_jdk_libs (2.0.32.1.3) to newer versions.
WorkManager configuration method-to-property migration
app/src/main/java/io/nekohasekai/sagernet/SagerNet.kt
Replaces override fun getWorkManagerConfiguration(): WorkConfiguration with override val workManagerConfiguration: WorkConfiguration, adapting to the updated WorkManager provider API while preserving the same builder logic.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

Poem

🐇 Hop, hop, versions leap ahead,
New libraries land where old ones tread.
A method becomes a property neat,
WorkManager config, tidy and complete.
The bunny approves — no bugs to dread! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main changes: updating multiple Android/Kotlin dependencies (AndroidX, Material, Gson, coroutines, guava, and desugar libraries).
Description check ✅ Passed The description is directly related to the changeset, providing a detailed summary of dependency version updates, API migration rationale, intentional holds, verification results, and scope.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

Comment @coderabbitai help to get the list of available commands and usage tips.

@hawkff hawkff marked this pull request as ready for review June 15, 2026 19:15
@hawkff

hawkff commented Jun 15, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai full review

Please focus on AndroidX/Material/coroutines compatibility with compileSdk 35, the WorkManager 2.9 Configuration.Provider property migration in SagerNet.kt, and any API breaks. Note: dependency versions were specifically chosen to stay compileSdk-35-compatible (avoided releases requiring compileSdk 36). kryo intentionally held (serialization). Both debug and release builds pass on the builder.

@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== app/build.gradle.kts ==="
cat app/build.gradle.kts

echo ""
echo "=== SagerNet.kt (search) ==="
fd -i "SagerNet.kt" --exec cat {}

echo ""
echo "=== WorkManager Configuration.Provider usage ==="
rg -n "Configuration" --type kotlin -C 5

echo ""
echo "=== coroutines usage patterns ==="
rg -n "coroutines\|GlobalScope\|CoroutineScope\|Dispatchers" --type kotlin -C 2 | head -80

echo ""
echo "=== navigation safe-args or NavController usage ==="
rg -n "NavController\|navigate\|findNavController\|NavigationUI" --type kotlin -C 2 | head -60

echo ""
echo "=== WorkManager enqueue/getConfiguration usage ==="
rg -n "WorkManager\|WorkRequest\|getWorkManagerConfiguration\|workManagerConfiguration" --type kotlin -C 3 | head -80

Length of output: 52114



@hawkff: Full review completed. Here are my findings.


Review: build: update AndroidX, Material, Gson, coroutines, guava, desugar

✅ WorkManager 2.9 — Configuration.Provider Migration (SagerNet.kt)

The migration is correct and complete.

// WorkManager ≤ 2.8 (old — method)
override fun getWorkManagerConfiguration(): WorkConfiguration { … }

// WorkManager ≥ 2.9 (new — property, as implemented)
override val workManagerConfiguration: WorkConfiguration
    get() = WorkConfiguration.Builder()
        .setDefaultProcessName("${BuildConfig.APPLICATION_ID}:bg")
        .build()

Additional correctness notes:

  • Import alias (import androidx.work.Configuration as WorkConfiguration) cleanly resolves the name clash with android.content.res.Configuration used on Lines 9, 107, and 129. No ambiguity.
  • work-runtime-ktx and work-multiprocess are both pinned to 2.9.1 — version parity is required and is present. ✅
  • setDefaultProcessName("${BuildConfig.APPLICATION_ID}:bg") correctly matches the isBgProcess check (process.endsWith(":bg")) in onCreate(). ✅

✅ compileSdk 35 Compatibility — All Bumps

Dependency New version compileSdk-35 safe? Note
appcompat:1.7.0 1.7.0 1.8.0 requires SDK 36 — correctly avoided
core-ktx:1.13.1 1.13.1 1.15+ requires SDK 36 — correctly avoided
work-runtime-ktx:2.9.1 2.9.1 2.10 requires SDK 36 — correctly avoided
navigation:2.8.5 2.8.5
fragment-ktx:1.8.5 1.8.5 activity-ktx:1.10.1 satisfies transitive requirement
material:1.12.0 1.12.0
constraintlayout:2.2.0 2.2.0
guava:33.4.0-android 33.4.0 Correct -android variant (not -jre)
desugar_jdk_libs:2.1.3 2.1.3 Matches isCoreLibraryDesugaringEnabled = true

✅ No SafeArgs / Navigation API Break

No SafeArgs plugin is declared in the plugins {} block (com.android.application, kotlin-android, ksp, kotlin-parcelize only). Navigation 2.8's new type-safe @Serializable route API is opt-in; @IdRes-based navigate() remains fully supported. No action needed.


✅ Fragment 1.8.5 — Predictive Back Compatibility

MainActivity already uses onBackPressedDispatcher.addCallback {} (the modern pattern) with no legacy override fun onBackPressed(). Fragment 1.8's predictive back integration is fully compatible. ✅


✅ Coroutines 1.8.1

DEBUG_PROPERTY_NAME and DEBUG_PROPERTY_VALUE_ON (used in SagerNet.onCreate()) remain stable public API in 1.8.1. No removals or deprecation breaks relevant to this codebase.


⚠️ Advisory: Gson 2.11.0 — Default Float Serialization Behavior Change

Gson 2.10+ changed the default behavior: NaN and ±Infinity are no longer serialized without explicitly enabling them via GsonBuilder().serializeSpecialFloatingPointValues(). If any profile data, subscription parsing, or config export code passes NaN/Infinity through a default Gson() instance, it will now throw IllegalArgumentException at runtime instead of silently encoding a non-standard JSON token.

This won't be caught by the build but could surface in runtime profile handling. It is worth scanning Gson instantiation sites for Gson() vs GsonBuilder() usage. Since kryo is intentionally held for profile serialization, the blast radius is limited — but subscription/config JSON paths may use Gson directly.


Summary

Area Result
WorkManager 2.9 Configuration.Provider property migration ✅ Correct
compileSdk 35 compatibility for all 14 bumps ✅ Confirmed
API breaks across all bumped libs ✅ None found
Navigation 2.8.5 (no SafeArgs) ✅ Safe
Fragment 1.8.5 back handling ✅ Compatible
Coroutines 1.8.1 ✅ No breaks
Gson 2.11.0 special float default ⚠️ Advisory — verify Gson instantiation sites

The PR is well-scoped and the only item requiring attention is the Gson advisory above.

✅ Action performed

Full review finished.

@hawkff

hawkff commented Jun 15, 2026

Copy link
Copy Markdown
Owner Author

Re: Gson 2.11.0 NaN/Infinity advisory — assessed, no change needed.

Both central Gson instances (JavaUtil.gson and SingBoxOptions.gsonSingbox) and the ad-hoc Gson() uses (V2RayFmt VMess QR) only ever serialize VPN config values: ports, timeouts, mbps, packet sizes, UUIDs, strings — all finite integers/doubles parsed from JSON/YAML/URI subscription input. There is no code path that produces Float.NaN or +/-Infinity to serialize, so the Gson 2.10+ stricter default cannot be triggered here. Adding serializeSpecialFloatingPointValues() would be defensive code for an input that cannot occur. Documented as an accepted no-op.

Profile persistence uses kryo (intentionally held), not Gson, so profile data is unaffected.

@hawkff hawkff merged commit 82da6a2 into main Jun 15, 2026
2 of 3 checks passed
@hawkff hawkff deleted the maintenance/update-androidx-misc branch June 15, 2026 19:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant