您的位置:首页 > 其它

【安卓学习之常见问题】从ANR到ConcurrentModificationException

2021-04-26 10:28 99 查看

█ 【安卓学习之常见问题】从ANR到ConcurrentModificationException

█ 系列文章目录

提示:这里是收集了安卓学习之常见问题的相关文章

█ 文章目录

█ 读前说明

  • 本文通过学习别人写demo,学习一些课件,参考一些博客,’学习相关知识,如果涉及侵权请告知
  • 本文只简单罗列相关的代码实现过程
  • 涉及到的逻辑以及说明也只是简单介绍,主要当做笔记,了解过程而已

█ 问题1:ANR

⚡️ ANR in com.xxx.xxx.debug (com.xxx.xxx.debug/org.xxx.xxx.xxx.TLogPlayBackActivity)

  • 执行代码
2021-04-26 09:13:30.082 1387-1422/? E/ActivityManager: ANR in com.xxx.xxx.debug (com.xxx.xxx.debug/org.xxx.xxx.xxx.TLogPlayBackActivity)
PID: 6873
Reason: Input dispatching timed out (Waiting to send non-key event because the touched window has not finished processing certain input events that were delivered to it over 500.0ms ago.  Wait queue length: 3.  Wait queue head age: 6174.0ms.)
Load: 6.21 / 5.99 / 5.11
CPU usage from 151214ms to 0ms ago (2021-04-26 09:10:56.271 to 2021-04-26 09:13:27.485):
134% 6873/com.xxx.xxx.debug: 121% user + 13% kernel / faults: 412028 minor
6.3% 599/surfaceflinger: 3.7% user + 2.5% kernel / faults: 18 minor
4.2% 1387/system_server: 2.8% user + 1.3% kernel / faults: 7680 minor
3.5% 572/android.hardware.graphics.composer@2.1-service: 2.2% user + 1.2% kernel / faults: 1 minor
1.4% 624/mm-pp-dpps: 0.5% user + 0.8% kernel
1.1% 262/kgsl_worker_thr: 0% user + 1.1% kernel
0.8% 3287/mdss_fb0: 0% user + 0.8% kernel

█ 问题1解决:线程

⚡️ 1.ANR 就是UI线程被阻塞导致的,看了下代码,当数据量比较大时,for循环太长,我这边有30万条数据的数据,因此就会出现

for (i in 0 until end) {
var coord= coords[i]
polylineInfo.addCoord(coord)
}
polylineInfo.update(this)// 地图打点

⚡️ 2.将其改为for循环为ui线程,计算后,在ui线程处理

var asyncScheduler = Executors.newSingleThreadExecutor()
asyncScheduler?.execute {
// 新线程
for (i in 0 until end) {
var coord= coords[i]
polylineInfo.addCoord(coord)
}
// ui线程
myHandler.post(Runnable {
polylineInfo.update(this)// 地图打点
})
}

⚡️ANR : Application Not Responding即应用无响应。当操作在一段时间内,系统无法处理是,就会发生ANR。弹出对应的无响应的对话框。Android ANR问题分为三类:Input(5秒),Receiver(10秒/60秒),Service(20秒)。

█ 问题2:ConcurrentModificationException

⚡️ ConcurrentModificationException

java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.next(ArrayList.java:860)


⚡️ MapUtils.java:205
coords 就是 polylineInfo中的add的coords

public static List<GeoPoint> coordToPoint(List<? extends LatLong> coords) {
List<GeoPoint> points = new ArrayList<>(coords.size());
for (LatLong coord : coords) {
points.add(coordToPoint(coord));
}
return points;
}

⚡️一个迭代器在迭代集合的时候 集合被修改了,例如 在迭代 Arraylist 的时候 对Arraylist进行增删操作 就会抛出该异常,原因是:集合中 list set 等 都没有实现同步 , 在多线程中 对集合进行操作时 同步操作都是由外部进行控制

█ 问题2解决:增加标记位

⚡️1.大概的意思就是,在update -> coordToPoint中执行for循环和 for (i in 0 until end)中执行add循环两个互相冲突了
⚡️2.其实在这边已经使用newSingleThreadExecutor,保证add 和update 不会同时执行,但是在其他操作时候,也会进行update
⚡️ 3.可以加同步锁,但是 可能 影响到了ui线程,导致ANR

