Moshi的定制适配器,带有RxAndroid和Retrofit&Kotlin

在为 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'

再次感谢你.

解决方法

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

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

通过以User1的形式添加间接(请原谅命名约定),使用JSON中的User1正确创建Userjson.

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)
    }
}

相关文章

Android性能优化——之控件的优化 前面讲了图像的优化,接下...
前言 上一篇已经讲了如何实现textView中粗字体效果,里面主要...
最近项目重构,涉及到了数据库和文件下载,发现GreenDao这个...
WebView加载页面的两种方式 一、加载网络页面 加载网络页面,...
给APP全局设置字体主要分为两个方面来介绍 一、给原生界面设...
前言 最近UI大牛出了一版新的效果图,按照IOS的效果做的,页...