首页 > 代码库 > android图片显示(一) ———— 关于并发,乱序问题的处理
android图片显示(一) ———— 关于并发,乱序问题的处理
GridView加适配器的方式
如果仅仅只用gridview加适配器的方法,因为加载图片是需要时间的,如果你直接在getview中加载图片的话,就会影响UI,照成滑动的时候卡顿。所以,每加载一个图片的时候,我们会开启一个额外的进程,这样就不会影响UI主线程了。
仅仅只是开启一个额外的线程会出现“乱序”的问题。也就是“并发性”的问题。
因为,当你进行滑动的时候,凡是经过的区域都会打开线程加载图片,每个线程执行完毕的时间不是固定的。只有当线程执行完毕后,才会显示在当前屏幕上。因此,当你大规模的滑动的时候,有些区域的图片还没显示就被滑走,但是他们的线程还在,所有的线程都挤到当前屏幕显示。所以被滑过的图片会在相续的显示,往往一个位置要显示好几张不同的图片(因为线程加载的时差相互覆盖),最后显示为该屏幕本来的图片。
这就是“并发性”的问题,并发性是指两个或多个事件在同一时间间隔内发生。
这样应该就能明白为什么会出现并发性问题,因为同时有多个线程再执行,我们不能保证图片的线程在被滑过之后就停止执行了。
解决并发性问题,我最近尝试的方式有两种,一种Android doc上推荐的方法,还有一个就是看guolin大神的博客上的方法。
Android doc上推荐的方式
Android doc上推荐的方法,思路是将线程与每个位置(ImageView)绑定,在图片没有加载完之前先用一个站位图片站着,若正在执行的线程不是当前图片所绑定的线程就取消掉,不再加载。这样就只有被绑定的线程才能执行,不会在一个位置上重复出现多张不同的图片。
参考链接:
http://developer.android.com/training/displaying-bitmaps/process-bitmap.html
guolin大神的setTag方式
而guolin大神用了一个ImageView.setTag(imgeUri),为每个位置绑定一张图片,其中imageUri是每张图片在本地的存储路径,既能保证不重复,也可以用它来加载图片。
参考链接:http://blog.csdn.net/guolin_blog/article/details/9526203
所以我自己试着用了setTag()写了一下,确实能解决问题。但是,图片出现的速度比guolin大神的慢了许多,比Android doc也慢了许多。想了一下,原来是因为Android doc的方法是在判断后有取消线程的执行。而我只是在线程执行之后,判断该线程所加载的图片是否与该位置绑定。没绑定就不显示。这样所有线程不管有用没有都执行了一遍,效率很低。而guolin大神的又不一样,因为他重写了OnScoll(),在滑动时,所有线程都取消,只有停下来的时候才开线程,所以,也不会有无用的线程在执行。我觉得这样也很不错!
本文出自 “什么是博客标题?” 博客,请务必保留此出处http://ysc921003.blog.51cto.com/5786498/1574182
android图片显示(一) ———— 关于并发,乱序问题的处理