首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >添加工厂时的Moshi ArrayOutOfBoundsException

添加工厂时的Moshi ArrayOutOfBoundsException
EN

Stack Overflow用户
提问于 2020-03-19 11:34:49
回答 1查看 131关注 0票数 2

在打开应用程序时,我发现这个异常有时与Moshi有关:

代码语言:javascript
复制
Caused by java.lang.ArrayIndexOutOfBoundsException: length=33; index=33
       at java.util.ArrayList.add(ArrayList.java:468)
       at com.squareup.moshi.Moshi$Builder.add(Moshi.java:231)

我们在BaseApplication中初始化一个存储库,有时在初始化Moshi时会导致所提到的崩溃。我在应用程序报告中发现了这个错误,但是我无法复制它。让我们跳到我们所拥有的,看看你是否有线索。

这个工厂用于创建Moshi实例,在添加KotlinJsonAdapterFactory时得到崩溃:

代码语言:javascript
复制
object MyMoshiConverterFactory {

    fun create(setup: (Moshi.Builder.() -> Unit)? = null): Converter.Factory {
        val moshi = MoshiUtil.createMoshi()
        setup?.let { moshi.it() }
        moshi.add(KotlinJsonAdapterFactory()) // Here is the crash!
        return MoshiConverterFactory.create(moshi.build())
    }
}

这里我们有一个类,我们使用的所有转换器。它确实有更多的转换器,但为了简单起见,我删除了其中的几个:

代码语言:javascript
复制
object MoshiUtil {

    private val lazyMoshi by lazy {
        Moshi.Builder().apply {
            add(DateAdapter())
            add(DefaultOnDataMismatchAdapter.newFactory(FeedItem::class.java, null))
            add(SkipListNullValuesAdapter.createFactory(Element::class.java))
            add(SkipListNullValuesAdapter.createFactory(Post::class.java))
            add(SkipListNullValuesAdapter.createFactory(MetadataItem::class.java))
            add(GeoGeometry::class.java, GeometryAdapter())
        }
    }

    fun createMoshi() = lazyMoshi
}

最后,在我们的BaseApplication中,我们有这样的东西:

代码语言:javascript
复制
class BaseApplication {

   @Override
    public void onCreate() {
        super.onCreate();

        val myService = getMyService(applicationContext)

    }

    private fun getMyService(appContext: Context): MyService {
       val converterFactory = MyMoshiConverterFactory.create()

       return Retrofit.Builder().baseUrl(baseUrl).apply {
                addConverterFactory(converterFactory)
                client(okHttpClientBuilder.build())
            }.build().create(MyService::class.java)
        }
    }
 }

那么,你看到什么可能导致它的东西了吗?当应用程序中的几个地方同时创建MoshiUtils对象时,您认为这可能是一个并发问题吗?期待着收到你们的来信,谢谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-04-09 23:14:15

Moshi.Builder是可变的,并不是线程安全的,因此有时您所得到的错误是由于这个原因而产生的争用条件。您应该在这个基本MoshiUtil实例上调用MoshiUtil以获得一个不可变的Moshi实例,然后使MoshiUtil.createMoshi be moshi.newBuilder()的返回值(创建已经配置为现有Moshi实例的Moshi.Builder ),如下所示:

代码语言:javascript
复制
object MoshiUtil {
    private val baseMoshi: Moshi = Moshi.Builder().apply {
        // ...
    }.build()

    fun createMoshi(): Moshi.Builder = baseMoshi.newBuilder()
}

由于每个调用createMoshi的人现在都有自己的Moshi.Builder实例,所以不应该再有任何并发问题了。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60756382

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档