9

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

{
    “消息”:“成功”,
    “用户”:{
        “用户名”:“埃里克”
    }
}

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

类用户(var 用户名:字符串)

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

还有一个 Moshi 的自定义类型适配器:

类用户适配器 {
    @FromJson fun fromJson(userJson: UserJson) : User {
        Log.d("MyLog", "message = ${userJson.message}") // = 成功
        Log.d("MyLog", "user = ${userJson.user}") // = null

        返回用户Json.user
    }
}

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

我是 Moshi 和 Kotlin 的新手,我已经在这个问题上坚持了大约 10 个小时。请帮帮我。谢谢你的帮助。

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

以下是整个代码MainActivity.kt(仅 50 行):

类 MainActivity : AppCompatActivity() {

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

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

        val 改造 = 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 { 用户 ->
                    Log.d("MyLog", user.toString())
                }
    }
}


// ========== 用于改造 ==========
接口帐户服务{

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

}


// ========== 对于 Moshi ==========
类用户(var 用户名:字符串)

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

类用户适配器 {

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

        返回用户Json.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:retrofit:2.1.0”
编译“com.squareup.retrofit2:converter-moshi:2.1.0”
编译'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'

再次感谢你。

4

2 回答 2

5

您可以通过更改代码来执行以下操作来解决问题。

基本上,在您UserAdapter注册的情况下,它告诉 moshi 它User只能从UserJson对象创建一个。因此 Moshi 无法识别带有关键字的 JSON 对象user

User1通过以(请原谅命名约定)的形式添加间接,可以使用JSONUserJson正确创建。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)
    }
}
于 2016-11-04T17:33:32.513 回答
5

如果你只需要User对象。有一个名为Moshi-Lazy-Adapters的库提供@Wrapped注释,允许指定所需对象的路径。您所要做的就是将相应的适配器添加到您的 Moshi 实例并将服务代码更改为:

interface AccountService {

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

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

于 2016-11-04T22:54:33.523 回答