提高android应用的效率--主要讲解listview的优化

简介:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
Adapter是listview和数据源间的中间人。
 
当每条数据进入可见区域时,adapter的getview()会被调用,返回代表具体数据的视图。触摸滚动时,频繁调用。支持成百上千条数据。
 
下面为显示每条数据的xml文件:
 
<LinearLayout
xmlns:android= "http://schemas.android.com/apk/res/android"
android:orientation= "horizontal" >
<ImageView android:id= "@+id/icon"
android:layout_width= "48dip"
android:layout_height= "48dip"  />
<TextView android:id= "@+id/text"
android:layout_gravity= "center_vertical"
android:layout_width= "0dip"
android:layout_weight= "1.0"
android:layout_height= "wrap_content"  />
</LinearLayout>
 
1 。最简单的方法,最慢且最不实用
 
public  View getView( int  pos, View convertView,
ViewGroup parent){
View item = mInflater.inflate(R.layout.list_item,  null );
((TextView) item.findViewById(R.id.text)).
setText(DATA[pos]);
((ImageView) item.findViewButId(R.id.icon)).
setImageBitmap((pos &  1 ) ==  1  ? mIcon1 : mIcon2);
return  item;
}
 
2 。利用convertview回收视图,效率提高 200 %。
 
public  View getView( int  pos, View convertView,
ViewGroup parent){
if  (convertView ==  null ) {
convertView = mInflater.inflate(
R.layout.list_item,  null );
}
((TextView) convertView.findViewById(R.id.text)).
setText(DATA[pos]);
((ImageView) convertView.findViewButId(R.id.icon)).
setImageBitmap((pos &  1 ) ==  1  ? mIcon1 : mIcon2);
return  convertView;
}
 
3 。利用viewholder模式,效率在提高 50 %
 
static  class  ViewHolder {
TextView text;
ImageView icon;
}
 
  
 
public  View getView( int  pos, View convertView, ViewGroup parent){
ViewHolder holder;
if  (convertView ==  null ) {
convertView = mInflater.inflate(R.layout.list_item,  null );
holder =  new  ViewHolder();
holder.text = (TextView) convertView.findViewById(
R.id.text));
holder.icon = (ImageView) convertView.findViewButId(
R.id.icon));
convertView.setTag(holder);
else  {
holder = (ViewHolder) convertView.getTag();
}
holder.text.setText(DATA[pos]);
holder.icon.setImageBitmap((pos &  1 ) ==  1  ? mIcon1 : mIcon2);
return  convertView;
}
 
adapter更新效率比较:
 
1 的更新不到 10  frames/second
 
2 的更新接近 30  frames/second
 
3 的更新接近 40  frames/second
 
背景和图像
 
视图背景图像总会填充整个视图区域
 
1 。图像尺寸不合适会导致自动缩放
 
2 。避免实时缩放
 
3 。最好预先缩放到视图大小
 
originalImage = Bitmap.createScaledBitmap(
originalImage,  // 􂿕缩放图像
view.getWidth(),  // 视图宽度
view.getHeight(),  // 视图高度
true );  // 􀽮线性过滤器
 
1 的效率接近 25  frames/second
 
2 的效率接近 50  frames/second
 
默认情况下, 窗口有一个不透明的背景
 
有时可以不需要
 
     -􁭱􃧗最高层的视图是不透明的
 
     - 􁭱 最高层的视图覆盖整个窗口
 
layout_width = fill_parent
layout_height = fill_parent
 
更新看不见的背景是浪费时间
 
删除窗口背景:
 
1 。修改编码
 
