NoSuchMethodError:类Landroid / util / SparseArray中没有虚拟方法containsIZ;

问题描述

1。每当我在应用程序中刷取下一张图片时,应用程序崩溃,我不知道怎么回事

2。此问题在更新至Android 30后无法正常工作

java.lang.NoSuchMethodError:类Landroid / util / SparseArray中没有虚拟方法contains(I)Z;或其上级类(“ android.util.SparseArray”的声明出现在/system/framework/framework.jar!classes2.dex中)

class PostViewFragment : DialogFragment() {
private var player: SimpleExoPlayer? = null
private lateinit var mediaDataSourceFactory: DataSource.Factory
//var post: FeedNodeModel? = null
private val STORAGE_PERMISSION_CODE = 100
private var post: FeedNodeModel? = null

var currentPos = 0
var registeredFragments = SparseArray<SidecarPagerFragment>()
var isFirstLoad = true

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setStyle(STYLE_NORMAL,R.style.FullScreenDialogStyle)

    isCancelable = true
}

override fun onCreateView(inflater: LayoutInflater,container: ViewGroup?,savedInstanceState: Bundle?): View? {
    /*if (createdView != null) {
        return createdView
    }*/

    val view = inflater.inflate(R.layout.fragment_post_view,container,false)

    //post = arguments?.getSerializable("post") as FeedNodeModel?

    when (post?.__typename) {
        "GraphImage","GraphStoryImage" -> {
            Picasso.get()
                    .load(post?.sourceUrl)
                    .into(view.img_post)
            view.img_post.visibility = View.VISIBLE
            view.playerView.visibility = View.GONE
            view.viewpager.visibility = View.GONE
        }
        "GraphVideo","GraphStoryVideo" -> {
            Glide.with(requireContext())
                    .load(post?.thumbnailUrl)
                    .into(object : CustomTarget<Drawable>() {
                        override fun onLoadCleared(p0: Drawable?) {

                        }

                        override fun onResourceReady(p0: Drawable,p1: Transition<in Drawable>?) {
                            initializePlayer(view.playerView,post?.sourceUrl)
                        }
                    })
            view.img_post.visibility = View.GONE
            view.playerView.visibility = View.VISIBLE
            view.viewpager.visibility = View.GONE
        }
        "GraphSidecar" -> {
            val calHeight =
                    (resources.displayMetrics.widthPixels *
                            (post?.feedNodeModel?.get(0)?.dimenHeight!!)) /
                            post?.feedNodeModel?.get(0)?.dimenWidth!!

            view.txt_pager_count.text = "1/${post?.feedNodeModel?.size}"
            view.viewpager.layoutParams.height = calHeight
            view.viewpager.adapter = object : FragmentPagerAdapter(childFragmentManager,FragmentStatePagerAdapter.POSITION_NONE) {
                override fun getItem(p0: Int): Fragment {
                    val fragment = SidecarPagerFragment.create(post?.feedNodeModel?.get(p0))
                    registeredFragments.put(p0,fragment)
                    if (isFirstLoad) {
                        fragment.isFirstLoad = true
                        isFirstLoad = false
                    }

                    return fragment
                }

                override fun getCount(): Int = post?.feedNodeModel?.size!!
            }

            view.viewpager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
                override fun onPageScrollStateChanged(state: Int) {

                }

                override fun onPageScrolled(position: Int,positionOffset: Float,positionOffsetPixels: Int) {

                }

                @RequiresApi(Build.VERSION_CODES.R)
                override fun onPageSelected(position: Int) {
                    if (post?.feedNodeModel?.get(currentPos)?.__typename == "GraphVideo") {
                        registeredFragments[currentPos]?.onPause()
                    }

                    currentPos = position
                    view.txt_pager_count.text = "${currentPos+1}/${post?.feedNodeModel?.size}"

                    if (registeredFragments.contains(position)) {
                        registeredFragments[position]?.loadVideo()
                    }
                }
            })

            view.viewpager.visibility = View.VISIBLE
            view.img_post.visibility = View.GONE
            view.playerView.visibility = View.GONE
        }
    }

此行发生应用崩溃

 if (registeredFragments.contains(position)) {
                        registeredFragments[position]?.loadVideo()
                    }

解决方法

使用containsKey

/** Returns true if the collection contains [key]. */
inline fun <T> SparseArray<T>.containsKey(key: Int) = indexOfKey(key) >= 0

我的团队负责人Mike的见解

,

直观的方法 contains(int key) 实际上是在 API 30 中引入的,因此它会使旧的 API 设备崩溃。非常新的方法不会像折旧的方法那样给你一个方便的警告,使它们变得更加危险。即使你的目标低于 30 Android Studio 仍然会编译 contains() 而不抗议。

参考资料如下:

public boolean contains (int key):
Returns true if the key exists in the array. This is equivalent to indexOfKey(int) >= 0

您可以使用 indexOfKey() 等效测试,尽管我个人更喜欢使用 get() 测试 null:

get(key) != null

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...