My Note Pad

エンジニアリングや日々の雑感を書いていきます

Android学習(DI・DB編)

前回↓に引き続き、mixiのAndroidTrainingで時間を見つけてはAndroid開発について学んでいます。

yuki10.hatenablog.com

yuki10.hatenablog.com

今回は、2.基礎編 10.データベースの項です。

mixi-inc.github.io

RDBは仕事でも使うので、取っ付きやすい章でした。
せっかくなので、SQLiteOpenHelperではなくORMを利用してみることにしました。

Android用のORMは色々なライブラリが公開されていましたが、今回はAndroid Ormaを利用してみました!

GitHub - gfx/Android-Orma: A lightning-fast ORM for Android as a wrapper of SQLiteDatabase

また、作者の方が公開しているチュートリアルを参考にさせていただきました。

gfx.hatenablog.com

その中で、OrmaDatabaseクラスのインスタンスをDIで@Singletonをおすすめとの記述があったので、合わせてDagger2にも挑戦してみることにしました。
Dagger2については、こちらの記事を参考にさせていただきました。

Dagger2 導入Step By Step - Qiita

依存ライブラリ等の定義

プロジェクト直下のbuild.gradle

  • repositoryにmavenCentralを追加
  • dependenciesにaptの定義を設定
    repositories {
        jcenter()
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.1.0'
        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
    }

続いてプロジェクト/app下のbuild.gradleの依存関係に

  • Dagger2の定義を追加
  • Ormaの定義を追加

以下のような順に追記しました。

dependencies {
    ・・・
    compile 'com.google.dagger:dagger:2.0.2'
    apt 'com.google.dagger:dagger-compiler:2.0.2'
    provided 'javax.annotation:jsr250-api:1.0'

    apt 'com.github.gfx.android.orma:orma-processor:2.4.7'
    compile 'com.github.gfx.android.orma:orma:2.4.7'
}

Moduleクラスの作成

import部分等は省略していますが、こんな感じで作ってみました。
OrmaDatabaseもここで@Singletonで定義しています。

@Module
public class ApplicationModule {

    private final Application application;

    public ApplicationModule(Application application) {
        this.application = application;
    }

    @Provides
    @Singleton
    Context provideApplicationContext() {
        return application.getApplicationContext();
    }

    @Singleton
    @Provides
    public OrmaDatabase provideOrmaDataBase(Context context) {
        return OrmaDatabase.builder(context).build();
    }
}

ComponentInterfaceの作成

@Singleton
@Component(modules = ApplicationModule.class)
public interface ApplicationComponent {

    void inject(MainActivity mainActivity);
}

Applicationクラスの作成

public class MainApplication extends Application {

    private ApplicationComponent applicationComponent;

    @Override
    public void onCreate() {
        super.onCreate();
        initializeInjector();
    }

    private void initializeInjector() {
        applicationComponent = DaggerApplicationComponent.builder()
                .applicationModule(new ApplicationModule(this))
                .build();
    }

    public ApplicationComponent getApplicationComponent() {
        return applicationComponent;
    }
}

AndroidManifest.xmlにも忘れずに定義します。

    <application
        android:name=".MainApplication" ・・・>
        ・・・
    </application>

実際にDIしてみる

以下の様な感じでApplicationComponentを取得してinjectメソッドを実行することで、@Injectと定義しているormaにDIすることができました。

public class MainActivity extends AppCompatActivity {

    @Inject
    OrmaDatabase orma;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        getApplicationComponent().inject(this);
    }

    private ApplicationComponent getApplicationComponent() {
        return ((MainApplication) getApplication()).getApplicationComponent();
    }
}

Ormaを利用してDBを扱う

テーブルは課題に合わせて以下の様な感じで作りました。
アノテーションで属性等を定義できるので分かりやすいです。

@Table
public class AndroidCodeName {

    @PrimaryKey(autoincrement = true)
    public long id;

    @Column(indexed = true)
    public String name;

    @Column
    @Nullable
    public String version;

    public static AndroidCodeName_Relation relation(OrmaDatabase orma) {
        return orma.relationOfAndroidCodeName().orderByIdDesc();
    }
}

今回はinsertとselectだけ載せておきます。

insertはこんな感じ。

    private void insert() {
        AndroidCodeName androidCodeName = new AndroidCodeName();
        androidCodeName.name = appNameEditText.getText().toString();
        androidCodeName.version = appVersionEditText.getText().toString();

        orma.insertIntoAndroidCodeName(androidCodeName);

        Toast.makeText(MainActivity.this, "insert success", Toast.LENGTH_SHORT).show();
    }

さらにselect

    private void select() {

        AndroidCodeName_Relation relation = AndroidCodeName.relation(orma);

        // Relationを利用してデータを取得
        Log.d(TAG, "from Relation");
        for (AndroidCodeName androidCodeName :relation) {
            Log.d(TAG, androidCodeName.name + ":" + androidCodeName.version);
        }


        // Helper経由でデータを取得
        Log.d(TAG, "from Helper");
        AndroidCodeName_Selector selector = orma.selectFromAndroidCodeName()
                .orderByIdAsc();

        for (AndroidCodeName androidCodeName : selector) {
            Log.d(TAG, androidCodeName.name + ":" + androidCodeName.version);
        }
    }

今回はDaggerでOrmaDatabaseをDIする所を中心に挑戦してみましたが、OrmaがRxJava用のインターフェースを備えているようなので、RxJavaを絡めて学んでみたいなと思います。
※RxJavaも触ったことがありません。。

Android開発者は今から始めると学ぶことが多いですね。。