public  void  onCreate(Bundle icicle){
super .onCreate(icicle);
setContentView(R.layout.mainview);
// 删除窗口背景
getWindow().setBackgroundDrawable( null );
...
 
2 。修改xml
 
  
 
首先确定你的res/values/styles.xml有
 
<resources>
<style name= "NoBackgroundTheme"  parent= "android:Theme" >
<item name= "android:windowBackground" > @null </item>
</style>
</resources>
 
然后编辑androidmainfest.xml
 
<activity android:name= "MyApplication"
android:theme= "@style/NoBackgroundTheme" >
...
</activity>
 
更新请求
 
当屏幕需要更新时,调用invalidate()方法,简单方便,但是更新了整个视图,代价太高。
 
最好先找到无效区域,然后调用
 
invalidate(Rect dirty);
invalidate( int  left,  int  top,  int  right,  int
bottom);
 
视图和布局
 
如果一个窗口包含很多视图,启动太慢,绘制时间长,用户界面反应速度很慢
 
解决方法:
 
1 。使用textview的复合drawable减少层次
 
<TextView
android:layout_width= "wrap_content"
android:layout_height= "wrap_content"
android:text= "@string/hello"
android:drawableLeft= "@drawable/icon" />
 
2 。使用viewstuf延迟展开视图
 
     在xml文件中定义viewstuf
 
<ViewStub android:id =  "@+id/stub_import"
android:inflatedId= "@+id/panel_import"
android:layout= "@layout/progress_overlay"
android:layout_width= "fill_parent"
android:layout_height= "wrap_content"
android:layout_gravity= "bottom" />
 
   在需要展开视图时,
 
findViewById(R.id.stub_import).setVisibility(View.VISIBLE);
// 或者
View importPanel = ((ViewStub)
findViewById(R.id.stub_import)).inflate();
 
3 。使用<merge>合并中间视图
 
默认情况下,布局文件的根作为一个节点,加入到父视图中,如果使用merge可以避免根节点
 
<merge xmlns:android =
"http://schemas.android.com/apk/res/android" >
<! -- Content -->
</merge>
 
4 。使用ralativelayout减少层次
 
<RelativeLayout xmlns:android= "http://schemas.android.com/apk/res/android"
android:layout_width= "fill_parent"  android:layout_height= "wrap_content" >
<ImageView android:id= "@+id/icon"
android:layout_width= "48dip"  android:layout_height= "48dip"
android:layout_alignParentLeft= "true"
android:layout_centerVertical= "true" />
<TextView android:layout_width= "wrap_content"
android:layout_height= "wrap_content"  android:id= "@+id/text_line1"
android:layout_alignParentTop= "true"
android:layout_toRightOf= "@id/icon" />
<TextView android:layout_width= "wrap_content"
android:layout_height= "wrap_content"  android:id= "@+id/text_line2"
android:layout_toRightOf= "@id/icon"
android:layout_below= "@id/text_line1" />
<Checkbox android:id= "@+id/star"
android:layout_width= "48dip"  android:layout_height= "48dip"
android:layout_alignParentRight= "true"
android:layout_centerVertical= "true" />
</RelativeLayout>
 
5 .使用自定义视图
 
class  CustomView  extends  View {
@Override
protected  void  onDraw(Canvas canvas) {
// 加入你的绘图编码
}
@Override
protected  void  onMeasure( int  widthMeasureSpec,
int  heightMeasureSpec) {
// 计算视图的尺寸
setMeasuredDimension(widthSpecSize, heightSpecSize);
}
}
 
6  使用自定义布局
 
class  GridLayout  extends  ViewGroup {
@Override
protected  void  onLayout( boolean  changed,  int  l,  int  t,
int  r,  int  b) {
final  int  count = getChildCount();
for  ( int  i= 0 ; i < count; i++) {
final  View child = getChildAt(i);
if  (child.getVisibility() != GONE) {
// 计算子视图的位置
child.layout(left, top, right, bottom);
}
}
}
}
 
内存分配
 
在性能敏感的代码里,避免创建java对象
 
1 。测量 onmeasure()
 
2 。布局onlayout()
 
3 。绘图 ondraw() dispatchdraw()
 
4 。事件处理 ontouchevent() dispatchtouchevent()
 
5 。adapter: getview() bindview()
 
强行限制(适用调试模式)
 
int  prevLimit = - 1 ;
try  {
prevLimit = Debug.setAllocationLimit( 0 );
// 执行不分配内存的代码
catch  (dalvik.system.AllocationLimitError e) {
// 如果代码分配内存, Java 虚拟机会抛出错误
Log.e(LOGTAG, e);
finally  {
Debug.setAllocationLimit(prevLimit);
}
 
管理好对象:
 
1 。适用软引用:内存缓存的最佳选择
 
2 。适用弱引用:避免内存泄露
 
内存缓存:
 
private  final  HashMap<String, SoftReference<T>> mCache;
public  void  put(String key, T value) {
mCache.put(key,  new  SoftReference<T>(value));
}
public  T get(String key, ValueBuilder builder) {
T value =  null ;
SoftReferece<T> reference = mCache.get(key);
if  (reference !=  null ) {
value = reference.get();


本文转自java豆子博客园博客,原文链接:http://www.cnblogs.com/error404/archive/2011/08/03/2126682.html,如需转载请自行联系原作者
相关文章
|
4天前
|
JSON Java Android开发
探索安卓开发之旅:打造你的第一个天气应用
【10月更文挑战第30天】在这个数字时代,掌握移动应用开发技能无疑是进入IT行业的敲门砖。本文将引导你开启安卓开发的奇妙之旅,通过构建一个简易的天气应用来实践你的编程技能。无论你是初学者还是有一定经验的开发者,这篇文章都将成为你宝贵的学习资源。我们将一步步地深入到安卓开发的世界中,从搭建开发环境到实现核心功能,每个环节都充满了发现和创造的乐趣。让我们开始吧,一起在代码的海洋中航行!
|
4天前
|
存储 搜索推荐 Java
打造个性化安卓应用:从设计到实现
【10月更文挑战第30天】在数字化时代,拥有一个个性化的安卓应用不仅能够提升用户体验,还能加强品牌识别度。本文将引导您了解如何从零开始设计和实现一个安卓应用,涵盖用户界面设计、功能开发和性能优化等关键环节。我们将以一个简单的记事本应用为例,展示如何通过Android Studio工具和Java语言实现基本功能,同时确保应用流畅运行。无论您是初学者还是希望提升现有技能的开发者,这篇文章都将为您提供宝贵的见解和实用的技巧。
|
8天前
|
搜索推荐 开发工具 Android开发
打造个性化Android应用:从设计到实现的旅程
【10月更文挑战第26天】在这个数字时代,拥有一个能够脱颖而出的移动应用是成功的关键。本文将引导您了解如何从概念化阶段出发,通过设计、开发直至发布,一步步构建一个既美观又实用的Android应用。我们将探讨用户体验(UX)设计的重要性,介绍Android开发的核心组件,并通过实际案例展示如何克服开发中的挑战。无论您是初学者还是有经验的开发者,这篇文章都将为您提供宝贵的见解和实用的技巧,帮助您在竞争激烈的应用市场中脱颖而出。
|
10天前
|
算法 Java 数据库
Android 应用的主线程在什么情况下会被阻塞?
【10月更文挑战第20天】为了避免主线程阻塞,我们需要合理地设计和优化应用的代码。将耗时操作移到后台线程执行,使用异步任务、线程池等技术来提高应用的并发处理能力。同时,要注意避免出现死循环、不合理的锁使用等问题。通过这些措施,可以确保主线程能够高效地运行,提供流畅的用户体验。
21 2
|
13天前
|
Java API Android开发
安卓应用程序开发的新手指南:从零开始构建你的第一个应用
【10月更文挑战第20天】在这个数字技术不断进步的时代,掌握移动应用开发技能无疑打开了一扇通往创新世界的大门。对于初学者来说,了解并学习如何从无到有构建一个安卓应用是至关重要的第一步。本文将为你提供一份详尽的入门指南,帮助你理解安卓开发的基础知识,并通过实际示例引导你完成第一个简单的应用项目。无论你是编程新手还是希望扩展你的技能集,这份指南都将是你宝贵的资源。
42 5
|
13天前
|
移动开发 Dart 搜索推荐
打造个性化安卓应用:从零开始的Flutter之旅
【10月更文挑战第20天】本文将引导你开启Flutter开发之旅,通过简单易懂的语言和步骤,让你了解如何从零开始构建一个安卓应用。我们将一起探索Flutter的魅力,实现快速开发,并见证代码示例如何生动地转化为用户界面。无论你是编程新手还是希望扩展技能的开发者,这篇文章都将为你提供价值。
|
23天前
|
调度 Android开发 开发者
构建高效Android应用:探究Kotlin多线程优化策略
【10月更文挑战第11天】本文探讨了如何在Kotlin中实现高效的多线程方案,特别是在Android应用开发中。通过介绍Kotlin协程的基础知识、异步数据加载的实际案例,以及合理使用不同调度器的方法,帮助开发者提升应用性能和用户体验。
40 4
|
23天前
|
编解码 Android开发 UED
构建高效Android应用:从内存优化到用户体验
【10月更文挑战第11天】本文探讨了如何通过内存优化和用户体验改进来构建高效的Android应用。介绍了使用弱引用来减少内存占用、懒加载资源以降低启动时内存消耗、利用Kotlin协程进行异步处理以保持UI流畅,以及采用响应式设计适配不同屏幕尺寸等具体技术手段。
45 2
|
5天前
|
安全 Android开发 iOS开发
深入探索iOS与Android系统的差异性及优化策略
在当今数字化时代,移动操作系统的竞争尤为激烈,其中iOS和Android作为市场上的两大巨头,各自拥有庞大的用户基础和独特的技术特点。本文旨在通过对比分析iOS与Android的核心差异,探讨各自的优势与局限,并提出针对性的优化策略,以期为用户提供更优质的使用体验和为开发者提供有价值的参考。
|
27天前
|
Android开发
Android开发显示头部Bar的需求解决方案--Android应用实战
Android开发显示头部Bar的需求解决方案--Android应用实战
19 0