2016-04-08 10 views
0

私はアンドロイドにSqliteHelperのための適切なシングルトンアクセスを書き留めようとしました。私はここで何かを逃しているかどうかはわからないが、最終版を形成するためにここやそこからビットと作品を得た。これはアンドロイドのSqliteHelperのシングルトンを行う正しい方法ですか?

public class DatabaseHelper extends SQLiteOpenHelper { 

    private static final String DATABASE_NAME = "EffiaSoft"; 
    private static final int DATABASE_VERSION = 1; 
    private static SQLiteOpenHelper sInstance; 
    private Semaphore semaphore = new Semaphore(1); 
    private Context mCxt; 

    /** 
    * Constructor should be private to prevent direct instantiation. 
    * make call to static method "getInstance()" instead. 
    */ 
    private DatabaseHelper(Context context) { 
     super(context, DATABASE_NAME, null, DATABASE_VERSION); 
     this.mCxt = context; 
    } 

    public static synchronized SQLiteOpenHelper getInstance(Context context) { 
     if (sInstance == null) { 
      sInstance = new DatabaseHelper(context.getApplicationContext()); 
     } 
     return sInstance; 
    } 

    private static <T> void setFields(Cursor cursor, T returnObject, Field[] declaredFields, String[] cursorColumns) throws IllegalAccessException { 
     for (Field declaredField : declaredFields) { 
      String fieldName = declaredField.getName(); 
      boolean hasColumn = false; 
      for (String columnName : cursorColumns) { 
       if (columnName.equals(fieldName)) 
        hasColumn = true; 
       else 
        continue; 
       break; 
      } 
      if (hasColumn) { 
       declaredField.setAccessible(true); 
       int columnIndex = cursor.getColumnIndex(fieldName); 
       if (columnIndex >= 0) { 
        if (declaredField.getType() == Character.TYPE) { 
         String value = cursor.getString(columnIndex); 
         if (!ValidationHelper.isNullOrEmpty(value) && value.length() == 1) { 
          char c = value.charAt(0); 
          declaredField.set(returnObject, c); 
         } 
        } else if (declaredField.getType() == Short.TYPE) { 
         declaredField.set(returnObject, cursor.getShort(columnIndex)); 
        } else if (declaredField.getType() == Integer.TYPE) { 
         declaredField.set(returnObject, cursor.getInt(columnIndex)); 
        } else if (declaredField.getType() == Long.TYPE) { 
         declaredField.set(returnObject, cursor.getLong(columnIndex)); 
        } else if (declaredField.getType() == Float.TYPE) { 
         declaredField.set(returnObject, cursor.getFloat(columnIndex)); 
        } else if (declaredField.getType() == Double.TYPE) { 
         declaredField.set(returnObject, cursor.getDouble(columnIndex)); 
        } else if (declaredField.getType() == Boolean.TYPE) { 
         String temp = cursor.getString(columnIndex); 
         declaredField.setBoolean(returnObject, temp.equalsIgnoreCase("Y")); 
        } else if (Date.class.equals(declaredField.getType())) { 
         if (!ValidationHelper.isNullOrEmpty(cursor.getString(columnIndex))) { 
          Date date = ValueFormatter.formatDateTime(cursor.getString(columnIndex)); 
          declaredField.set(returnObject, date); 
         } 
        } else if (BigDecimal.class.equals(declaredField.getType())) { 
         declaredField.set(returnObject, BigDecimal.valueOf(cursor.getDouble(columnIndex))); 
        } else { 
         declaredField.set(returnObject, cursor.getString(columnIndex)); 
        } 
       } 
      } 

     } 
    } 

    private void Disconnect() { 
     semaphore.release(); 
    } 

    private void Connect() { 
     try { 
      semaphore.acquire(); 
     } catch (InterruptedException e) { 
      LogHelper.writeExceptionLog(e); 
     } 
    } 

    @Override 
    public void onCreate(SQLiteDatabase db) { 

    } 

