8

ORMLite を使用して Android プロジェクトをセットアップしようとしています。DI には Roboguice を使用しています。ここで私の質問は、ここにいる誰かがそれらを一緒に機能させるのを助けることができるかどうかです.

拡張するヘルパー クラスをセットアップしましたOrmLiteSqliteOpenHelper。今、正しいDAOクラスを注入する方法を考えています。

一般的なベストプラクティスは素晴らしいでしょう。Roboguice で処理する必要があるため、使用OrmLiteBaseActivityは実際には適用されません。質問は次のとおりです。どのように?

助け、あなたの経験、ベストプラクティスなどをいただければ幸いです。

4

4 に答える 4

12

OrmLiteBaseActivity から拡張している場合、 RoboActivityから拡張することはできません。以下を呼び出して (roboguice 1.1 を想定)、非ロボアクティビティ アクティビティにインジェクションを実行するだけです。

((InjectorProvider)getApplicationContext()).getInjector().injectMembers(this)

それができたら、dao オブジェクトのインジェクションを実行できます。

DAO を注入するには、SystemServiceProvider によって確立されたパターン ( classbindings ) に従うことをお勧めします。したがって、次のような DaoProvider を実装します。

class DaoProvider<T> implements Provider<T> {
    protected ConnectionSource conn;
    protected Class<T> clazz;

    public DaoProvider( ConnectionSource conn, Class<T> clazz ) {
        this.conn = conn;
        this.clazz = clazz;
    }

    @Override
    public T get() {
        return DaoManager.createDao( conn, clazz  );
    }
}

バインディングを提供します。注入する DAO タイプごとに 1 つ実行する必要があります。

bind(MyDaoObjectType.class).toProvider(
      new DaoProvider<MyDaoObjectType>(conn,MyDaoObjectType.class));

次に、それをアクティビティまたは他の場所に挿入できます。

@Inject MyDaoObjectType myDaoObjectType;
于 2011-04-25T17:31:30.810 に答える
3

私はこれと同じ問題を抱えており、最終的に OrmLiteActivityListener を作成して、RoboActivity をリッスンし、発生するイベントを処理しました。

public class RoboOrmActivityBase<H extends IOrmLiteSqliteOpenHelper> extends RoboActivity {
@Inject RoboOrmLiteActivityListener<H> OrmActivityListener;

/*
 * Get a helper for this action.
 */
public H getHelper() {
    return OrmActivityListener.getHelper();
}

/**
 * Get a connection source for this action.
 */
public ConnectionSource getConnectionSource() {
    return OrmActivityListener.getHelper().getConnectionSource();
}
}

RoboOrmLiteActivityListener クラスは OrmLiteActivityBase クラスから派生しました。その継承を削除し、代わりにリッスンしました。

public class RoboOrmLiteActivityListener<H extends IOrmLiteSqliteOpenHelper> {
private volatile H helper;
private volatile boolean created = false;
private volatile boolean destroyed = false;

OrmLiteSqliteOpenHelperProvider databaseHelperProvider;

@Inject
public RoboOrmLiteActivityListener(OrmLiteSqliteOpenHelperProvider databaseHelperProvider) {
    this.databaseHelperProvider = databaseHelperProvider;
}

/**
 * Get a helper for this action.
 */
public H getHelper() {
    if (helper == null) {
        if (!created) {
            throw new IllegalStateException("A call has not been made to onCreate() yet so the helper is null");
        } else if (destroyed) {
            throw new IllegalStateException(
                    "A call to onDestroy has already been made and the helper cannot be used after that point");
        } else {
            throw new IllegalStateException("Helper is null for some unknown reason");
        }
    } else {
        return helper;
    }
}

/**
 * Get a connection source for this action.
 */
public ConnectionSource getConnectionSource() {
    return getHelper().getConnectionSource();
}

// As you might expect, some events can have parameters.  The OnCreate event
// has the savedInstanceState parameter that Android passes to onCreate(Bundle)   
public void onCreate(@Observes OnCreateEvent onCreate) {
    //Ln.d("onCreate savedInstanceState is %s", onCreate.getSavedInstanceState())
    if (helper == null) {
        helper = getHelperInternal();
        created = true;
    }
}

public void onDestroy(@Observes OnDestroyEvent onDestroy) {
    releaseHelper(helper);
    destroyed = true;
}

/**
 * This is called internally by the class to populate the helper object instance. This should not be called directly
 * by client code unless you know what you are doing. Use {@link #getHelper()} to get a helper instance. If you are
 * managing your own helper creation, override this method to supply this activity with a helper instance.
 * 
 * <p>
 * <b> NOTE: </b> If you override this method, you most likely will need to override the
 * {@link #releaseHelper(OrmLiteSqliteOpenHelper)} method as well.
 * </p>
 */
private H getHelperInternal() {
    @SuppressWarnings("unchecked")
    H newHelper = (H) databaseHelperProvider.get();
    return newHelper;
}

/**
 * Release the helper instance created in {@link #getHelperInternal(Context)}. You most likely will not need to call
 * this directly since {@link #onDestroy()} does it for you.
 * 
 * <p>
 * <b> NOTE: </b> If you override this method, you most likely will need to override the
 * {@link #getHelperInternal(Context)} method as well.
 * </p>
 */
private void releaseHelper(H helper) {
    OpenHelperManager.releaseHelper();
    helper = null;
}
}

