2016-11-04 4 views
1

Android用Kotlinプロジェクトを設定した後、簡単にMainActivity.ktと書いています。ので、ここで上記のJSONの構造を反映するために、2つのクラスがあり、私はKotlinのクラスにJSONデータを変換するために、モシを使用したい今Moshiのカスタムアダプター(RxAndroid&Retrofit&Kotlin付き)

 
{ 
    "message": "success", 
    "user": { 
     "username": "Eric" 
    } 
} 

それは、以下のデータが含まれてJSONファイルを取得するためにレトロフィットと呼ばれます
 
class User(var username: String) 

class UserJson(var message: String, var user: User) 

とモシのためのカスタム型アダプター:

 
class UserAdapter { 
    @FromJson fun fromJson(userJson: UserJson) : User { 
     Log.d("MyLog", "message = ${userJson.message}") // = success 
     Log.d("MyLog", "user = ${userJson.user}")  // = null 

     return userJson.user 
    } 
} 

期待どおりに機能fromJson()userJson.message = "success"に入ります。しかし、奇妙なことに、userJson.usernullであり、それはUser(username="Eric")でなければならない。

私はMoshiとKotlinには新しく、すでにこの問題を約10時間抱えています。私を助けてください。助けてくれてありがとう。

========================================次

MainActivity.kt(のみ50行)の全体のコードされています

 
class MainActivity : AppCompatActivity() { 

    override fun onCreate(savedInstanceState: Bundle?) { 
     super.onCreate(savedInstanceState) 
     setContentView(R.layout.activity_main) 

     // Custom Type Adapters for Moshi 
     val userMoshi = Moshi.Builder().add(UserAdapter()).build() 

     val retrofit = Retrofit.Builder() 
       .baseUrl("https://dl.dropboxusercontent.com/") 
       .addConverterFactory(MoshiConverterFactory.create(userMoshi)) 
       .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) 
       .build() 

     val accountService = retrofit.create(AccountService::class.java) 

     accountService.signUpAnonymously() 
       .subscribeOn(Schedulers.io()) 
       .observeOn(AndroidSchedulers.mainThread()) 
       .subscribe { user -> 
        Log.d("MyLog", user.toString()) 
       } 
    } 
} 


// ========== For Retrofit ========== 
interface AccountService { 

    @GET("u/17350105/test.json") 
    fun signUpAnonymously() : Observable<User> 

} 


// ========== For Moshi ========== 
class User(var username: String) 

class UserJson(var message: String, var user: User) 

class UserAdapter { 

    @FromJson fun fromJson(userJson: UserJson) : User { 
     Log.d("MyLog", "message = ${userJson.message}")  // = success 
     Log.d("MyLog", "user = ${userJson.user}")    // = null 

     return userJson.user 
    } 

} 

build.gradleは次のとおりです。

 
compile "io.reactivex.rxjava2:rxjava:2.0.0" 
compile "io.reactivex.rxjava2:rxandroid:2.0.0" 

compile "com.android.support:appcompat-v7:25.0.0" 

compile "com.squareup.retrofit2:retrofit:2.1.0" 
compile "com.squareup.retrofit2:converter-moshi:2.1.0" 
compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0' 

ありがとうございました。

答えて

1

問題を解決するには、コードを変更して以下のようにします。

UserAdapterが登録されている場合、基本的にはをUserJsonオブジェクトからのみ作成することができます。したがって、MoshiはキーワードuserでJSONオブジェクトを認識しません。

User1の形式で間接参照を追加すると、UserJsonがJSONのUser1で正しく作成されます。

class User(var username: String) 

class User1(var username: String) // I introduced this class 
class UserJson(var message: String, var user: User1) // changed User to User1 

class UserAdapter { 
    @FromJson fun fromJson(userJson: UserJson): User { 
     println("message = ${userJson.message}")   
     println("user = ${userJson.user}")    
     return User(userJson.user.username) 
    } 
} 
+0

ありがとうございます!もう一つ質問があります:同じ目標を達成するためのよりよい方法はありますか? (私がする必要があるのは、元のJSONから 'user'フィールドを取得することだけです) – iForests

3

Userオブジェクトが必要な場合は、 @Wrapped注釈を提供するMoshi-Lazy-Adaptersというライブラリがあり、目的のオブジェクトへのパスを指定できます。その他のカスタムアダプタの必要性を全く

interface AccountService { 

    @GET("u/17350105/test.json") 
    @Wrapped("user") 
    fun signUpAnonymously() : Observable<User> 
} 

:あなたがしなければならないのは、あなたのモシインスタンスにそれぞれのアダプタを追加していないとするサービスコードをchagneです。

+0

MoshiのGitHubページ(#182#176#113)でいくつかの関連する問題が見られました。あなたのMoshi-Lazy-Adaptersにどうもありがとう! – iForests

+0

答えを補うだけで、改造ビルダーでこのようなアダプタを定義する必要があります。 ".addConverterFactory(Moshi.Builder()。add(Wrapped.ADAPTER_FACTORY).build()))"また、より深いパスが必要な場合は、@Wrapped(path = ["a"、 "b"、 "c"]) – isanjosgon

関連する問題