为Android项目配置Kotlin后,我写了一个简单的MainActivity.kt
。它调用Retrofit来获取包含以下数据的JSON文件:
{ "message": "success", "user": { "username": "Eric" } }
现在我想使用Moshi将JSON数据转换为Kotlin的类,所以这里有两个类来反映上面的JSON结构:
class User(var username: String) class UserJson(var message: String, var user: User)
Moshi的自定义类型适配器:
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.user
是null
,应该是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'
再次感谢你。
答案 0 :(得分:4)
如果您只需要User
个对象。有一个名为Moshi-Lazy-Adapters的库提供@Wrapped
注释,允许指定所需对象的路径。您所要做的就是将相应的适配器添加到您的moshi实例并将服务代码转换为:
interface AccountService {
@GET("u/17350105/test.json")
@Wrapped("user")
fun signUpAnonymously() : Observable<User>
}
无需任何其他自定义适配器。
答案 1 :(得分:3)
您可以通过更改代码来执行以下操作来解决问题。
基本上在您注册UserAdapter
的情况下,它告诉moshi它只能从User
对象创建UserJson
。因此,Moshi无法识别带有关键字user
的JSON对象。
通过以User1
的形式添加间接(请原谅命名约定),使用来自JSON的UserJson
正确创建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)
}
}