Подтвердить что ты не робот

Как использовать SQLiteDatabase.CursorFactory

Кто-нибудь понимает, как использовать SQLiteDatabase.CursorFactory на Android? Я ищу, чтобы получить постоянный объект SQLiteCursor, который использует инструкцию SQL SELECT, где несколько выражений предложения WHERE используют параметры, которые могут быть изменены программно перед запросом.

Например:

SELECT LocationID FROM Locations WHERE Latitude < northlimit AND Latitude > southlimit AND Longitude < eastlimit AND Longitude > westlimit;

Предельные параметры будут динамически меняться, раз каждые 200 мс

Я пытаюсь решить проблему, при которой, если я просто использую SQLiteDatabase.rawQuery("SELECT ...");, система создает новый CursorWindow для каждого нового запроса, в конечном итоге заканчивается память. Поэтому я пытаюсь найти способ заставить систему не создавать новые CursorWindows.

4b9b3361

Ответ 1

myCursor.close();
myDataBaseHelp.close();

И помните, что после извлечения данных закройте его!

Ответ 2

Вы можете проверить этот учебник. его сумма отлично:

http://www.youtube.com/watch?v=j-IV87qQ00M

и вы должны закрыть БД после любого использования. Другой способ - создать переменную класса Cursor cr и каждый раз, когда вы ее используете, проверьте это: если (кр == NULL)  cr = новый.... else//сделать что-то//

cr.close();

Ответ 3

Я не верю, что использование CursorFactory поможет или необходимо.

В следующем примере таблица на основе вашей создается и загружается 100000 строк.

Один Курсор используется для извлечения переменного числа строк каждые 50 мс 10000 раз.

Когда курсор возвращается, получается счетчик (вызывая сканирование курсора и, таким образом, обращаясь к базе данных), и обновляется TextView, отображая итерацию и количество полученных строк.

Приложение работает без сбоев, и профилировщик показывает, что память управляется волнами в соответствии с: -

enter image description here

Используемый код:

Помощник по базам данных: -

public class DBHelper extends SQLiteOpenHelper {

    public static final String DBNAME = "mydb";
    public static final int DBVERSION = 1;

    public static final String TBL_LOCATIONS = "Locations";
    public static final String COl_LOCATIONS_ID = "LocationId";
    public static final String COl_LATITUDE = "Lattitude";
    public static final String COl_LONGITUDE = "Longitude";
    public static final String COL_OTHER = "other";


    public DBHelper(@Nullable Context context) {
        super(context, DBNAME, null, DBVERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("CREATE TABLE IF NOT EXISTS " + TBL_LOCATIONS +
                "(" +
                COl_LOCATIONS_ID + " INTEGER PRIMARY KEY," +
                COl_LATITUDE + " REAL," +
                COl_LONGITUDE + " REAL," +
                COL_OTHER + " TEXT," +
                " UNIQUE(" + COl_LONGITUDE + "," +  COl_LATITUDE + ")" +
                ")"
        );
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }

    public long insertLocation(double longitude, double latitude, String other) {
        ContentValues cv = new ContentValues();
        cv.put(COl_LONGITUDE,longitude);
        cv.put(COl_LATITUDE,latitude);
        cv.put(COL_OTHER,other);
        return this.getWritableDatabase().insert(TBL_LOCATIONS,null,cv);
    }

    public Cursor getLocations(double northlimit, double southlimt, double eastlimit, double westlimit) {
        return this.getWritableDatabase().query(
                TBL_LOCATIONS,
                new String[]{COl_LOCATIONS_ID},
                COl_LATITUDE + " <? AND " + COl_LATITUDE + ">? AND " + COl_LONGITUDE + "<? AND " + COl_LONGITUDE + "<?",
                new String[]{
                        String.valueOf(northlimit),
                        String.valueOf(southlimt),
                        String.valueOf(eastlimit),
                        String.valueOf(westlimit)},
                null,null,null );
    }
}

Деятельность:

public class MainActivity extends AppCompatActivity {

    private int mInterval = 50;
    private int mCounter = 0;
    private final int mLimit = 10000;
    private Handler mHandler;
    private DBHelper mDBHlpr;
    private Cursor mCsr; //<<<<<<<<<< Just this 1 Cursor is used.
    TextView mTV;
    Random mRnd;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mTV = this.findViewById(R.id.tv);
        mRnd = new Random();
        mDBHlpr = new DBHelper(this);
        addSomeDataIfNone();
        mHandler = new Handler();
        mRunIt.run();

    }

    private void addSomeDataIfNone() {

        SQLiteDatabase db = mDBHlpr.getWritableDatabase();
        if (DatabaseUtils.queryNumEntries(db,DBHelper.TBL_LOCATIONS) > 0) return;
        Random rnd = new Random();
        db.beginTransaction();
        for (int i=0; i < 100000; i++ ) {
            mDBHlpr.insertLocation(abs(mRnd.nextDouble()),abs(mRnd.nextDouble()),"LOCATION" + String.valueOf(i));
        }
        db.setTransactionSuccessful();
        db.endTransaction();
    }

    Runnable mRunIt = new Runnable() {
        @Override
        public void run() {
            if (mCounter > mLimit) return;
            getData(mCounter);
            mCounter++;
            mHandler.postDelayed(mRunIt, mInterval);
        }
    };

    private void getData(int iteration) {
        Log.d("GETTINGDATA","Getting data for iteration " + String.valueOf(iteration));
        double latlim1 = abs(mRnd.nextDouble());
        double latlim2 = abs(mRnd.nextDouble());
        double  lnglim1 = abs(mRnd.nextDouble());
        double lnglim2 = abs(mRnd.nextDouble());
        double nlim = 0.0, slim = 0.0, elim = 0.0, wlim = 0.0;

        if (latlim1 > latlim2) {
            nlim = latlim1;
            slim = latlim2;
        } else {
            nlim = latlim2;
            slim = latlim1;
        }
        if (lnglim1 > lnglim2) {
            elim = lnglim1;
            wlim = lnglim2;
        } else {
            elim = lnglim2;
            wlim = lnglim1;
        }

        mCsr = mDBHlpr.getLocations(nlim,slim,elim,wlim);
        mTV.setText("Iteration " + String.valueOf(iteration) + " Rows returned = " + String.valueOf(mCsr.getCount()));
    }
}