You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RecyclerView重复点击商品弹出Dialog触发‘System services not available...’错误求助

Fixing "System services not available to Activities before onCreate()" Crash on RecyclerView Item Re-Click

Hey there, let's break down this frustrating crash you're hitting! That System services not available to Activities before onCreate() error almost always ties to invalid Context handling when creating your custom Dialog—especially when reusing or holding onto stale references between clicks. Here's how to diagnose and fix it:

Common Root Causes

The issue happens because your second click is trying to use a Context that's either:

  • Already destroyed (from a previous Dialog instance that wasn't properly cleaned up)
  • Not tied to a currently active Activity lifecycle state
  • Using Application Context instead of Activity Context (Dialogs require an Activity to attach their window to)

Step-by-Step Solutions

1. Always Use a Valid Activity Context for Dialogs

Never use Application Context to create a Dialog—they need an active Activity to bind their window to. In your RecyclerView Adapter's click handler, grab the Context directly from the ViewHolder's itemView, and safely cast it to your Activity type:

holder.itemView.setOnClickListener {
    // Safely get the active Activity from the item's context
    val currentActivity = holder.itemView.context as? AppCompatActivity
    currentActivity?.let { activity ->
        // Create a NEW Dialog instance with the valid Activity context
        val quantityDialog = CustomQuantityDialog(activity)
        // Set up your Dialog listeners/data here
        quantityDialog.show()
    }
}

Using as? prevents crashes if the Context isn't an Activity (though this shouldn't happen in a typical RecyclerView setup).

2. Avoid Holding Stale Context References

If your Adapter stores an Activity reference as a member variable, wrap it in a WeakReference to prevent memory leaks and avoid holding onto a destroyed Activity:

class ProductAdapter(private val activityRef: WeakReference<AppCompatActivity>) : RecyclerView.Adapter<ProductViewHolder>() {

    override fun onBindViewHolder(holder: ProductViewHolder, position: Int) {
        holder.itemView.setOnClickListener {
            // Check if the Activity is still valid before using it
            activityRef.get()?.takeIf { !it.isFinishing && !it.isDestroyed }?.let { activity ->
                val dialog = CustomQuantityDialog(activity)
                dialog.show()
            }
        }
    }
}

When initializing the Adapter, pass in WeakReference(requireActivity()) (from a Fragment) or WeakReference(this) (from an Activity).

3. Don't Reuse Old Dialog Instances

Never store a Dialog as a member variable in your Adapter or ViewHolder. Each click should create a fresh Dialog instance with the current valid Context—reusing old instances can lead to them being tied to a destroyed Activity.

4. Validate Activity State Before Showing Dialogs

Add a quick check to ensure the Activity is still active before attempting to show your Dialog:

currentActivity?.let { activity ->
    if (!activity.isFinishing && !activity.isDestroyed) {
        val dialog = CustomQuantityDialog(activity)
        dialog.show()
    }
}

This prevents attempts to show a Dialog when the Activity is already in the process of being destroyed.

Why This Works

Dialogs rely on system services like WindowManager, which can only be accessed when an Activity is in a valid lifecycle state (between onCreate() and onDestroy()). By ensuring you're always using a fresh, active Activity Context for each Dialog, you eliminate the stale reference that's causing the crash on the second click.

内容的提问来源于stack exchange,提问作者Demonic218

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:20:26