Skip to content

Commit eb43a33

Browse files
committed
Removed memory leakage by deleting static context from Builder
1 parent 42b5339 commit eb43a33

4 files changed

Lines changed: 53 additions & 39 deletions

File tree

app/src/main/java/com/demoapp/MainActivity.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ protected void onCreate(Bundle savedInstanceState) {
4545
userModel.fullname = "First Last name";
4646
userModel.age = 12;
4747

48+
userModel.delete();
4849
//SQLiteManager.getInstance().insert(userModel);
4950

5051
//Inserting it to the table
@@ -172,7 +173,7 @@ protected void onCreate(Bundle savedInstanceState) {
172173
.innerJoin("carId")
173174
.columns("cars.id", "drivers.fullname", "cars.release_date", "drivers.id")
174175
.getCursor();
175-
//
176+
176177
// String[] names = cursor.getColumnNames();
177178
// if (cursor.moveToFirst()) {
178179
// do {

sqlitemanager/src/main/java/com/sqlitemanager/AbstractTableModel.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public long update() {
1515
}
1616

1717
public long delete() {
18-
return -1;
18+
return SQLiteManager.delete(this);
1919
}
2020

2121
@Override

sqlitemanager/src/main/java/com/sqlitemanager/SQLiteManager.java

Lines changed: 47 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
import android.content.ContentValues;
55
import android.content.Context;
6+
import android.content.res.Configuration;
67
import android.database.Cursor;
78
import android.database.sqlite.SQLiteDatabase;
89
import android.database.sqlite.SQLiteOpenHelper;
@@ -36,7 +37,6 @@
3637
import java.util.List;
3738
import java.util.Locale;
3839

39-
4040
/**
4141
* Created by aslan on 5/10/2017.
4242
*/
@@ -45,10 +45,9 @@ public class SQLiteManager extends SQLiteOpenHelper {
4545

4646
protected final static String TAG = "SQLiteManager";
4747

48+
//Todo: this is a serious problem. Solve it! HINT: https://github.com/prashantsolanki3/Secure-Pref-Manager/blob/master/secureprefs/src/main/java/com/prashantsolanki/secureprefmanager/SecurePrefManagerInit.java
4849
private static SQLiteManager sqLiteManager = null;
4950

50-
//TODO: Replace ArrayLists with Arrays or Lists as much as possible for the sake of efficiency;
51-
5251
private ArrayList<Class> tableTypesList;
5352

5453
private ArrayList<TableModel> databaseTables = new ArrayList<>();
@@ -57,20 +56,23 @@ public class SQLiteManager extends SQLiteOpenHelper {
5756

5857
private ArrayList<String> tablesNames = new ArrayList<>();
5958

60-
private Context context;
59+
private String databaseName;
60+
private int databaseVersion;
6161

62-
private Builder builder;
6362

6463
private boolean willBeUpdated;
6564

65+
//Todo: Wright test cases for all methods!
66+
6667
private SQLiteManager(Builder builder) {
6768
super(builder.context, builder.databaseName, null, builder.databaseVersion);
6869
Log.i("Database operations", "Database created or opened...");
69-
this.builder = builder;
70-
tableTypesList = builder.classes;
71-
context = builder.context;
7270

71+
databaseName = builder.databaseName;
72+
databaseVersion = builder.databaseVersion;
73+
tableTypesList = builder.classes;
7374
willBeUpdated = builder.willBeUpdated;
75+
7476
findAllAnnotatedFields();
7577
}
7678

@@ -134,13 +136,19 @@ private void prepareCreateTablesQueryStr() {
134136
}
135137
}
136138

137-
public static void deleteDatabase() {
138-
sqLiteManager.context.deleteDatabase(sqLiteManager.getDatabaseName());
139+
public static void deleteDatabase(Context context) {
140+
context.deleteDatabase(sqLiteManager.getDatabaseName());
139141
}
140142

141-
public static void refreshDatabase() {
142-
deleteDatabase();
143-
sqLiteManager = new SQLiteManager(sqLiteManager.builder);
143+
public static void refreshDatabase(Context context) {
144+
deleteDatabase(context);
145+
SQLiteManager.Builder newBuilder = new SQLiteManager.Builder(context)
146+
.setDBName(sqLiteManager.databaseName)
147+
.setDBVersion(sqLiteManager.databaseVersion)
148+
.setWillBeUpdated(sqLiteManager.willBeUpdated)
149+
.setTableList(sqLiteManager.tableTypesList.toArray(new Class[sqLiteManager.tableTypesList.size()]));
150+
151+
sqLiteManager = new SQLiteManager(newBuilder);
144152
}
145153

146154
private void findAllAnnotatedFields() {
@@ -379,12 +387,6 @@ public int compare(Field field, Field t1) {
379387
}
380388
}
381389

382-
public <T extends Tableable> SqlResponse delete(T tableModel) {
383-
String tableName = Utils.getTableName(tableModel.getClass());
384-
sqLiteManager.getWritableDatabase().delete(tableName, "?=?", new String[]{"1", "jack"});
385-
return SqlResponse.Successful;
386-
}
387-
388390
//TODO: Make it compatible with several foreign key!
389391
private String getStringForeignKey(String columnWithForeignKey, String mainTableName) {
390392
String refColName = "";
@@ -416,7 +418,8 @@ public static <T extends Tableable> ArrayList<T> all(Class<T> modelClass) {
416418

417419
private Cursor selectManyCursor(String name, String[] args,
418420
String condition, SortOrder sortOrder,
419-
Integer limit, String columnWithForeignKey, String[] columns, String sortColumn) {
421+
Integer limit, String columnWithForeignKey,
422+
String[] columns, String sortColumn) {
420423

421424
SQLiteDatabase sqLiteDatabase = sqLiteManager.getReadableDatabase();
422425
String foreignKey = (columnWithForeignKey != null && !columnWithForeignKey.isEmpty()) ? getStringForeignKey(columnWithForeignKey, name) : "";
@@ -509,7 +512,7 @@ public int compare(Field field, Field t1) {
509512
for (final Field field : fields) {
510513
String simpleNameOfDataType = field.getType().getSimpleName();
511514

512-
SqlResponse result = Utils.readingSwitchAction(simpleNameOfDataType, field, tableModel, index, cursor, new AbstractDefaultCase() {
515+
long result = Utils.readingSwitchAction(simpleNameOfDataType, field, tableModel, index, cursor, new AbstractDefaultCase() {
513516
@Override
514517
public void onDefault(Field field, int indexx, Cursor cursorr) {
515518
try {
@@ -519,7 +522,7 @@ public void onDefault(Field field, int indexx, Cursor cursorr) {
519522
}
520523
}
521524
});
522-
if (result == SqlResponse.Failed) continue;
525+
if (result == -1) continue;
523526
index++;
524527
}
525528
tableModels.add(tableModel);
@@ -542,19 +545,17 @@ public static <T extends Tableable> SqlResponse deleteTable(Class<T> tableClass)
542545
return deleteTable(Utils.getTableName(tableClass));
543546
}
544547

545-
public static SqlResponse clearTableData(String tableName) {
548+
public static long clearTableData(String tableName) {
546549
long result;
547550
if (Utils.tableExist(tableName))
548-
result = sqLiteManager.getWritableDatabase().delete(tableName, "1=1", null);
551+
result = sqLiteManager.getWritableDatabase().delete(tableName, "1", null);
549552
else
550-
return SqlResponse.TableNotExist;
553+
return -1;
551554

552-
if (result > 0)
553-
return SqlResponse.Successful;
554-
return SqlResponse.Failed;
555+
return result;
555556
}
556557

557-
public static <T extends Tableable> SqlResponse clearTableData(Class<T> tableClass) {
558+
public static <T extends Tableable> long clearTableData(Class<T> tableClass) {
558559
return clearTableData(Utils.getTableName(tableClass));
559560
}
560561

@@ -589,7 +590,6 @@ public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
589590

590591
//TODO: Name this as QueryBuilder
591592
public static class Select {
592-
593593
private Class tableClass;
594594
private String tableName;
595595
private String[] args;
@@ -703,7 +703,6 @@ public Builder setWillBeUpdated(boolean willBeUpdated) {
703703
}
704704
}
705705

706-
707706
static <T extends Tableable> int update(T tableModel) {
708707
SQLiteDatabase writable = sqLiteManager.getWritableDatabase();
709708
String whereClause = null;
@@ -737,7 +736,6 @@ static <T extends Tableable> int update(T tableModel) {
737736
return writable.updateWithOnConflict(Utils.getTableName(tableModel.getClass()), contentValues, whereClause, whereArgs, SQLiteDatabase.CONFLICT_IGNORE);
738737
}
739738

740-
741739
public static <T extends Tableable> T find(Class<T> clazz, Integer id) {
742740
try {
743741
return find(clazz.newInstance(), id);
@@ -785,7 +783,7 @@ public int compare(Field field, Field t1) {
785783
for (final Field field : fields) {
786784
String simpleNameOfDataType = field.getType().getSimpleName();
787785

788-
SqlResponse response = Utils.readingSwitchAction(simpleNameOfDataType, field, tableModel, index, cursor, new AbstractDefaultCase() {
786+
long response = Utils.readingSwitchAction(simpleNameOfDataType, field, tableModel, index, cursor, new AbstractDefaultCase() {
789787
@Override
790788
public void onDefault(Field field, int indexx, Cursor cursorr) {
791789

@@ -796,7 +794,7 @@ public void onDefault(Field field, int indexx, Cursor cursorr) {
796794
}
797795
}
798796
});
799-
if (response == SqlResponse.Failed) continue;
797+
if (response == -1) continue;
800798
index++;
801799
}
802800
cursor.close();
@@ -805,4 +803,19 @@ public void onDefault(Field field, int indexx, Cursor cursorr) {
805803
cursor.close();
806804
return tableModel;
807805
}
806+
807+
static <T extends Tableable> long delete(T tableModel) {
808+
String tableName = Utils.getTableName(tableModel.getClass());
809+
Field field = Utils.getPrimaryKeyField(tableModel.getClass());
810+
if (field == null)
811+
throw new SqLiteManagerException("No primary key found in table " + tableName.getClass().getSimpleName());
812+
String prmrKeyFieldName = field.getName();
813+
long result;
814+
try {
815+
result = sqLiteManager.getWritableDatabase().delete(tableName, prmrKeyFieldName + "=?", new String[]{field.get(tableModel).toString()});
816+
} catch (Exception e) {
817+
throw new SqLiteManagerException(e.getMessage());
818+
}
819+
return result;
820+
}
808821
}

sqlitemanager/src/main/java/com/sqlitemanager/Utils.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,8 @@ static Field getPrimaryKeyField(Class clazz) {
6363
return null;
6464
}
6565

66-
static <T extends Tableable> SqlResponse readingSwitchAction(String simpleNameOfDataType, final Field field, T tableModel, int index, Cursor cursor, AbstractDefaultCase defaultCase) {
67-
if (!field.isAnnotationPresent(Column.class)) return SqlResponse.Failed;
66+
static <T extends Tableable> long readingSwitchAction(String simpleNameOfDataType, final Field field, T tableModel, int index, Cursor cursor, AbstractDefaultCase defaultCase) {
67+
if (!field.isAnnotationPresent(Column.class)) return -1;
6868

6969

7070
try {
@@ -123,7 +123,7 @@ static <T extends Tableable> SqlResponse readingSwitchAction(String simpleNameOf
123123
} catch (Exception e) {
124124
Log.e(TAG, e.getMessage());
125125
}
126-
return SqlResponse.Successful;
126+
return 1;
127127
}
128128

129129
static boolean isColumn(Field field) {

0 commit comments

Comments
 (0)