sql >> データベース >  >> RDS >> SQLite

バックグラウンドスレッドでSQLiteクエリを非同期で実行するにはどうすればよいですか?

    おそらく、このhttps://developer.android.com/reference/android/app/LoaderManager.htmlがあなたにぴったりです。

    その上、ここにあなたのための短い実装がありますが、これはRxJavaではありません。

    まず、LoaderManager.LoaderCallbacks<Cursor>を実装する必要があります 、通常、このインターフェイスはアクティビティ(またはフラグメント)によって実装されます。

    onCreateLoader内 、CursorLoader 作成して返す必要があります。これは、CursorLoaderの子孫としてMyCursorLoaderを使用した例です。 、データベースへの接続とクエリを実行できます。

    onLoadFinished クエリの結果でカーソルを処理する必要があります。

    上記のandroid.comへのリンクを検討してください。

    public class MainActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor>{
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
    
    @Override
    protected void onResume() {
        super.onResume();
    
        // start loading data using LoaderManager of Activity
        // third argument only has sense in this case
        getLoaderManager().initLoader(0, null, this);
    }
    
    private static final String ACTIVITY_NAME = "main_activity";
    
    private void treatCursorRow(Cursor cursor){
        // treat record from cursor
    }
    
    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
        // this callback is called by LoaderManager in order to obtain CursorLoader
        // here a new one loader is created
        // created loader will be processed by LoaderManager
        return new MyCursorLoader(this, ACTIVITY_NAME);
    }
    
    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
        // this callback is called when loader finishes load cursor
        // you don't need to destroy loader - just tread the data
        if(data != null)
            while(data.moveToNext())
                treatCursorRow(data);
    }
    
    @Override
    public void onLoaderReset(Loader<Cursor> loader) {
        // here you can do something
        // relevant to cancelling of loading data
        // in example, when you have an event that cancels current
        // loading and restarts new one
    }
    
    class MyCursorLoader extends CursorLoader {
    
        private static final String DATABASE_NAME = "my_database";
        private static final int DATABASE_VERSION = 1;
        private String name_param;
    
        public MyCursorLoader(Context context, String activity_name) {
            super(context);
            name_param = activity_name;
        }
    
        @Override
        public Cursor loadInBackground() {
            // assuming, that we have implemented SQLiteOpenHelper
            // to treat sqlite-database
            MyDatabaseHelper dbh = new MyDatabaseHelper(
                    MainActivity.this,
                    DATABASE_NAME,
                    null,
                    DATABASE_VERSION
            );
            return dbh.getWritableDatabase().rawQuery(
                    "SELECT * FROM some_table WHERE name=?",
                    new String[]{ name_param }
            );
        }
    
    }
    
    }
    

    もう1つの方法は、ContentProviderを使用することです。 https://developer.android.com/guide/topics/providers/content-providers.html。

    このようにして、データレイヤーとビジネスロジックを分離できます。データアクセスはurisに抽象化されます。ContentProviderの使用 、その中でクエリを定義し、URIを使用してデータをロードします:

    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
        return getContentResolver().query(
                YourContentProvider.SOME_URI,
                null,
                null,
                null,
                null
        );
    }
    

    これは、データ(アクティビティまたはフラグメント)の顧客が1つまたは2つ以上ある場合に便利な方法です。SQLクエリを繰り返したり、多数のCursorLoaders descendandsを作成したりするのではなく、事前定義されたURIのみを使用します。 。

    さらに、ContentProvider 必要に応じて、アプリの外部から使用できます。




    1. MicrosoftAccessでデータベースの破損を防ぐ方法

    2. DLL「kernel32.dll」で「InterlockedIncrement」という名前のエントリポイントが見つかりません-[メール保護]64ビット

    3. MariaDBでのOCT()のしくみ

    4. MySQL CEILING()関数–最も近い整数に切り上げ