小言_互联网的博客

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

425人阅读  评论(0)

█ 【安卓学习之常见问题】从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


转载:https://blog.csdn.net/ljb568838953/article/details/116142977
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场