我讀了Christian Gruber的post,我開始想知道如何使用應用程序範圍的單例。
在我的應用程序中,我有一個類DBHelper
,其主要目的是持有我的數據庫的關鍵。我也有很多(至少兩個)不同的DAO。
現在 - 我沒有看到爲什麼我的幾個活動/類不僅僅需要一個DAO實例。更重要的是,爲什麼DAO只需要一個DBHelper
的實例?我非常肯定他們可以共享,特別是我不預測兩個DAO都希望同時對我的數據庫執行某些操作的情況。讓我們看看一些類:如何在Dagger 1.x中使用Singleton?
DBHelper
@Singleton public class DBHelper extends SQLiteOpenHelper { //some not relevant configuration stuff private Context context; @Inject public DBHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); this.context = context; } @Override public void onCreate(SQLiteDatabase db) { //db.execSQL, creating tables and stuff } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { //dropping tables, creating a new one onCreate(db); } }
例如
DAO
public interface SomeDataDAO { void hai(); } public class SomeDataDAOImpl implements SomeDataDAO { private DBHelper dbHelper; public SomeDataDAOImpl(DBHelper dbHelper){ this.dbHelper = dbHelper; } @Override public void hai() { SQLiteDatabase database = dbHelper.getWritableDatabase(); dbHelper.doSomeDatabaseStuff() } }
SomeDataModule
@Module( injects = { MainActivity.class, SomeServiceImpl.class } ) public class SomeDataModule { private Context appContext; @Provides @Singleton public SomeDataDAO provideSomeDataDao(DBHelper dbHelper){ return new SomeDataDAOImpl(dbHelper); } @Provides @Singleton public ISomeService provideSomeService(SomeServiceImpl impl){ return impl; } @Provides public Context getAppContext(){ return this.appContext; } public SomeDataModule(){ this.appContext = MainActivity.getAppContext(); } }
現在讓我們看看依賴消費者的兩個例子
public class MainActivity extends ActionBarActivity { @Inject SomeDataDAO someDataDAO; private ObjectGraph objectGraph; @Inject ISomeService someService; private static Context appContext; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); appContext = getApplicationContext(); objectGraph = ObjectGraph.create(SomeDataModule.class); objectGraph.inject(this); someService.doSomeStuff(); } public static Context getAppContext() { return appContext; } }
public class SomeServiceImpl implements ISomeService { private ObjectGraph objectGraph; @Inject public SomeDataDAO someDataDAO; public SomeServiceImpl(){ objectGraph = ObjectGraph.create(GraphDataModule.class); objectGraph.inject(this); } public void doSomeStuff(){ someDataDAO.hai(); } }
它的工作原理,但是當我inject(this)
兩次,匕首顯然創造了我的DBHelper
兩個實例,因爲它認爲「一個單一的圖形實例」。如何將SomeDataModule
包裝在ApplicationModule
中,因此我在整個應用程序中只有一個DBHelper
實例?不幸的是,將@Singleton
添加到DBHelper
是不夠的。
如果你必須去單身,爲什麼不使用靜態成員和方法全局類? – 2014-12-02 19:32:34
@KristyWelsh我正在學習Android&Dagger。即使在這種特殊情況下,具有靜態成員和方法的類可能會更好,但我想知道如何通過依賴注入實現我的目標,尤其是當我現在有一個非常簡單的示例時。順便說一句,它甚至是一個適當的設計模式?我不認爲我曾經遇到過這種方法。我遇到了帶有常量,SQL等靜態字段的類,但從未分發DAO。 – spoko 2014-12-02 20:43:13