Merge "Preventing launcher crashes due to low disk space." into ub-launcher3-burnaby-polish
This commit is contained in:
@@ -28,7 +28,7 @@ import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.content.res.Resources;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteOpenHelper;
|
||||
import android.database.sqlite.SQLiteException;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Canvas;
|
||||
@@ -48,6 +48,7 @@ import com.android.launcher3.compat.UserManagerCompat;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.model.PackageItemInfo;
|
||||
import com.android.launcher3.util.ComponentKey;
|
||||
import com.android.launcher3.util.SQLiteCacheHelper;
|
||||
import com.android.launcher3.util.Thunk;
|
||||
|
||||
import java.util.Collections;
|
||||
@@ -230,9 +231,9 @@ public class IconCache {
|
||||
public synchronized void removeIconsForPkg(String packageName, UserHandleCompat user) {
|
||||
removeFromMemCacheLocked(packageName, user);
|
||||
long userSerial = mUserManager.getSerialNumberForUser(user);
|
||||
mIconDb.getWritableDatabase().delete(IconDB.TABLE_NAME,
|
||||
mIconDb.delete(
|
||||
IconDB.COLUMN_COMPONENT + " LIKE ? AND " + IconDB.COLUMN_USER + " = ?",
|
||||
new String[] {packageName + "/%", Long.toString(userSerial)});
|
||||
new String[]{packageName + "/%", Long.toString(userSerial)});
|
||||
}
|
||||
|
||||
public void updateDbIcons(Set<String> ignorePackagesForMainUser) {
|
||||
@@ -275,58 +276,65 @@ public class IconCache {
|
||||
componentMap.put(app.getComponentName(), app);
|
||||
}
|
||||
|
||||
Cursor c = mIconDb.getReadableDatabase().query(IconDB.TABLE_NAME,
|
||||
new String[] {IconDB.COLUMN_ROWID, IconDB.COLUMN_COMPONENT,
|
||||
IconDB.COLUMN_LAST_UPDATED, IconDB.COLUMN_VERSION,
|
||||
IconDB.COLUMN_SYSTEM_STATE},
|
||||
IconDB.COLUMN_USER + " = ? ",
|
||||
new String[] {Long.toString(userSerial)},
|
||||
null, null, null);
|
||||
|
||||
final int indexComponent = c.getColumnIndex(IconDB.COLUMN_COMPONENT);
|
||||
final int indexLastUpdate = c.getColumnIndex(IconDB.COLUMN_LAST_UPDATED);
|
||||
final int indexVersion = c.getColumnIndex(IconDB.COLUMN_VERSION);
|
||||
final int rowIndex = c.getColumnIndex(IconDB.COLUMN_ROWID);
|
||||
final int systemStateIndex = c.getColumnIndex(IconDB.COLUMN_SYSTEM_STATE);
|
||||
|
||||
HashSet<Integer> itemsToRemove = new HashSet<Integer>();
|
||||
Stack<LauncherActivityInfoCompat> appsToUpdate = new Stack<>();
|
||||
|
||||
while (c.moveToNext()) {
|
||||
String cn = c.getString(indexComponent);
|
||||
ComponentName component = ComponentName.unflattenFromString(cn);
|
||||
PackageInfo info = pkgInfoMap.get(component.getPackageName());
|
||||
if (info == null) {
|
||||
if (!ignorePackages.contains(component.getPackageName())) {
|
||||
Cursor c = null;
|
||||
try {
|
||||
c = mIconDb.query(
|
||||
new String[]{IconDB.COLUMN_ROWID, IconDB.COLUMN_COMPONENT,
|
||||
IconDB.COLUMN_LAST_UPDATED, IconDB.COLUMN_VERSION,
|
||||
IconDB.COLUMN_SYSTEM_STATE},
|
||||
IconDB.COLUMN_USER + " = ? ",
|
||||
new String[]{Long.toString(userSerial)});
|
||||
|
||||
final int indexComponent = c.getColumnIndex(IconDB.COLUMN_COMPONENT);
|
||||
final int indexLastUpdate = c.getColumnIndex(IconDB.COLUMN_LAST_UPDATED);
|
||||
final int indexVersion = c.getColumnIndex(IconDB.COLUMN_VERSION);
|
||||
final int rowIndex = c.getColumnIndex(IconDB.COLUMN_ROWID);
|
||||
final int systemStateIndex = c.getColumnIndex(IconDB.COLUMN_SYSTEM_STATE);
|
||||
|
||||
while (c.moveToNext()) {
|
||||
String cn = c.getString(indexComponent);
|
||||
ComponentName component = ComponentName.unflattenFromString(cn);
|
||||
PackageInfo info = pkgInfoMap.get(component.getPackageName());
|
||||
if (info == null) {
|
||||
if (!ignorePackages.contains(component.getPackageName())) {
|
||||
remove(component, user);
|
||||
itemsToRemove.add(c.getInt(rowIndex));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if ((info.applicationInfo.flags & ApplicationInfo.FLAG_IS_DATA_ONLY) != 0) {
|
||||
// Application is not present
|
||||
continue;
|
||||
}
|
||||
|
||||
long updateTime = c.getLong(indexLastUpdate);
|
||||
int version = c.getInt(indexVersion);
|
||||
LauncherActivityInfoCompat app = componentMap.remove(component);
|
||||
if (version == info.versionCode && updateTime == info.lastUpdateTime &&
|
||||
TextUtils.equals(mSystemState, c.getString(systemStateIndex))) {
|
||||
continue;
|
||||
}
|
||||
if (app == null) {
|
||||
remove(component, user);
|
||||
itemsToRemove.add(c.getInt(rowIndex));
|
||||
} else {
|
||||
appsToUpdate.add(app);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if ((info.applicationInfo.flags & ApplicationInfo.FLAG_IS_DATA_ONLY) != 0) {
|
||||
// Application is not present
|
||||
continue;
|
||||
}
|
||||
|
||||
long updateTime = c.getLong(indexLastUpdate);
|
||||
int version = c.getInt(indexVersion);
|
||||
LauncherActivityInfoCompat app = componentMap.remove(component);
|
||||
if (version == info.versionCode && updateTime == info.lastUpdateTime &&
|
||||
TextUtils.equals(mSystemState, c.getString(systemStateIndex))) {
|
||||
continue;
|
||||
}
|
||||
if (app == null) {
|
||||
remove(component, user);
|
||||
itemsToRemove.add(c.getInt(rowIndex));
|
||||
} else {
|
||||
appsToUpdate.add(app);
|
||||
} catch (SQLiteException e) {
|
||||
Log.d(TAG, "Error reading icon cache", e);
|
||||
// Continue updating whatever we have read so far
|
||||
} finally {
|
||||
if (c != null) {
|
||||
c.close();
|
||||
}
|
||||
}
|
||||
c.close();
|
||||
if (!itemsToRemove.isEmpty()) {
|
||||
mIconDb.getWritableDatabase().delete(IconDB.TABLE_NAME,
|
||||
Utilities.createDbSelectionQuery(IconDB.COLUMN_ROWID, itemsToRemove),
|
||||
null);
|
||||
mIconDb.delete(
|
||||
Utilities.createDbSelectionQuery(IconDB.COLUMN_ROWID, itemsToRemove), null);
|
||||
}
|
||||
|
||||
// Insert remaining apps.
|
||||
@@ -356,8 +364,7 @@ public class IconCache {
|
||||
values.put(IconDB.COLUMN_USER, userSerial);
|
||||
values.put(IconDB.COLUMN_LAST_UPDATED, info.lastUpdateTime);
|
||||
values.put(IconDB.COLUMN_VERSION, info.versionCode);
|
||||
mIconDb.getWritableDatabase().insertWithOnConflict(IconDB.TABLE_NAME, null, values,
|
||||
SQLiteDatabase.CONFLICT_REPLACE);
|
||||
mIconDb.insertOrReplace(values);
|
||||
}
|
||||
|
||||
@Thunk ContentValues updateCacheAndGetContentValues(LauncherActivityInfoCompat app,
|
||||
@@ -672,19 +679,18 @@ public class IconCache {
|
||||
label, Color.TRANSPARENT);
|
||||
values.put(IconDB.COLUMN_COMPONENT, componentName.flattenToString());
|
||||
values.put(IconDB.COLUMN_USER, userSerial);
|
||||
mIconDb.getWritableDatabase().insertWithOnConflict(IconDB.TABLE_NAME, null, values,
|
||||
SQLiteDatabase.CONFLICT_REPLACE);
|
||||
mIconDb.insertOrReplace(values);
|
||||
}
|
||||
|
||||
private boolean getEntryFromDB(ComponentKey cacheKey, CacheEntry entry, boolean lowRes) {
|
||||
Cursor c = mIconDb.getReadableDatabase().query(IconDB.TABLE_NAME,
|
||||
new String[] {lowRes ? IconDB.COLUMN_ICON_LOW_RES : IconDB.COLUMN_ICON,
|
||||
Cursor c = null;
|
||||
try {
|
||||
c = mIconDb.query(
|
||||
new String[]{lowRes ? IconDB.COLUMN_ICON_LOW_RES : IconDB.COLUMN_ICON,
|
||||
IconDB.COLUMN_LABEL},
|
||||
IconDB.COLUMN_COMPONENT + " = ? AND " + IconDB.COLUMN_USER + " = ?",
|
||||
new String[] {cacheKey.componentName.flattenToString(),
|
||||
Long.toString(mUserManager.getSerialNumberForUser(cacheKey.user))},
|
||||
null, null, null);
|
||||
try {
|
||||
new String[]{cacheKey.componentName.flattenToString(),
|
||||
Long.toString(mUserManager.getSerialNumberForUser(cacheKey.user))});
|
||||
if (c.moveToNext()) {
|
||||
entry.icon = loadIconNoResize(c, 0, lowRes ? mLowResOptions : null);
|
||||
entry.isLowResIcon = lowRes;
|
||||
@@ -698,8 +704,12 @@ public class IconCache {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} catch (SQLiteException e) {
|
||||
Log.d(TAG, "Error reading icon cache", e);
|
||||
} finally {
|
||||
c.close();
|
||||
if (c != null) {
|
||||
c.close();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -745,9 +755,9 @@ public class IconCache {
|
||||
LauncherActivityInfoCompat app = mAppsToUpdate.pop();
|
||||
String cn = app.getComponentName().flattenToString();
|
||||
ContentValues values = updateCacheAndGetContentValues(app, true);
|
||||
mIconDb.getWritableDatabase().update(IconDB.TABLE_NAME, values,
|
||||
mIconDb.update(values,
|
||||
IconDB.COLUMN_COMPONENT + " = ? AND " + IconDB.COLUMN_USER + " = ?",
|
||||
new String[] {cn, Long.toString(mUserSerial)});
|
||||
new String[]{cn, Long.toString(mUserSerial)});
|
||||
mUpdatedPackages.add(app.getComponentName().getPackageName());
|
||||
|
||||
if (mAppsToUpdate.isEmpty() && !mUpdatedPackages.isEmpty()) {
|
||||
@@ -782,7 +792,7 @@ public class IconCache {
|
||||
mSystemState = Locale.getDefault().toString();
|
||||
}
|
||||
|
||||
private static final class IconDB extends SQLiteOpenHelper {
|
||||
private static final class IconDB extends SQLiteCacheHelper {
|
||||
private final static int DB_VERSION = 7;
|
||||
|
||||
private final static int RELEASE_VERSION = DB_VERSION +
|
||||
@@ -800,11 +810,11 @@ public class IconCache {
|
||||
private final static String COLUMN_SYSTEM_STATE = "system_state";
|
||||
|
||||
public IconDB(Context context) {
|
||||
super(context, LauncherFiles.APP_ICONS_DB, null, RELEASE_VERSION);
|
||||
super(context, LauncherFiles.APP_ICONS_DB, RELEASE_VERSION, TABLE_NAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(SQLiteDatabase db) {
|
||||
protected void onCreateTable(SQLiteDatabase db) {
|
||||
db.execSQL("CREATE TABLE IF NOT EXISTS " + TABLE_NAME + " (" +
|
||||
COLUMN_COMPONENT + " TEXT NOT NULL, " +
|
||||
COLUMN_USER + " INTEGER NOT NULL, " +
|
||||
@@ -817,25 +827,6 @@ public class IconCache {
|
||||
"PRIMARY KEY (" + COLUMN_COMPONENT + ", " + COLUMN_USER + ") " +
|
||||
");");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
|
||||
if (oldVersion != newVersion) {
|
||||
clearDB(db);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
|
||||
if (oldVersion != newVersion) {
|
||||
clearDB(db);
|
||||
}
|
||||
}
|
||||
|
||||
private void clearDB(SQLiteDatabase db) {
|
||||
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
|
||||
onCreate(db);
|
||||
}
|
||||
}
|
||||
|
||||
private ContentValues newContentValues(Bitmap icon, String label, int lowResBackgroundColor) {
|
||||
|
||||
@@ -10,7 +10,6 @@ import android.content.res.Resources;
|
||||
import android.database.Cursor;
|
||||
import android.database.SQLException;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteOpenHelper;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Bitmap.Config;
|
||||
import android.graphics.BitmapFactory;
|
||||
@@ -32,6 +31,7 @@ import com.android.launcher3.compat.AppWidgetManagerCompat;
|
||||
import com.android.launcher3.compat.UserHandleCompat;
|
||||
import com.android.launcher3.compat.UserManagerCompat;
|
||||
import com.android.launcher3.util.ComponentKey;
|
||||
import com.android.launcher3.util.SQLiteCacheHelper;
|
||||
import com.android.launcher3.util.Thunk;
|
||||
import com.android.launcher3.widget.WidgetCell;
|
||||
|
||||
@@ -104,7 +104,7 @@ public class WidgetPreviewLoader {
|
||||
* The DB holds the generated previews for various components. Previews can also have different
|
||||
* sizes (landscape vs portrait).
|
||||
*/
|
||||
private static class CacheDb extends SQLiteOpenHelper {
|
||||
private static class CacheDb extends SQLiteCacheHelper {
|
||||
private static final int DB_VERSION = 4;
|
||||
|
||||
private static final String TABLE_NAME = "shortcut_and_widget_previews";
|
||||
@@ -117,11 +117,11 @@ public class WidgetPreviewLoader {
|
||||
private static final String COLUMN_PREVIEW_BITMAP = "preview_bitmap";
|
||||
|
||||
public CacheDb(Context context) {
|
||||
super(context, LauncherFiles.WIDGET_PREVIEWS_DB, null, DB_VERSION);
|
||||
super(context, LauncherFiles.WIDGET_PREVIEWS_DB, DB_VERSION, TABLE_NAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(SQLiteDatabase database) {
|
||||
public void onCreateTable(SQLiteDatabase database) {
|
||||
database.execSQL("CREATE TABLE IF NOT EXISTS " + TABLE_NAME + " (" +
|
||||
COLUMN_COMPONENT + " TEXT NOT NULL, " +
|
||||
COLUMN_USER + " INTEGER NOT NULL, " +
|
||||
@@ -133,25 +133,6 @@ public class WidgetPreviewLoader {
|
||||
"PRIMARY KEY (" + COLUMN_COMPONENT + ", " + COLUMN_USER + ", " + COLUMN_SIZE + ") " +
|
||||
");");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
|
||||
if (oldVersion != newVersion) {
|
||||
clearDB(db);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
|
||||
if (oldVersion != newVersion) {
|
||||
clearDB(db);
|
||||
}
|
||||
}
|
||||
|
||||
private void clearDB(SQLiteDatabase db) {
|
||||
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
|
||||
onCreate(db);
|
||||
}
|
||||
}
|
||||
|
||||
private WidgetCacheKey getObjectKey(Object o, String size) {
|
||||
@@ -176,13 +157,7 @@ public class WidgetPreviewLoader {
|
||||
values.put(CacheDb.COLUMN_VERSION, versions[0]);
|
||||
values.put(CacheDb.COLUMN_LAST_UPDATED, versions[1]);
|
||||
values.put(CacheDb.COLUMN_PREVIEW_BITMAP, Utilities.flattenBitmap(preview));
|
||||
|
||||
try {
|
||||
mDb.getWritableDatabase().insertWithOnConflict(CacheDb.TABLE_NAME, null, values,
|
||||
SQLiteDatabase.CONFLICT_REPLACE);
|
||||
} catch (SQLException e) {
|
||||
Log.e(TAG, "Error saving image to DB", e);
|
||||
}
|
||||
mDb.insertOrReplace(values);
|
||||
}
|
||||
|
||||
public void removePackage(String packageName, UserHandleCompat user) {
|
||||
@@ -194,13 +169,9 @@ public class WidgetPreviewLoader {
|
||||
mPackageVersions.remove(packageName);
|
||||
}
|
||||
|
||||
try {
|
||||
mDb.getWritableDatabase().delete(CacheDb.TABLE_NAME,
|
||||
CacheDb.COLUMN_PACKAGE + " = ? AND " + CacheDb.COLUMN_USER + " = ?",
|
||||
new String[] {packageName, Long.toString(userSerial)});
|
||||
} catch (SQLException e) {
|
||||
Log.e(TAG, "Unable to delete items from DB", e);
|
||||
}
|
||||
mDb.delete(
|
||||
CacheDb.COLUMN_PACKAGE + " = ? AND " + CacheDb.COLUMN_USER + " = ?",
|
||||
new String[]{packageName, Long.toString(userSerial)});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -238,10 +209,10 @@ public class WidgetPreviewLoader {
|
||||
LongSparseArray<HashSet<String>> packagesToDelete = new LongSparseArray<>();
|
||||
Cursor c = null;
|
||||
try {
|
||||
c = mDb.getReadableDatabase().query(CacheDb.TABLE_NAME,
|
||||
new String[] {CacheDb.COLUMN_USER, CacheDb.COLUMN_PACKAGE,
|
||||
CacheDb.COLUMN_LAST_UPDATED, CacheDb.COLUMN_VERSION},
|
||||
null, null, null, null, null);
|
||||
c = mDb.query(
|
||||
new String[]{CacheDb.COLUMN_USER, CacheDb.COLUMN_PACKAGE,
|
||||
CacheDb.COLUMN_LAST_UPDATED, CacheDb.COLUMN_VERSION},
|
||||
null, null);
|
||||
while (c.moveToNext()) {
|
||||
long userId = c.getLong(0);
|
||||
String pkg = c.getString(1);
|
||||
@@ -274,7 +245,7 @@ public class WidgetPreviewLoader {
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
Log.e(TAG, "Error updatating widget previews", e);
|
||||
Log.e(TAG, "Error updating widget previews", e);
|
||||
} finally {
|
||||
if (c != null) {
|
||||
c.close();
|
||||
@@ -288,16 +259,15 @@ public class WidgetPreviewLoader {
|
||||
@Thunk Bitmap readFromDb(WidgetCacheKey key, Bitmap recycle, PreviewLoadTask loadTask) {
|
||||
Cursor cursor = null;
|
||||
try {
|
||||
cursor = mDb.getReadableDatabase().query(
|
||||
CacheDb.TABLE_NAME,
|
||||
new String[] { CacheDb.COLUMN_PREVIEW_BITMAP },
|
||||
CacheDb.COLUMN_COMPONENT + " = ? AND " + CacheDb.COLUMN_USER + " = ? AND " + CacheDb.COLUMN_SIZE + " = ?",
|
||||
new String[] {
|
||||
cursor = mDb.query(
|
||||
new String[]{CacheDb.COLUMN_PREVIEW_BITMAP},
|
||||
CacheDb.COLUMN_COMPONENT + " = ? AND " + CacheDb.COLUMN_USER + " = ? AND "
|
||||
+ CacheDb.COLUMN_SIZE + " = ?",
|
||||
new String[]{
|
||||
key.componentName.flattenToString(),
|
||||
Long.toString(mUserManager.getSerialNumberForUser(key.user)),
|
||||
key.size
|
||||
},
|
||||
null, null, null);
|
||||
});
|
||||
// If cancelled, skip getting the blob and decoding it into a bitmap
|
||||
if (loadTask.isCancelled()) {
|
||||
return null;
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
package com.android.launcher3.util;
|
||||
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteException;
|
||||
import android.database.sqlite.SQLiteFullException;
|
||||
import android.database.sqlite.SQLiteOpenHelper;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* An extension of {@link SQLiteOpenHelper} with utility methods for a single table cache DB.
|
||||
* Any exception during write operations are ignored, and any version change causes a DB reset.
|
||||
*/
|
||||
public abstract class SQLiteCacheHelper {
|
||||
private static final String TAG = "SQLiteCacheHelper";
|
||||
|
||||
private final String mTableName;
|
||||
private final MySQLiteOpenHelper mOpenHelper;
|
||||
|
||||
private boolean mIgnoreWrites;
|
||||
|
||||
public SQLiteCacheHelper(Context context, String name, int version, String tableName) {
|
||||
mTableName = tableName;
|
||||
mOpenHelper = new MySQLiteOpenHelper(context, name, version);
|
||||
|
||||
mIgnoreWrites = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see SQLiteDatabase#update(String, ContentValues, String, String[])
|
||||
*/
|
||||
public void update(ContentValues values, String whereClause, String[] whereArgs) {
|
||||
if (mIgnoreWrites) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
mOpenHelper.getWritableDatabase().update(mTableName, values, whereClause, whereArgs);
|
||||
} catch (SQLiteFullException e) {
|
||||
onDiskFull(e);
|
||||
} catch (SQLiteException e) {
|
||||
Log.d(TAG, "Ignoring sqlite exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see SQLiteDatabase#delete(String, String, String[])
|
||||
*/
|
||||
public void delete(String whereClause, String[] whereArgs) {
|
||||
if (mIgnoreWrites) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
mOpenHelper.getWritableDatabase().delete(mTableName, whereClause, whereArgs);
|
||||
} catch (SQLiteFullException e) {
|
||||
onDiskFull(e);
|
||||
} catch (SQLiteException e) {
|
||||
Log.d(TAG, "Ignoring sqlite exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see SQLiteDatabase#insertWithOnConflict(String, String, ContentValues, int)
|
||||
*/
|
||||
public void insertOrReplace(ContentValues values) {
|
||||
if (mIgnoreWrites) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
mOpenHelper.getWritableDatabase().insertWithOnConflict(
|
||||
mTableName, null, values, SQLiteDatabase.CONFLICT_REPLACE);
|
||||
} catch (SQLiteFullException e) {
|
||||
onDiskFull(e);
|
||||
} catch (SQLiteException e) {
|
||||
Log.d(TAG, "Ignoring sqlite exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void onDiskFull(SQLiteFullException e) {
|
||||
Log.e(TAG, "Disk full, all write operations will be ignored", e);
|
||||
mIgnoreWrites = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see SQLiteDatabase#query(String, String[], String, String[], String, String, String)
|
||||
*/
|
||||
public Cursor query(String[] columns, String selection, String[] selectionArgs) {
|
||||
return mOpenHelper.getReadableDatabase().query(
|
||||
mTableName, columns, selection, selectionArgs, null, null, null);
|
||||
}
|
||||
|
||||
protected abstract void onCreateTable(SQLiteDatabase db);
|
||||
|
||||
/**
|
||||
* A private inner class to prevent direct DB access.
|
||||
*/
|
||||
private class MySQLiteOpenHelper extends SQLiteOpenHelper {
|
||||
|
||||
public MySQLiteOpenHelper(Context context, String name, int version) {
|
||||
super(context, name, null, version);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(SQLiteDatabase db) {
|
||||
onCreateTable(db);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
|
||||
if (oldVersion != newVersion) {
|
||||
clearDB(db);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
|
||||
if (oldVersion != newVersion) {
|
||||
clearDB(db);
|
||||
}
|
||||
}
|
||||
|
||||
private void clearDB(SQLiteDatabase db) {
|
||||
db.execSQL("DROP TABLE IF EXISTS " + mTableName);
|
||||
onCreate(db);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user