var isAdd = false // 标记位
var asyncScheduler = Executors.newSingleThreadExecutor()
asyncScheduler?.execute {
synchronized (polylineInfo) {
// 新线程
if (isAdd) return@execute
isAdd = true
for (i in 0 until end) {
var coord= coords[i]
polylineInfo.addCoord(coord)
}
}
// ui线程
myHandler.post(Runnable {
synchronized (polylineInfo) {// 可能会阻塞
polylineInfo.update(this)// 地图打点
isAdd = false
}
})
}

⚡️ 4.增加标记位,当进行数据处理时,不能进行数据修改(增删改)

var isAdd = false // 标记位
var asyncScheduler = Executors.newSingleThreadExecutor()
asyncScheduler?.execute {
// 新线程
if (isAdd) return@execute
isAdd = true
for (i in 0 until end) {
var coord= coords[i]
polylineInfo.addCoord(coord)
}
// ui线程
myHandler.post(Runnable {
polylineInfo.update(this)// 地图打点
isAdd = false
})
}

█ 补充问题3:TransactionTooLargeException

⚡️ TransactionTooLargeException
在启动Activity时,进行传递数据,通过intent.putExtra传递,因为lists数据太大,导致问题

context.startActivity(Intent(context, XXXActivity::class.java).putExtra("data",lists))
companion object {
fun start(context: Context, fileName: String, lists: LinkedList<Event>) {
context.startActivity(Intent(context, XXXActivity::class.java)
.putExtra("data",lists)
)
}
}
2021-04-26 11:24:38.719 17803-17803/com.xxx.xxx.debug E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.xxx.xxx.debug, PID: 17803
java.lang.RuntimeException: Failure from system
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1620)
at android.app.Activity.startActivityForResult(Activity.java:4501)
at androidx.fragment.app.FragmentActivity.startActivityForResult(FragmentActivity.java:675)
at android.app.Activity.startActivityForResult(Activity.java:4459)
at androidx.fragment.app.FragmentActivity.startActivityForResult(FragmentActivity.java:662)
at android.app.Activity.startActivity(Activity.java:4820)
at android.app.Activity.startActivity(Activity.java:4788)
at org.xxx.xxx.xxx.XXXActivity$Companion.start(XXXActivity.kt:54)

⚡️ 改为EventBus
在启动Activity时,进行传递数据,通过intent.putExtra传递

companion object {
fun start(context: Context, fileName: String, lists: LinkedList<Event>) {
EventBus.getDefault().postSticky(XXXEventInfo(lists))
context.startActivity(Intent(context, XXXActivity::class.java)
//.putExtra("data",lists)
)
}
}

@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
fun onEventMainThread(event: XXXEventInfo) {
var data = event.lists
。。。。。。 //处理数据
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
。。。。。。
EventBus.getDefault().register(this)
}

override fun onDestroy() {
super.onDestroy()
EventBus.getDefault().unregister(this)
}

█ 相关资料

提示:这里是参考的相关文章

  1. 2018-04-04 Android ANR简介_的专栏-CSDN博客_anr
  2. 2018-05-26 Android ANR 问题第二弹------Input事件是如何超时导致ANR的_为码消得人憔悴-CSDN博客
  3. 2017-06-07 java.util.ConcurrentModificationException at java.util.ArrayList$ArrayListIterator.next(ArrayList._我的代码我做主的博客-CSDN博客
  4. 2016-04-20 Android开发笔记(八十八)同步与加锁_aqi00的博客-CSDN博客_android kotlin 同步锁
  5. 2018-12-03 TransactionTooLargeException: data parcel size xxx bytes原因与解决方案_迎风致万里的博客-CSDN博客

█ 免责声明

博主分享的所有文章内容,部分参考网上教程,引用大神高论,部分亲身实践,记下笔录,内容可能存在诸多不实之处,还望海涵,本内容仅供学习研究使用,切勿用于商业用途,若您是部分内容的作者,不喜欢此内容被分享出来,可联系博主说明相关情况通知删除,感谢您的理解与支持!

提示:转载请注明出处:
https://blog.csdn.net/ljb568838953/article/details/116142977

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: