androidlistview的優化
『壹』 android ListView 每個item載入大量的文本滑動會出現內存溢出咋辦咋辦
這個設計到listview優化問題。
首先,listview必須嚴格按照convertView及viewHolder格式書寫,這樣可以基本保證數據最優。
其次,如果自定義Item中有涉及到圖片等等的,一定要做圖片優化。bitmap釋放可以不做。
第三,盡量避免在BaseAdapter中使用static 來定義全局靜態變數,這個影響很大,static是Java中的一個關鍵字,當用它來修飾成員變數時,那麼該變數就屬於該類,而不是該類的實例。所以用static修飾的變數,它的生命周期是很長的,如果用它來引用一些資源耗費過多的實例(比如Context的情況最多),這時就要盡量避免使用了..
第四,盡量避免在ListView適配器中使用線程,因為線程產生內存泄露的主要原因在於線程生命周期的不可控制。
最後,如果上述你都做到的話,你的listview已經優化的很好了。針對你的問題,你的listview控制項高度是否設置為fill_parent,因為warp會導致listview滑動中無限計算自身高度。你的文本載入是否做過線程以及多次重復載入的問題處理。你的item中變數是否多次無限生成新的內存對象等等。
『貳』 android listview 按照網上的優化方法提示 空指針訪問:變數 convertView 在此位置只可為空值 就是else後
在getView 的方法中,需要每次判斷 convertView 是否為空,應為有可能listview滑動過快,導致布局來不及釋放重用。如果convertView為空,則按照正常的流程,convertView賦值,如convertView = findViewById(id);確保此值不為空。
『叄』 android listview優化幾種寫法詳細介紹
listview A view that shows items in a vertically scrolling list 。一個顯示一個垂直的滾動子項的列表視圖 在android開發中,使用listview的地方很多,用它來展現數據,成一個垂直的視圖。使用listview是一個標準的適配器模式,用數據--,界面--xml以及適配器--adapter,數據被適配器按照需要的方式展現出來,xml描寫了數據如何展現,activity中控制這些活動。 其中使用自定義的adapter,會要重寫getView方法,在getView方法產生給用戶item的視圖以及數據。 見圖: 這里有一個優化的地方,就是重用view,這樣減少內存消耗,同時加快item載入速度。 在getView中優化的地方,大家想必都非常情況,下面我總結了三種優化的寫法,請大家指正。 第一: 重用了convertView,很大程度上的減少了內存的消耗。通過判斷convertView是否為null,是的話就需要產生一個視圖出來,然後給這個視圖數據,最後將這個視圖返回給底層,呈獻給用戶。 特點:如果當前的convertView為null,則通過LayoutInflat產生一個view。View Code 第二: 上面的寫法會有一個缺點,就是每次在getVIew的時候,都需要重新的findViewById,重新找到控制項,然後進行控制項的賦值以及事件相應設置。這樣其實在做重復的事情,因為的geiview中,其實包含有這些控制項,而且這些控制項的id還都是一樣的,也就是其實只要在view中findViewById一次,後面無需要每次都要findViewById了。 下面給出第二種寫法 寫發的特點,通常有一個內部類class ViewHolder,這個ViewHolder,用來標識view中一些控制項,方便進行一些事件相應操作的設置,比如onClick等等,這樣可以不用每次都要findViewById了,減少了性能的消耗。同時重用了convertView,很大程度上的減少了內存的消耗。View Code 第三:
個人覺得這個寫法是最舒服的,最舒服的意思是看著代碼有一種很爽,看的很清晰。 特點,使用了內部類class ViewHolder、重用了convertView。 區別第二種寫法是,使用了一個臨時變數View view = convertView,然後修改view,最後返回viewView Code 以上就是集中寫法,供新手學習和總結。源代碼如下:LisViewTest.zip 根據樓下朋友提供的建議,發現還有優化的地方,最新更新如下: View Code @Override public View getView(int position, View convertView, ViewGroup parent) { View view = convertView; ViewHolder holder ; if (view == null) { view = LayoutInflater.from(context).inflate(R.layout.section_list_item1, null); holder = new ViewHolder(); holder.tv_name = (TextView)view.findViewById(R.id.contact_contactinfoitem_tv_name); holder.tv_phone = (TextView)view.findViewById(R.id.contact_contactinfoitem_tv_phoneNum); view.setTag(holder); } else { holder = (ViewHolder)view.getTag(); } ContactInfo1 confo = contacts.get(position); Log.i("my", "confo "+confo.getContactName()); if (confo != null) {//to set every item's text holder.tv_name.setText(confo.getContactName()); holder.tv_phone.setText(confo.getContact_Phone()); } return view; } <font color="\"#0000ff\""> </font>staticclass ViewHolder { TextView tv_name,tv_phone; } 注意:static class ViewHolder 這里設置ViewHolder 為static,也就是靜態的,靜態類只會在第一次載入時 會耗費比較長時間,但是後面就可以很好幫助載入,同時保證了內存中只有一個ViewHolder,節省了內存的開銷。 非常感謝大家提出建議以及大家的關注!
『肆』 優化listview 有哪些方法
首先,雖然大家都知道,還是提一下,利用好 convertView 來重用 View,切忌每次 getView() 都新建。ListView 的核心原理就是重用 View。ListView 中有一個回收器,Item 滑出界面的時候 View 會回收到這里,需要顯示新的 Item 的時候,就盡量重用回收器裡面的 View。
利用好 View Type,例如你的 ListView 中有幾個類型的 Item,需要給每個類型創建不同的 View,這樣有利於 ListView 的回收,當然類型不能太多;
盡量讓 ItemView 的 Layout 層次結構簡單,這是所有 Layout 都必須遵循的;
善用自定義 View,自定義 View 可以有效的減小 Layout 的層級,而且對繪制過程可以很好的控制;
盡量能保證 Adapter 的 hasStableIds() 返回 true,這樣在 notifyDataSetChanged() 的時候,如果 id 不變,ListView 將不會重新繪制這個 View,達到優化的目的;
每個 Item 不能太高,特別是不要超過屏幕的高度,可以參考 Facebook 的優化方法,把特別復雜的 Item 分解成若干小的 Item,特別推薦看一下這個文章:https://code.facebook.com/posts/879498888759525/fast-rendering-news-feed-on-android/
為了保證 ListView 滑動的流暢性,getView() 中要做盡量少的事情,不要有耗時的操作。特別是滑動的時候不要載入圖片,停下來再載入,這個庫可以幫助你 Glide:https://github.com/bumptech/glide
使用 RecycleView 代替。 ListView 每次更新數據都要 notifyDataSetChanged(),有些太暴力了。RecycleView 在性能和可定製性上都有很大的改善,推薦使用。
有時候,需要從根本上考慮,是否真的要使用 ListView 來實現你的需求,或者是否有其他選擇?
『伍』 android listview的生命周期,為什麼要這樣復用,有什麼好處
主要是為了減少內存的消耗,如果不進行復用,那麼創建一千個Item,就需要實例化1千個實例,會造成內存溢出。目前listview採用的策略是,只顯示一屏幕的View,當View超過一屏幕,將其移除後放到最下面進行復用。
好處:減少內存佔用,避免內存溢出。
壞處:CPU佔用會稍微高點,因為會不斷重復Iitem的溢出添加。
『陸』 安卓面試時總是被問到listview優化和布局適配不同機型,大圖片處理問題
你這是幾個問題啊,那就說說listview的優化,listview有很多的Item。一般情況下每個Item的布局是一樣的(也有不一樣的),很多情況布局中都帶有圖片,從url載入的話,就會非常耗時,非常卡。
就有了優化。
通過線程來非同步載入圖片,把Http的相關操作放在線程里,最好使用線程池來控制線程數。返回的bitmap通過Handler來更新每個Item布局上的ImageView(就是賦上圖片)。
當遇到大圖片的話,可以對圖片處理一下再使用,比如壓縮,壓縮到480*800。網上有很多關於圖片壓縮的資料。
布局的問題,我習慣用framelayout結合weight比重來整體劃分界面
『柒』 針對Android的性能優化集中哪些方面
一、概要:
本文主要以Android的渲染機制、UI優化、多線程的處理、緩存處理、電量優化以及代碼規范等幾方面來簡述Android的性能優化
二、渲染機制的優化:
大多數用戶感知到的卡頓等性能問題的最主要根源都是因為渲染性能。
Android系統每隔16ms發出VSYNC信號,觸發對UI進行渲染, 如果每次渲染都成功,這樣就能夠達到流暢的畫面所需要的60fps,為了能夠實現60fps,這意味著程序的大多數操作都必須在16ms內完成。
*關於JobScheler的更多知識可以參考http://hukai.me/android-training-course-in-chinese/background-jobs/scheling/index.html
七、代碼規范
1)for loop中不要聲明臨時變數,不到萬不得已不要在裡面寫try catch。
2)明白垃圾回收機制,避免頻繁GC,內存泄漏,OOM(有機會專門說)
3)合理使用數據類型,StringBuilder代替String,少用枚舉enum,少用父類聲明(List,Map)
4)如果你有頻繁的new線程,那最好通過線程池去execute它們,減少線程創建開銷。
5)你要知道單例的好處,並正確的使用它。
6)多用常量,少用顯式的"action_key",並維護一個常量類,別重復聲明這些常量。
7)如果可以,至少要弄懂設計模式中的策略模式,組合模式,裝飾模式,工廠模式,觀察者模式,這些能幫助你合理的解耦,即使需求頻繁變更,你也不用害怕牽一發而動全身。需求變更不可怕,可怕的是沒有在寫代碼之前做合理的設計。
8)View中設置緩存屬性.setDrawingCache為true.
9)cursor的使用。不過要注意管理好cursor,不要每次打開關閉cursor.因為打開關閉Cursor非常耗時。Cursor.require用於刷cursor.
10)採用SurfaceView在子線程刷新UI,避免手勢的處理和繪制在同一UI線程(普通View都這樣做)
11)採用JNI,將耗時間的處理放到c/c++層來處理
12)有些能用文件操作的,盡量採用文件操作,文件操作的速度比資料庫的操作要快10倍左右
13)懶載入和緩存機制。訪問網路的耗時操作啟動一個新線程來做,而不要再UI線程來做
14)如果方法用不到成員變數,可以把方法申明為static,性能會提高到15%到20%
15)避免使用getter/setter存取field,可以把field申明為public,直接訪問
16)私有內部類要訪問外部類的field或方法時,其成員變數不要用private,因為在編譯時會生成setter/getter,影響性能。可以把外部類的field或方法聲明為包訪問許可權
17)合理利用浮點數,浮點數比整型慢兩倍
18)針對ListView的性能優化,ListView的背景色與cacheColorHint設置相同顏色,可以提高滑動時的渲染性能。ListView中getView是性能是關鍵,這里要盡可能的優化。
getView方法中要重用view;getView方法中不能做復雜的邏輯計算,特別是資料庫操作,否則會嚴重影響滑動時的性能
19)不用new關鍵詞創建類的實例,用new關鍵詞創建類的實例時,構造函數鏈中的所有構造函數都會被自動調用。但如果一個對象實現了Cloneable介面,我們可以調用它的clone()方法。
clone()方法不會調用任何類構造函數。在使用設計模式(Design Pattern)的場合,如果用Factory模式創建對象,則改用clone()方法創建新的對象實例非常簡單。例如,下面是Factory模式的一個典型實現:
20)public static Credit getNewCredit() {
return new Credit();
}
改進後的代碼使用clone()方法,如下所示:
private static Credit BaseCredit = new Credit();
public static Credit getNewCredit() {
return (Credit) BaseCredit.clone();
}
上面的思路對於數組處理同樣很有用。
21)乘法和除法
考慮下面的代碼:
for (val = 0; val < 100000; val +=5) { alterX = val * 8; myResult = val * 2; }
用移位操作替代乘法操作可以極大地提高性能。下面是修改後的代碼:
for (val = 0; val < 100000; val += 5) { alterX = val << 3; myResult = val << 1; }
22)ViewPager同時緩存page數最好為最小值3,如果過多,那麼第一次顯示時,ViewPager所初始化的pager就會很多,這樣pager累積渲染耗時就會增多,看起來就卡。
23)每個pager應該只在顯示時才載入網路或資料庫(UserVisibleHint=true),最好不要預載入數據,以免造成浪費
24)提高下載速度:要控制好同時下載的最大任務數,同時給InputStream再包一層緩沖流會更快(如BufferedInputStream)
25)提供載入速度:讓服務端提供不同解析度的圖片才是最好的解決方案。還有合理使用內存緩存,使用開源的框架
引用:Android性能優化的淺談