    public <T> ArrayList<T> getData(Context context, String tableName, String columnName, String filterCondition, String orderBy, 
            String groupBy, Class<T> type, SQLiteDatabase database) { 

     Connect(); 
     ArrayList<T> arrayList = null; 
     try { 
      if (context != null && !ValidationHelper.isNullOrEmpty(tableName)) { 
       SQLiteDatabase db; 
       if (database == null) { 
        db = getWritableDatabase(); 
       } else 
        db = database; 
       arrayList = new ArrayList<>(); 
       if (db != null) { 
        StringBuilder selectQuery = new StringBuilder(); 
        selectQuery.append("SELECT "); 
        if (columnName != null && columnName.length() > 0) 
         selectQuery.append(columnName); 
        else 
         selectQuery.append("*"); 
        selectQuery.append(" FROM "); 
        selectQuery.append(tableName); 
        if (!ValidationHelper.isNullOrEmpty(filterCondition)) { 
         selectQuery.append(" WHERE "); 
         selectQuery.append(filterCondition); 
        } 
        if (!ValidationHelper.isNullOrEmpty(orderBy)) { 
         selectQuery.append(" ORDER BY "); 
         selectQuery.append(orderBy); 
        } 
        if (!ValidationHelper.isNullOrEmpty(groupBy)) { 
         selectQuery.append(" GROUP BY "); 
         selectQuery.append(groupBy); 
        } 
        Cursor cursor; 
        cursor = db.rawQuery(selectQuery.toString(), null); 
        if (cursor != null) { 
         String[] cursorColumn = cursor.getColumnNames(); 
         if (cursor.moveToFirst()) { 
          do { 
           T returnObject = type.newInstance(); 
           Class<?> returnClass = returnObject.getClass(); 
           if (!returnClass.getSuperclass().equals(Object.class)) { 
            setFields(cursor, returnObject, returnClass.getSuperclass().getDeclaredFields(), cursorColumn); 
           } 
           setFields(cursor, returnObject, returnClass.getDeclaredFields(), cursorColumn); 
           arrayList.add(returnObject); 
          } while (cursor.moveToNext()); 
         } 

        } 
       } 
      } 
     } catch (Exception e) { 
      LogHelper.writeExceptionLog(e); 
     } finally { 
      Disconnect(); 
     } 
     return arrayList; 
    } 

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

    } 

    @Override 
    protected void finalize() throws Throwable { 
     this.close(); 
     super.finalize(); 
     Disconnect(); 
    } 
} 
+1

:あなたの活動で

private static DatabaseHelper mInstance = null; public static DatabaseHelper getInstance(Context context) { if (mInstance == null) { mInstance = new DatabaseHelper(context); } return mInstance; } 

'getInstance(コンテキスト)'。別のパラメータで呼び出すとどうなりますか?常に、そのパラメータに適したインスタンスを取り戻す必要があります。なぜこれが本当にシングルトンである必要があるのか​​自分に尋ねます。 –

+0

私たちはトランザクションを使って極端にマルチスレッド化されたアクセスを持っています。非常に多くの場合、 'すでに閉じられたデータベースを開くことができません。 –

+0

このシングルトン[シングルトンパターン]のいずれかを試してください(http://stackoverflow.com/a/22497718/3436179) – Alexander

答えて

0

あなたはこのように定義する必要があります。あなたがそうであるようにパラメータに基づいて、単一のインスタンスをキャッシュすることは適切ではありません

DatabaseHelper db = DatabaseHelper.getInstance(context); 
+1

さらに、database = getWritableDatabase()を定義する必要があります。あなたのコンストラクタで。 –

+1

は 'context.getApplicationContext())'でなければなりません。なぜなら、contextは後でもう存在しないアクティビティかもしれないからです。 ApplicationContextはアクティビティのライブサイクルを生き延びます – k3b

+0

私はDatabaseHelperのインスタンスを作成した後、コンテキストがdatabasehelperに属し、アクティビティに関係しないと考えています –

関連する問題