dingyi222666 / TreeView

An Android TreeView with RecyclerView
Apache License 2.0
105 stars 9 forks source link

动态添加很多数据,闪退 #9

Closed zhengyu-android closed 1 year ago

zhengyu-android commented 1 year ago

input parameter exceed reasonable range 1000000 4 2 0 2023-08-23 19:57:26.500 2077-2636/? E/DeviceMonitorPowerKit: not Satify ApplyResource 2023-08-23 19:57:26.542 13846-13920/com.iimt.robotarm E/AndroidRuntime: FATAL EXCEPTION: pool-6-thread-1 Process: com.iimt.robotarm, PID: 13846 java.util.ConcurrentModificationException at java.util.ArrayList$Itr.next(ArrayList.java:860) at java.util.AbstractList.hashCode(AbstractList.java:566) at com.iimt.robotarm.result.TreeNodeData.hashCode(Unknown Source:81) at io.github.dingyi222666.view.treeview.TreeNode.hashCode(treeNodes.kt:108) at io.github.dingyi222666.view.treeview.TreeViewBinder.areContentsTheSame(TreeView.kt:667) at io.github.dingyi222666.view.treeview.TreeViewBinder.areContentsTheSame(TreeView.kt:596) at androidx.recyclerview.widget.AsyncListDiffer$1$1.areContentsTheSame(AsyncListDiffer.java:319) at androidx.recyclerview.widget.DiffUtil$DiffResult.findMatchingItems(DiffUtil.java:702) at androidx.recyclerview.widget.DiffUtil$DiffResult.(DiffUtil.java:675) at androidx.recyclerview.widget.DiffUtil.calculateDiff(DiffUtil.java:178) at androidx.recyclerview.widget.DiffUtil.calculateDiff(DiffUtil.java:106) at androidx.recyclerview.widget.AsyncListDiffer$1.run(AsyncListDiffer.java:292) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) at java.lang.Thread.run(Thread.java:930) 2023-08-23 19:57:26.559 814-814/? E/SurfaceFlingerEx: Invalid parameter(s)! 2023-08-23 19:57:26.572 3184-4264/? E/HONOR_AWARENESS_AppGeneralCollectAbility: contained in blacklist : com.hihonor.android.launcher 2023-08-23 19:57:26.572 1025-2676/? E/ZrHung.AppEyeFocusWindow: NFW check! 2023-08-23 19:57:26.616 814-814/? E/SurfaceFlinger: checkContinuousFrameMiss ADD 1. 2023-08-23 19:57:26.616 814-814/? E/SurfaceFlingerEx: itouch VsyncOffsetInfo ERROR sfRefreshPoint is smaller than sfInvalidatPoint 2023-08-23 19:57:26.626 1983-2194/? E/BoosterUtil: convertSubIdToSlotId failed, subId:0, slotId:-1 2023-08-23 19:57:26.626 1983-2194/? E/BoosterUtil: getDefaultDataSlotId failed, invalid slotId:-1, subId:0 2023-08-23 19:57:26.626 1983-2194/? E/Booster_BroadcastProxy: [isDataOn]isDataOn failed, invalid slotId=-1 2023-08-23 19:57:26.628 814-916/? E/SurfaceFlingerEx: Invalid parameter(s)! 2023-08-23 19:57:26.635 814-814/? E/BpTransactionCompletedListener: Failed to transact (-32) 2023-08-23 19:57:26.635 814-814/? E/BpTransactionCompletedListener: Failed to transact (-32) 2023-08-23 19:57:26.651 814-1082/? E/SurfaceFlingerEx: Invalid parameter(s)! 2023-08-23 19:57:26.659 1983-9343/? E/HsmCoreServiceImpl: onTransact in code is: 102 2023-08-23 19:57:26.659 2035-2926/? E/AwareLog: Stub: processProcessDied has not been overridden! 2023-08-23 19:57:26.660 1983-2194/? E/DollieAdapterService: notifyActivityState pkg:com.iimt.robotarm/com.iimt.robotarm.app.MainVMActivity state:19 fg:false mUid:10267 2023-08-23 19:57:26.660 1983-2194/? E/BoosterUtil: convertSubIdToSlotId failed, subId:0, slotId:-1

dingyi222666 commented 1 year ago

你是用什么更新数据的,DataSource 吗?

理论上来说在 fetchChildData 时应该返回一个副本 set。

zhengyu-android commented 1 year ago

val item = TreeNodeData( id = Config.Sign.id++, typeId = ROBOT_PROCEDURE, name = "程序", icon = R.drawable.program_robot_procedure, isArrive = 0, command = "", isSign = true, isSelect = true, iShow = true )

在item中添加,然后使用 lifecycleScope.launch { binding.treeView.refresh() } 更新。

dingyi222666 commented 1 year ago

能不能写一段能复现的代码出来

zhengyu-android commented 1 year ago

val item = TreeNodeData( id = Config.Sign.id++, typeId = ROBOT_PROCEDURE, name = "机器人程序", icon = R.drawable.program_robot_procedure, isArrive = 0, command = "", isSign = true, isSelect = true, iShow = true )

@Subscribe
fun mTreeNodeEvent(event: TreeNodeEvent) {

// setAllIsSelectToFalse(item.child) var childData = item.child var lastIndex = 0 // 遍历数据赋值 获取最后一位 if (positionList.size > 1) { for (position in positionList.dropLast(1)) { childData = childData[position].child } lastIndex = positionList[positionList.size - 1] + 1 positionList[positionList.size - 1] = lastIndex } else { if (positionList.size>0) { lastIndex = positionList[0] + 1 } else { lastIndex = childData.size } } childData.add(lastIndex,event.data) childData[lastIndex].isSelect = true

    lifecycleScope.launch {
        binding.treeView.refresh()
    }
}

通过eventbus,添加数据更新,数据量大,可能会造成闪退

dingyi222666 commented 1 year ago

val item = TreeNodeData( id = Config.Sign.id++, typeId = ROBOT_PROCEDURE, name = "机器人程序", icon = R.drawable.program_robot_procedure, isArrive = 0, command = "", isSign = true, isSelect = true, iShow = true )

@Subscribe
fun mTreeNodeEvent(event: TreeNodeEvent) {

// setAllIsSelectToFalse(item.child) var childData = item.child var lastIndex = 0 // 遍历数据赋值 获取最后一位 if (positionList.size > 1) { for (position in positionList.dropLast(1)) { childData = childData[position].child } lastIndex = positionList[positionList.size - 1] + 1 positionList[positionList.size - 1] = lastIndex } else { if (positionList.size>0) { lastIndex = positionList[0] + 1 } else { lastIndex = childData.size } } childData.add(lastIndex,event.data) childData[lastIndex].isSelect = true

    lifecycleScope.launch {
        binding.treeView.refresh()
    }
}

通过eventbus,添加数据更新,数据量大,可能会造成闪退

你这个是用的 TreeNodeGenerator 还是 DataSource

zhengyu-android commented 1 year ago

The TreeNodeGenerator is used. I'm sorry, this is my problem. I tried to modify the ArrayList object while iterating, which caused it. In a multithreaded environment, if one thread is traversing a collection while another thread is modifying the collection at the same time, this exception will occur. I have already solved the problem with CopyOnWriteArrayList. Thank you