android - 使用领域和侦听器时应用程序崩溃
问题描述
我目前遇到了一个烦人的问题,我不知道这是一个错误还是我实现了错误。这会导致我的应用程序偶尔崩溃而没有明显的错误消息。我一直在 Stackoverflow 和其他页面上搜索,但到目前为止还没有解决方案。错误本身很长发布,所以如果不是问题,我会发布第一行。
错误信息:
2021-11-06 21:19:55.269 31533-31533/com.example.test A/ple.test: java_vm_ext.cc:577] JNI DETECTED ERROR IN APPLICATION: JNI NewLocalRef called with pending exception java.lang.NullPointerException:
java_vm_ext.cc:577] (Throwable with no stack trace)
java_vm_ext.cc:577]
java_vm_ext.cc:577] in call to NewLocalRef
java_vm_ext.cc:577] from void android.os.MessageQueue.nativePollOnce(long, int)
2021-11-06 21:19:55.455 31533-31533/com.example.test A/ple.test: runtime.cc:655] Runtime aborting...
runtime.cc:655] Dumping all threads without mutator lock held
runtime.cc:655] All threads:
runtime.cc:655] DALVIK THREADS (40):
runtime.cc:655] "main" prio=10 tid=1 Runnable
…
我今天整天都在进行故障排除,以发现问题出在 BottomSheetDialogFragment 和 RealmDB 中。因此,当我启动函数“updateContactChat”时,一切正常,没有错误。一旦我再次打开相同的 BottomSheetDialogFragment 并启动函数“updateContactChat”,应用程序就会完全崩溃并出现上述错误。
是代码。
class ChatAdd : BottomSheetDialogFragment() {
private val appRealm = Realm.getInstance(General.secureDB())
private var binding: FragmentChatsAddBinding? = null
override fun getTheme(): Int = R.style.BottomSheetDialogTheme
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
super.onCreateView(inflater, container, savedInstanceState)
binding = FragmentChatsAddBinding.inflate(inflater, container, false)
return binding!!.root
}
override fun onStart() {
super.onStart()
BottomSheetBehavior.from(requireView().parent as View).apply {
state = BottomSheetBehavior.STATE_EXPANDED
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
R.style.DialogAnimation.also { dialog!!.window?.attributes?.windowAnimations = it }
binding!!.contactListContainer.layoutManager = LinearLayoutManager(activity)
binding!!.contactListContainer.setHasFixedSize(true)
binding!!.contactListContainer.addItemDecoration(ContactsList.ItemDecoration())
showList()
}
private fun showList() {
var contacts: RealmResults<SchemeContacts>? = null
binding!!.contactListContainer.adapter = ContactsAdapter(contacts, true, object :
ContactsAdapter.ContactItemClickListener {
override fun onClick(contact: SchemeContacts?) {
contact?.contact_id?.let {
CoroutineScope(Dispatchers.IO).launch {
try {
updateContactChat(it)
}catch(e:Exception){
Log.d("log", "catch error: "+e)
}
}
}
}
})
}
private fun updateContactChat(contactId: String) {
val updateRealm = Realm.getInstance(General.secureDB())
updateRealm.executeTransaction { bgRealm ->
val user =
bgRealm.where<SchemeContacts>().equalTo("contact_id", contactId).findFirst()!!
user.contact_chat = true
user.contact_chatupdated = LocalDateTime.now().toString()
user.contact_chatnew = 0
user.contact_chatstatus = 0
}
updateRealm.close()
dialog!!.dismiss()
}
override fun onDestroy() {
super.onDestroy()
appRealm.close()
binding = null
}
}
我也尝试了几种使用 Realm DB 的解决方案,但不幸的是无济于事。我希望这里有人能指出我正确的方向。
更新:
我有一个更改侦听器,它在数据库中进行更改时触发。此代码在我的父片段中,而不是在我的底页片段中。因此,当我选择一个联系人时,数据库会更新,这会触发父片段中的侦听器(您将被发送到该特定的联系人片段)。这是监听器的代码。
fun runListener(){
contacts?.addChangeListener(OrderedRealmCollectionChangeListener { contacts, changeSet ->
if (contacts.size > 0) {
binding!!.notfound.root.visibility = View.GONE
} else {
binding!!.notfound.root.visibility = View.VISIBLE
}
})
}
override fun onDestroy() {
super.onDestroy()
binding = null
appRealm.close()
}
所以第一次什么都没有发生,因为绑定存在并且它将运行没有错误并且Android将运行“onDestroy”,该绑定和数据库正在关闭/为空。因为我从未关闭过监听器,所以会继续收听。当我重复我的动作并启动一个新的监听器时,两个监听器都被调用了。第一个侦听器将查找不存在的“绑定”,因为我在 Android 第一次销毁片段时“取消”了它。所以这就是为什么我得到一个空异常。第一个侦听器的绑定不再存在。
将代码更改为此后,一切正常,没有崩溃或错误:
fun runListener(){
contacts?.addChangeListener(OrderedRealmCollectionChangeListener {
contacts, changeSet ->
try {
if(binding != null) {
if (contacts.size > 0) {
binding!!.notfound.root.visibility = View.GONE
} else {
binding!!.notfound.root.visibility = View.VISIBLE
}
}
}catch(e:Exception){
Log.d("error","Try Catch error: "+e.toString())
}
})
}
override fun onDestroy() {
super.onDestroy()
if(contacts != null){
contacts!!.removeAllChangeListeners()
}
binding = null
appRealm.close()
}
我希望它很清楚,这确实是初学者的一个漫长的错误,也是非常重要的一课。关闭你开始的一切。
解决方案
问题是绑定到元素的父片段上的领域侦听器。它显然会导致错误。
推荐阅读
- windows - 如何在 OSGeo4W 中将 proj 升级到 6.1?
- java - 打包jar时Maven无法检索buildNumber
- sql-server - Sql server中的Cte是执行一次还是每次被引用?
- xamarin.forms - CollectionView 不能正常工作是 iOS
- java - MaterialDatePicker 无法在 Android 上运行
- overflow - 减法和加法时位溢出。我的视频很混乱
- docker - Dockerfile单行`ENV`组成变量不起作用
- android - 如何将文件位置作为函数参数传递给 MediaPlayer 文件的可单击列表视图
- openapi - openapi3:如何指定对象模式应该是模式本身?
- java - 如何在debian虚拟机上安装java