Moshi的定制适配器与RxAndroid&Retrofit&Kotlin

在为Android项目配置Kotlin之后,我写了一个简单的MainActivity.kt 。 它调用Retrofit来获取包含以下数据的JSON文件:

 {
     “消息”:“成功”,
     “user”:{
         “用户名”:“Eric”
     }
 }

现在我想用Moshi把JSON数据转换成Kotlin类,所以这里有两个类来反映上面的JSON结构:

 class User(var username:String)

 UserJson类(var消息:字符串,var用户:用户)

而Moshi的自定义类型适配器:

类UserAdapter {
     @FromJson fun fromJson(userJson:UserJson):User {
         Log.d(“MyLog”,“message = $ {userJson.message}”)// =成功
         Log.d(“MyLog”,“user = $ {userJson.user}”)// = null

        返回userJson.user
     }
 }

当它进入函数从fromJson()userJson.message = "success"的预期。 但奇怪的是, userJson.usernull ,这应该是User(username="Eric")

我是Moshi和Kotlin的新手,我已经坚持了这个问题约10个小时。 请帮我一下 感谢您的帮助。

========================================

以下是MainActivity.kt的完整代码(仅限50行):

 class MainActivity:AppCompatActivity(){

    重写fun onCreate(savedInstanceState:Bundle?){
         super.onCreate(savedInstanceState)
        的setContentView(R.layout.activity_main)

         // Moshi的自定义类型适配器
         val userMoshi = Moshi.Builder().add(UserAdapter())。build()

         val retrofit = Retrofit.Builder()
                 .baseUrl( “https://dl.dropboxusercontent.com/”)
                 .addConverterFactory(MoshiConverterFactory.create(userMoshi))
                 .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                 。建立()

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

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


 // ========== For Retrofit ==========
接口AccountService {

     @GET( “U / 17350105 / test.json”)
    有趣的signUpAnonymously():Observable <User>

 }


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

 UserJson类(var消息:字符串,var用户:用户)

类UserAdapter {

     @FromJson fun fromJson(userJson:UserJson):User {
         Log.d(“MyLog”,“message = $ {userJson.message}”)// =成功
         Log.d(“MyLog”,“user = $ {userJson.user}”)// = null

        返回userJson.user
     }

 }

build.gradle是:

编译“io.reactivex.rxjava2:rxjava:2.0.0”
编译“io.reactivex.rxjava2:rxandroid:2.0.0”

编译“com.android.support:appcompat-v7:25.0.0”

编译“com.squareup.retrofit2:翻新:2.1.0”
编译“com.squareup.retrofit2:converter-moshi:2.1.0”
编译'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'

再次感谢你。

你可以通过改变你的代码来做下面的事情来解决这个问题。

基本上你的情况下,当UserAdapter注册,它告诉moshi,它可以创建一个User只从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) } } 

如果你只需要User对象。 有一个名为Moshi-Lazy-Adapters的库,它提供了一个@Wrapped注解,允许指定所需对象的路径。 您只需将相应的适配器添加到您的moshi实例中,然后将服务代码添加到:

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

不需要任何其他自定义适配器。