Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ dependencies {
testCompile 'junit:junit:4.12'

// for data binding
kapt 'com.android.databinding:compiler:3.0.0'
kapt 'com.android.databinding:compiler:3.0.1'

// for dagger2
compile "com.google.dagger:dagger:2.12"
Expand All @@ -49,6 +49,14 @@ dependencies {
compile "com.github.gfx.android.orma:orma:4.2.5"
kapt "com.github.gfx.android.orma:orma-processor:4.2.5"

// for Retrofit2
compile 'com.squareup.retrofit2:retrofit:2.3.0'
compile 'com.squareup.retrofit2:converter-gson:2.3.0'
compile 'com.squareup.okhttp3:logging-interceptor:3.8.1'

// RxJava/RxAndroid
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
compile 'io.reactivex.rxjava2:rxjava:2.1.6'

}

Expand Down
12 changes: 11 additions & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="jp.chau2chaun2.kotlindatabindingsample">

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

<application
android:name=".CustomApplication"
android:allowBackup="true"
Expand All @@ -10,20 +13,27 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">

<activity android:name=".view.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<activity
android:name=".view.BMICalculateActivity"
android:windowSoftInputMode="adjustResize"/>

<activity
android:name=".view.BMIRealtimeCalculateActivity"
android:windowSoftInputMode="adjustResize"/>

<activity android:name=".view.BMIListActivity" />

<activity android:name=".view.RandomUserListActivity" />

</application>

</manifest>
</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package jp.chau2chaun2.kotlindatabindingsample.dao

import com.github.gfx.android.orma.SingleAssociation
import jp.chau2chaun2.kotlindatabindingsample.model.orma.Name_Relation
import jp.chau2chaun2.kotlindatabindingsample.model.orma.OrmaDatabase
import jp.chau2chaun2.kotlindatabindingsample.model.orma.RandomUser
import javax.inject.Inject

class NameDao @Inject constructor(private val ormaDatabase: OrmaDatabase) {

val relation: Name_Relation = ormaDatabase.relationOfName()

fun insert(randomUser: RandomUser) {
randomUser.results.forEach { result ->
result.serializedName?.let { name ->
relation.inserter().execute(name).also {
name.id = it
result.name = SingleAssociation.just(it)
}
}
}
}

fun deleteAll(): Int = relation.deleter().execute()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package jp.chau2chaun2.kotlindatabindingsample.dao

import jp.chau2chaun2.kotlindatabindingsample.model.orma.OrmaDatabase
import jp.chau2chaun2.kotlindatabindingsample.model.orma.RandomUser
import jp.chau2chaun2.kotlindatabindingsample.model.orma.Result_Relation
import javax.inject.Inject

/**
* Equals User Dao actually.
*/
class ResultDao @Inject constructor(private val ormaDatabase: OrmaDatabase) {

val relation: Result_Relation = ormaDatabase.relationOfResult()

fun insert(randomUser: RandomUser) {
randomUser.results.forEach { result ->
relation.inserter().execute(result).also { result.id = it }
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import dagger.Subcomponent
import jp.chau2chaun2.kotlindatabindingsample.view.BMICalculateActivity
import jp.chau2chaun2.kotlindatabindingsample.view.BMIListActivity
import jp.chau2chaun2.kotlindatabindingsample.view.BMIRealtimeCalculateActivity
import jp.chau2chaun2.kotlindatabindingsample.view.RandomUserListActivity

@ActivityScope
@Subcomponent(modules = arrayOf(ActivityModule::class))
Expand All @@ -14,4 +15,6 @@ interface ActivityComponent {
fun inject(activity: BMICalculateActivity)

fun inject(activity: BMIListActivity)

fun inject(activity: RandomUserListActivity)
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ import com.github.gfx.android.orma.AccessThreadConstraint
import dagger.Module
import dagger.Provides
import jp.chau2chaun2.kotlindatabindingsample.model.orma.OrmaDatabase
import jp.chau2chaun2.kotlindatabindingsample.net.ApiService
import jp.chau2chaun2.kotlindatabindingsample.net.IApiService
import javax.inject.Singleton

@Module
@Module(includes = arrayOf(ClientModule::class))
class AppModule(private val mContext: Context) {

@Provides
Expand All @@ -36,4 +38,10 @@ class AppModule(private val mContext: Context) {
.readOnMainThread(AccessThreadConstraint.NONE)
.build()
}

@Singleton
@Provides
internal fun providesApiService(): IApiService {
return ApiService().service
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package jp.chau2chaun2.kotlindatabindingsample.di

import dagger.Binds
import dagger.Module
import jp.chau2chaun2.kotlindatabindingsample.net.client.ApiRandomUserClient
import jp.chau2chaun2.kotlindatabindingsample.net.client.IApiRandomUser

@Module
interface ClientModule {
@Binds fun bindApiService(client: ApiRandomUserClient): IApiRandomUser
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package jp.chau2chaun2.kotlindatabindingsample.model.orma

import com.github.gfx.android.orma.SingleAssociation
import com.github.gfx.android.orma.annotation.Column
import com.github.gfx.android.orma.annotation.PrimaryKey
import com.github.gfx.android.orma.annotation.Table
import com.google.gson.annotations.SerializedName

data class RandomUser(val info: Info,
val results: List<Result>)

data class Info(val seed: String,
val results: Int,
val page: Int,
val version: String)

@Table("user")
class Result {

@PrimaryKey
@Transient
var id: Long = 0

@Column lateinit var gender: String

@Column lateinit var email: String

@Column lateinit var registered: String

@Column lateinit var dob: String

@Column lateinit var phone: String

@Column lateinit var cell: String

@Column lateinit var nat: String

@SerializedName("name")
var serializedName: Name? = null

@Column
@Transient
var name: SingleAssociation<Name> = SingleAssociation.just(0)
}

@Table("name")
class Name {

@PrimaryKey
@Transient
var id: Long = 0

@Column lateinit var first: String

@Column lateinit var last: String

@Column lateinit var title: String
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package jp.chau2chaun2.kotlindatabindingsample.net

import com.google.gson.GsonBuilder
import jp.chau2chaun2.kotlindatabindingsample.model.orma.RandomUser
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Call
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.http.GET
import java.util.concurrent.TimeUnit



class ApiService {

// core for controller
val service: IApiService = create(IApiService::class.java)

lateinit var retrofit: Retrofit

fun <S> create(serviceClass: Class<S>): S {
val gson = GsonBuilder()
.serializeNulls()
.create()

// create retrofit
retrofit = Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create(gson))
.baseUrl("http://randomuser.me/")
.client(httpBuilder.build())
.build()

return retrofit.create(serviceClass)
}

val httpBuilder: OkHttpClient.Builder get() {
// create http client
val httpClient = OkHttpClient.Builder()
.addInterceptor(Interceptor { chain ->
val original = chain.request()

//header
val request = original.newBuilder()
.header("Accept", "application/json")
.method(original.method(), original.body())
.build()

return@Interceptor chain.proceed(request)
})
.readTimeout(30, TimeUnit.SECONDS)

// log interceptor
val loggingInterceptor = HttpLoggingInterceptor()
loggingInterceptor.level = HttpLoggingInterceptor.Level.BODY
httpClient.addInterceptor(loggingInterceptor)

return httpClient
}
}

interface IApiService {
@GET("api")
fun apiDemo(): Call<RandomUser>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package jp.chau2chaun2.kotlindatabindingsample.net.client

import android.accounts.NetworkErrorException
import io.reactivex.Observable
import io.reactivex.Single
import jp.chau2chaun2.kotlindatabindingsample.model.orma.RandomUser
import jp.chau2chaun2.kotlindatabindingsample.net.IApiService
import javax.inject.Inject

interface IApiRandomUser {
fun getRandomUser(): Single<RandomUser>
fun getRandomUser(numberOfUsers: Int): Observable<RandomUser>
}

class ApiRandomUserClient @Inject constructor(private val apiService: IApiService) : IApiRandomUser {

override fun getRandomUser(): Single<RandomUser> {
return Single.create { subscriber ->
try {
val responce = apiService.apiDemo().execute()

responce.body()?.takeIf { responce.isSuccessful }?.let {
subscriber.onSuccess(it)
} ?: run {
subscriber.onError(NetworkErrorException("Error occurred somehow."))
}

} catch (e: NetworkErrorException) {
subscriber.onError(e)
}
}
}

override fun getRandomUser(numberOfUsers: Int): Observable<RandomUser> {
return Observable.create { subscriber ->
try {
for (i in 0 until numberOfUsers) {
val responce = apiService.apiDemo().execute()

responce.body()?.takeIf { responce.isSuccessful }?.let {
subscriber.onNext(it)

} ?: run {
subscriber.onError(NetworkErrorException("Error occurred somehow."))
return@create
}
}

subscriber.onComplete()

} catch (e: NetworkErrorException) {
subscriber.onError(e)
}
}
}
}
Loading