Skip to main content

Main-thread misuse (7.x Beta)

7.x Beta

APIs and defaults may still change before the 7.0 stable release.

The main-thread misuse detector flags I/O, network, database, or SharedPreferences operations executed on the UI thread — the kind of work that directly causes jank, hangs, and ANRs. When a violation is observed, Bugsee reports an issue with the offending stack trace categorised under one of six domains: DiskRead, DiskWrite, Network, Database, SharedPrefs, or generic Blocking.

Each unique call-site is reported once per session — repeated calls don't flood Bugsee with duplicates.

Requires the Bugsee Gradle plugin

Main-thread misuse is powered by bytecode instrumentation performed by the Bugsee Gradle plugin's mainThreadMisuse transform. The plugin injects lightweight pre-call checks before guarded I/O / network / DB / SharedPreferences calls, and the checks bridge to BugseeMainThreadGuardAdapter at runtime. Without the Gradle plugin, setting the option alone has no effect.

See the Gradle plugin page for setup instructions.

Configuration

FormSetting
Manifest meta-data<meta-data android:name="com.bugsee.option.detect.main_thread_misuse" android:value="true" />
Bugsee.launch() mapoptions.put(Options.DetectAndReportMainThreadMisuse, true)
Defaultfalse
<meta-data android:name="com.bugsee.option.detect.main_thread_misuse"
android:value="true" />

What gets instrumented

The Gradle plugin's transform wraps these surface families:

  • Disk read / writejava.io.FileInputStream / FileOutputStream, RandomAccessFile, Files.read* / write*.
  • NetworkSocket connect / read / write, HttpURLConnection.getResponseCode(), OkHttpClient.execute().
  • DatabaseSQLiteDatabase.execSQL / rawQuery, SupportSQLite* (Room) equivalents.
  • SharedPreferencesSharedPreferences.Editor.commit() (note: apply() is async, so it isn't flagged).
  • BlockingObject.wait, Thread.sleep, CountDownLatch.await when called on the main thread without a timeout.

Calls that are already wrapped in a known background-dispatch idiom (e.g. withContext(Dispatchers.IO), executor.submit(...)) won't trigger reports because the runtime check runs after the dispatch.

See also

Found an issue, typo, or wrong statement on this page? Report it now →