Tencent/VasSonic · error · IllegalStateException

SonicDBHelper::createInstance() needs to be called before…

Error message

SonicDBHelper::createInstance() needs to be called before SonicDBHelper::getInstance()!

What it means

SonicDBHelper is a singleton whose instance must be explicitly created via createInstance(Context) before use. getInstance() throws this IllegalStateException if the singleton was never initialized, so callers cannot silently operate on a null DB handle.

Solutions

  1. Call SonicDBHelper.createInstance(context) once during app startup (Application.onCreate) before any use of getInstance()
  2. Guard call sites: use SonicDBHelper.isInitialized()/null-check pattern or defer DB access until after SDK init
  3. Ensure initialization happens in every process that touches the DB
  4. Move init earlier in the startup sequence if a component (service/provider) may run before Application.onCreate finishes

Example fix

// before
SonicDBHelper.getInstance().insert(...); // IllegalStateException
// after
public class App extends Application {
  @Override public void onCreate() {
    super.onCreate();
    SonicDBHelper.createInstance(this);
  }
}
SonicDBHelper.getInstance().insert(...);
Defensive patterns

Strategy: validation

Validate before calling

if (SonicDBHelper.getInstanceOrNull() == null) {
  SonicDBHelper.createInstance(context);
}
SonicDBHelper.getInstance()....

Type guard

// Java: wrap access in a lazy initializer
synchronized (App.class) {
  if (!SonicDBHelper.isInitialized()) SonicDBHelper.createInstance(app);
}

Try / catch

try {
  SonicDBHelper.getInstance().query(...);
} catch (IllegalStateException e) {
  SonicDBHelper.createInstance(context);
  SonicDBHelper.getInstance().query(...);
}

Prevention

When it happens

Trigger: Calling SonicDBHelper.getInstance() before any call to SonicDBHelper.createInstance(), e.g. accessing the DB helper from a code path (background thread, ContentProvider, secondary process) that runs before the SDK's init in Application.onCreate().

Common situations: Initializing Sonic in a lazy spot instead of Application.onCreate(); multiple processes where only one ran createInstance; refactoring that removed the init call; accessing the DB helper from a service started independently of the app UI.

Related errors


AI-assisted analysis of Tencent/VasSonic@59936beff6 (2026-09-08). Data as JSON: /api/errors/29db3318c2c4f9c5. Report an issue: GitHub.

Appendix: source

Thrown at sonic-android/sdk/src/main/java/com/tencent/sonic/sdk/SonicDBHelper.java:66

    private static SonicDBHelper sInstance = null;

    private static AtomicBoolean isDBUpgrading = new AtomicBoolean(false);

    private SonicDBHelper(Context context) {
        super(context, SONIC_DATABASE_NAME, null, SONIC_DATABASE_VERSION);
    }

    static synchronized SonicDBHelper createInstance(Context context) {
        if (null == sInstance) {
            sInstance = new SonicDBHelper(context);
        }
        return sInstance;
    }

    public static synchronized SonicDBHelper getInstance() {
        if (null == sInstance) {
            throw new IllegalStateException("SonicDBHelper::createInstance() needs to be called before SonicDBHelper::getInstance()!");
        }
        return sInstance;
    }

    /**
     * Called when the database is created for the first time. This is where the
     * creation of tables and the initial population of the tables should happen.
     *
     * @param db The database.
     */
    @Override
    public void onCreate(SQLiteDatabase db) {
        // create sessionData table
        db.execSQL(SonicDataHelper.CREATE_TABLE_SQL);

        // upgrade SP if need(session data save in SP on sdk 1.0)
        onUpgrade(db, -1, SONIC_DATABASE_VERSION);

View on GitHub (pinned to 59936beff6)