前段時間找工作面試遇到幾個問題,在這分享一下
問題:在做一個列表時,每一行都有一張圖片及其它信息,每頁顯示10條,當玩命滑動列表換頁時,如何保證圖片的異步下載及時顯示屏幕內的圖片
答案1:使用異步類,下載圖片,每個異步都是並行的,所以屏幕內的圖片就可以優先顯示.
分析:這個答案,顯然面試官是不滿意的,因為假如每一個圖片都直接開啟異步線程下載,那這個線程數量是無法控制的,圖片較多時,可能會有上百個線程在后台下載圖片.
答案2:使用ExecutorService分配固定長度的線程池管理圖片下載.比如線程數為5.
分析:問題又來了,ExecutorService 使用execute .submit方法提交給線程池的線程任務,當大於設定線程數時,ExecutorService 內部有一個隊列,會自動排隊等待.直接到按排隊順序逐個執行所有線程任務.顯然,玩命滑動列表時,屏幕上的圖片不一定能夠優先顯示.因為可能此時線程池在執行滑動之前的圖片下載任務.
這兩個答案都沒有得到面試官的滿意,有沒有更好的方法呢,肯定是有,只是在面試的時候沒有想到,而且之前的工作中也沒有想到更好的辦法處理.
經過自己事后仔細思考,答案終於還是找到了
最終答案1:
自已實現線程池類,具體描述如下:
1.可以設定線程池大小,比如線程數為5,即最多同時下載5張圖片
2.實現execute方法來添加線程任務,同時根據隊列任務數量,開辟線程,最多5個,
3.內部定義一個線程任務列表,線程池按按順序獲取線程任務,順序執行
4.當一個線程執行完成后,判斷線程任務列表是否有任務,沒有,結束當前線程.
此方法具體實現可以參照:
http://blog.csdn.net/touch_2011/article/details/6914468
這里基本實現了線程管理,只是這個實現當沒有線程任務時,5個線程還會在后台默默的運行.所以修改成動態創建,釋放線程的形式即可
當玩命滑動窗口時,我們就可以控制這個線程任務列表,可以移除任務列表,或者優先排隊當前任務.這樣就可以保證屏幕的圖片優先顯示.
最終答案2:
繼續使用ExecutorService 類來管理線程,具體實現如下:
1.提前給線程池的Runnable對象中定義變量,isCancle表示是否取消執行,默認為false
2.在滑動列表時,滑動停步滑動后,當線程池內的Runnable對象isCancle設為true,即池中的任務列表全部取消,並且添加屏幕內的線程任務