次に、OrmLiteSqliteOpenHelper から拡張されたヘルパーを提供する DatabaseHelperProvider があります。このプロバイダーは、OpenHelperManager からヘルパーを取得した後、手動でヘルパーにインジェクションを実行します。

public class OrmLiteSqliteOpenHelperProvider implements Provider<OrmLiteSqliteOpenHelper> {
  private final Context context;
  private final Injector injector;

  @Inject
  public OrmLiteSqliteOpenHelperProvider(Context context, Injector injector) {
      this.context=context;
      this.injector=injector;
  }
  public OrmLiteSqliteOpenHelper get() {
      //The OpenHelperManager built the DatabaseHelper, not us.  So we need to guice it up manually.  
      //Guice normally does its injections when it does its constructions. 
    OrmLiteSqliteOpenHelper dbhelp = OpenHelperManager.getHelper(context);
      injector.injectMembers(dbhelp);
    return dbhelp;
  }
}

OrmLiteSqliteOpenHelper から抽出されたメンバーを含む IOrmLiteSqliteOpenHelper というインターフェイスもあります。次に、OrmLiteSqliteOpenHelper から派生したヘルパー用のインターフェイス (IDatabaseHelper) を構築すると、IOrmLiteSqliteOpenHelper から拡張できます。

次に、私が持っているモジュールにバインドします

static {
    OpenHelperManager.setOpenHelperClass(DatabaseHelper.class);
}

@SuppressWarnings("unchecked")
private void bindDataHelperProvider() {
    bind(IDatabaseHelper.class)
    .toProvider((Class<? extends Provider<? extends IDatabaseHelper>>) OrmLiteSqliteOpenHelperProvider.class);
}

次に、私のアクティビティには、RoboGuice と Ormlite のすべてが基本クラスで完全に処理され、次のようになります。

public class MyActivity extends RoboOrmActivityBase<IDatabaseHelper> {

    List<IMyEntity> lis;

@Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    setContentView(R.layout.routine);

    try {
        Dao<IMyEntity,Integer> myDao = getHelper().getMyDao();
        lis = myDao.queryForAll();
于 2011-05-29T12:36:50.293 に答える
1

これは、私が思いついた解決策だけのベストプラクティスではありません。

改善のためにメモを残してください。

ここでは例として UserLocation エンティティを使用しています SqliteOpenHelper と Dao をシングルトンとしてバインドするには、これをモジュール構成に追加しました。

bind(new TypeLiteral<SqliteOpenHelper>(){}).toProvider(OrmLiteSqliteOpenHelperProvider.class).in(Singleton.class);
bind(new TypeLiteral<Dao<UserLocation, Integer>>(){}).toProvider(DaoUserLocationProvider.class).in(Singleton.class);

OrmLiteSqliteOpenHelperProvider は次のようになります。

public class OrmLiteSqliteOpenHelperProvider implements Provider<SqliteOpenHelper>
{
    @Inject Context context;

    @Override
    public SqliteOpenHelper get() {
        return (SqliteOpenHelper) OpenHelperManager.getHelper(context);
    }
}

DaoUserLocationProvider は次のようになります。

public class DaoUserLocationProvider implements Provider<Dao<UserLocation, Integer>>
{
    @Inject SqliteOpenHelper sqliteOpenHelper;

    @Override
    public Dao<UserLocation, Integer> get() {
        try {
            return sqliteOpenHelper.getUserLocationDao();
        } catch (SQLException e) {
            Ln.e(e);
        }
        return null;
    }
}

これで、Dao リークに次のように注入できます。

@Inject private Dao<UserLocation, Integer> userLocationDao;

そうすれば、roboguice アクティビティを使い続けることができ、SqliteOpenHelper は roboguice によってシングルトンとして保持されます。

しかし、破壊/解放に関する問題は残っています。OrmLiteBaseActivity の内容をコピーして貼り付けて、RoboActivity を拡張したくなります。ご意見はありますか?

于 2011-04-28T03:40:44.490 に答える
0

http://abdennour-insat.blogspot.com/2012/10/using-ormlite-for-sqlite-with-android.html

このチュートリアルに従うことができます。

チュートリアルの冒頭で述べた多重継承を避けるために、特定のソフトウェア アーキテクチャを使用しました。

ormliteを拡張したクラス

OrmliteActivity .しかし、GreenDroidを使用する場合

,アクティビティは GDActivity を拡張する必要があります。

残念ながら、Java は複数をサポートしていません。

継承、つまり、JAVA クラスは継承できるのは 1 つだけです。

スーパークラス最大。

于 2012-10-28T11:19:23.667 に答える