在片段中创建警报对话框时,我遇到了一个小问题。以下是在Logcat中抛出的错误:
2020-07-26 11:21:47.425 20063-20063/com.example.MyApp E/WindowManager: android.view.WindowLeaked: Activity com.example.MyApp.MainActivity has leaked window DecorView@b9684c5[MainActivity] that was originally added here
at android.view.ViewRootImpl.<init>(ViewRootImpl.java:769)
at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:440)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:95)
at android.app.Dialog.show(Dialog.java:473)
at com.example.MyApp.ScannerFragment.onCreateView(ScannerFragment.kt:44)
at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2698)
at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:320)
at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1187)
at androidx.fragment.app.FragmentManager.addAddedFragments(FragmentManager.java:2224)
at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1997)
at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1953)
at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1849)
at androidx.fragment.app.FragmentManager$4.run(FragmentManager.java:413)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:237)
at android.app.ActivityThread.main(ActivityThread.java:8125)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:496)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1100)
我尝试参考this question,它解释说出现这个错误可能是因为在退出活动后显示一个对话框,或者在退出之前没有调用dismiss()
,或者其他的可能性。
然而,在我的上下文中,我不确定如何应用在我的上下文中建议的解决方案。我通过底部导航菜单在与活动MainActivity
相关的片段ScannerFragment
上显示了Alert对话框。以下是相关文件的代码:
ScannerFragment.kt
package com.example.MyApp
import android.Manifest
import android.content.DialogInterface
import android.content.pm.PackageManager
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.core.app.ActivityCompat
import androidx.core.app.ActivityCompat.requestPermissions
import androidx.fragment.app.Fragment
class ScannerFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
if (ActivityCompat.checkSelfPermission(requireContext(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
val builder: AlertDialog.Builder? = this.let {
AlertDialog.Builder(requireActivity())
}
builder
?.setMessage(R.string.camera_unauthorisedMessage)
?.setTitle(R.string.camera_unauthorisedTitle)
?.apply {
setPositiveButton("OK",
DialogInterface.OnClickListener { dialog, _ ->
requestPermissions(requireActivity(), arrayOf(Manifest.permission.CAMERA), 1111)
dialog.dismiss()
})
}
builder?.create()?.show() // Line 44 - error occurs here
} else {
Log.e("DB", "PERMISSION GRANTED")
}
return inflater.inflate(R.layout.fragment_scanner, container, false)
}
}
MainActivity.kt
package com.example.MyApp
import android.Manifest
import android.content.DialogInterface
import android.content.pm.PackageManager
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AlertDialog
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.core.view.children
import androidx.navigation.findNavController
import androidx.navigation.ui.setupWithNavController
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Sets up the bottom navigation bar for usage
initialiseBottomNav()
}
// Overrides the back button to prevent going back to StartActivity
override fun onBackPressed() {}
private fun initialiseBottomNav() {
val navController = findNavController(R.id.main_navhostfragment)
main_bottomnav.setupWithNavController(navController)
}
}
如果我提到上面的问题,我需要执行哪些步骤来解决此错误?非常感谢您的帮助,谢谢!
发布于 2020-07-26 13:34:59
这种情况意味着你的活动正在结束,或者你的应用程序在代码中的其他地方崩溃了,但随后打开的对话框导致了窗口泄漏。提示可能是检查您的日志(通常在您共享的日志之上的行),并查看是否有任何其他异常/错误发生在前面。
发布于 2020-07-26 14:09:03
首先,我建议您将AlertDialog
代码添加到片段的onViewCreated方法中。
其次,您可以在显示AlertDialog
之前添加以下检查
if(!requireActivity().isFinishing)
builder?.create()?.show()
发布于 2020-07-26 16:10:08
这是因为与活动上下文相关联的对话框使用了应用程序上下文
val builder: AlertDialog.Builder? = activity?.applicationContext?.let { AlertDialog.Builder(it) }
if(builder != null) {
builder
.setMessage("")
?.setTitle("R.string.camera_unauthorisedTitle")
?.apply {
setPositiveButton("OK",
DialogInterface.OnClickListener { dialog, _ ->
requestPermissions(requireActivity(), arrayOf(Manifest.permission.CAMERA), 1111)
dialog.dismiss()
})
}
builder.create().show() // Line 44 - error occurs here
}
https://stackoverflow.com/questions/63095804
复制相似问题