該dialog支持在展示過程中變更文字內(nèi)容,并避免dialog生命周期引起的崩潰閃退問題椭赋。
object GlobalDialogManager {
private var dialog: AlertDialog? = null
private var dialogTextView: TextView? = null
private var isDialogShowing = false
private val lock = Any()
private var job: Job? = null
private var contextRef: WeakReference<Context>? = null
//展示dialog,并在20秒后自動(dòng)取消dialog彈框并可以通過callBack做后續(xù)功能
fun showDialog(context: Context, msg: String? = null, callBack: () -> Unit?) {
val activity = context as? Activity ?: return
//判斷dialog是否已經(jīng)展示疮跑,并且activity并未被消耗胖喳,展示的avtivit也是處于棧頂
if (isDialogShowing || activity.isFinishing || activity.isDestroyed || !FoxApp.instance().lifecycle.isActivityForeground(activity)) return
synchronized(lock) {
try {
contextRef = WeakReference(context)
if (dialog == null) {
val builder = AlertDialog.Builder(context, R.style.loadingDialog)
val inflater = LayoutInflater.from(context)
val dialogView = inflater.inflate(R.layout.dialog_loading_http, null)
dialogTextView = dialogView.findViewById(R.id.tv_loading)
builder.setView(dialogView)
dialog = builder.create().apply {
setCancelable(false)
setCanceledOnTouchOutside(false)
}
dialog?.window?.setDimAmount(0f)
}
if (!activity.isFinishing && !activity.isDestroyed && FoxApp.instance().lifecycle.isActivityForeground(
activity) && !isDialogShowing) {
job = GlobalScope.launch(Dispatchers.Main) {
dialog?.show()
isDialogShowing = true
dialogTextView?.text = msg ?: context.getString(R.string.loading_wait) // 延遲 20 秒后關(guān)閉對(duì)話框
delay(20000)
if (dialog != null && (isDialogShowing || dialog?.isShowing == true)) {
dismissDialog(context)
callBack?.invoke()
}
}
}
} catch (e: Exception) {
LogUtils.e("GlobalDialogManager", "Error showing dialog", e)
}
}
}
//展示過程中修改文字
fun updateText(newText: String?) {
synchronized(lock) {
CoroutineScope(Dispatchers.Main).launch {
dialogTextView?.text = newText ?: FoxApp.instance().getString(R.string.loading_wait)
}
}
}
fun initDialog() {
synchronized(lock) {
dialog = null
isDialogShowing = false
}
}
fun dismissDialog(context: Context) {
synchronized(lock) {
GlobalScope.launch(Dispatchers.Main) {
val activity = context as? Activity
val shouldDismiss =
activity == null || !activity.isFinishing && !activity.isDestroyed && FoxApp.instance().lifecycle.isActivityForeground(
activity)
if (shouldDismiss && dialog != null && (isDialogShowing || dialog?.isShowing == true)) {
job?.cancel()
dialog?.dismiss()
isDialogShowing = false
contextRef?.clear()
contextRef = null
}
}
}
}
fun cleanUp() {
synchronized(lock) {
job?.cancel() // 取消延遲任務(wù)
if (isDialogShowing) {
dialog?.dismiss()
}
contextRef?.clear()
contextRef = null
isDialogShowing = false
dialog = null
dialogTextView = null
}
}
}