`
cnetwei
  • 浏览: 177204 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

【转】Android系统中的UI优化

 
阅读更多

1、RelativeLayout 优于 LinearLayout

Android中最常用LinearLayout来表示UI的框架,而且也是最直观和方便的方法,例如创建一个UI用于展现Item的基本内容,如图所示:


线框示意图:


通过LinearLayout实现以上UI的代码:

<LinearLayout xmlns:
  android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="?android:attr/listPreferredItemHeight"
    android:padding="6dip">

 <ImageView
        android:id="@+id/icon"
        android:layout_width="wrap_content"
        android:layout_height="fill_parent"
        android:layout_marginRight="6dip"
        android:src="@drawable/icon" />

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="0dip"
        android:layout_weight="1"
        android:layout_height="fill_parent">

        <TextView
            android:layout_width="fill_parent"
            android:layout_height="0dip"
            android:layout_weight="1"
            android:gravity="center_vertical"
            android:text="My Application" />

        <TextView
            android:layout_width="fill_parent"
            android:layout_height="0dip"
            android:layout_weight="1" 
            android:singleLine="true"
            android:ellipsize="marquee"
            android:text="Simple application that shows how to use RelativeLayout" />
    </LinearLayout>
</LinearLayout>

 

尽管可以通过Linearlayout实现我们所预想的结果,但是在这里存在一个优化的问题,尤其是针对大量Items时。比较RelativeLayout和LinearLayout,它们在资源利用上,前者会占用更少的资源而达到相同的效果,以下是用RelativeLayout来实现同样UI的代码:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="?android:attr/listPreferredItemHeight"
    android:padding="6dip">
    <ImageView
        android:id="@+id/icon"
        android:layout_width="wrap_content"
        android:layout_height="fill_parent"
        android:layout_alignParentTop="true"
        android:layout_alignParentBottom="true"
        android:layout_marginRight="6dip"
        android:src="@drawable/icon" />

    <TextView
        android:id="@+id/secondLine"
        android:layout_width="fill_parent"
        android:layout_height="26dip" 
        android:layout_toRightOf="@id/icon"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        android:singleLine="true"
        android:ellipsize="marquee"
        android:text="Simple application that shows how to use RelativeLayout" />

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@id/icon"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:layout_above="@id/secondLine"
        android:layout_alignWithParentIfMissing="true"
        android:gravity="center_vertical"
        android:text="My Application" />
</RelativeLayout>

使用RelativeLayout时有一点需要注意,因为它内部是通过多个View之间的关系而确定UI框架,那么当其中某一个View因为某些需要调用GONE来完全隐藏掉后,会影响与其相关联的Views。Android为我们提供了一个属性 alignWithParentIfMissing 用于解决类似问题,当某一个View无法找到与其相关联的Views后将依据alignWithParentIfMissing的设定判断是否与父级View对齐。

你可以通过Hierarchy Viewer查看两种布局方案的View层级图,RelativeLayout明显优于LinearLayout。

2、UI资源的复用

定义Android Layout(XML)时,有四个比较特别的标签是非常重要的,其中有三个是与资源复用有关,分别是:<viewStub/>,<merge/>和<include/> ,可是以往我们所接触的案例或者官方文档的例子都没有着重去介绍这些标签的重要性。

<include/> :可以通过这个标签直接加载外部的xml到当前结构中,是复用UI资源的常用标签。使用方法:将需要复用xml文件路径赋予include标签的Layout属性,示例如下:

<include android:id="@+id/cell1" layout="@layout/ar01"/>
<include android:layout_width="fill_parent" layout="@layout/ar02"/>

< viewStub/ > 此标签可以使UI在特殊情况下,直观效果类似于设置View的不可见性,但是其更大的意义在于被这个标签所包裹的Views在默认状态下不会占用任何内存空间。viewStub通过include从外部导入Views元素。使用方法:通过android:layout来指定所包含的内容,默认情况下,ViewStub所包含的标签都属于visibility=GONE。viewStub通过方法inflate()来召唤系统加载其内部的Views。
示例:

<ViewStub android:id="@+id/stub"
    android:inflatedId="@+id/subTree"
    android:layout="@layout/mySubTree"
    android:layout_width="120dip"
    android:layout_height="40dip" />

<merge/> :该标签在优化UI结构时起到很重要的作用,目的是通过删减多余或者额外的层级,从而优化整个UI Layout的结构。以下将通过一个例子来了解这个标签实际所产生的作用,这样可以更直观的了解 &lt;merge/&gt;的 用法。

建立一个简单的Layout,其中包含两个Views元素:ImageView和TextView,默认状态下我们将这两个元素放在FrameLayout中。其效果是在主视图中全屏显示一张图片,之后将标题显示在图片上,并位于视图的下方。以下是xml代码:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <ImageView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" 
        android:scaleType="center"
        android:src="@drawable/golden_gate" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="20dip"
        android:layout_gravity="center_horizontal|bottom"
        android:padding="12dip"
        android:background="#AA000000"
        android:textColor="#ffffffff"
        android:text="Golden Gate" />
</FrameLayout>

以上布局的效果图如下:


启动 tools> hierarchyviewer.bat工具查看当前UI结构视图:


 我们可以很明显的看到由红色线框所包含的结构出现了两个framelayout节点,很明显这两个完全意义相同的节点造成了资源浪费(这里可以提醒大家在开发工程中可以习惯性的通过hierarchyViewer查看当前UI资源的分配情况),那么如何才能解决这种问题呢?(就当前例子是如何去掉多余的frameLayout节点),这时候就要用到 &lt;merge/&gt; 标签了,我们将上边xml代码中的framLayout替换成merge:

<merge xmlns:android="http://schemas.android.com/apk/res/android">
    <ImageView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" 
        android:scaleType="center"
        android:src="@drawable/golden_gate" />
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="20dip"
        android:layout_gravity="center_horizontal|bottom"
        android:padding="12dip"
        android:background="#AA000000"
        android:textColor="#ffffffff"
        android:text="Golden Gate" />
</merge>

运行程序后在Emulator中显示的效果是一样的,可是通过hierarchyviewer查看的UI结构是有变化的,当初多余的 FrameLayout节点被合并在一起了,或者可以理解为将merge标签中的子集直接加到Activity的FrameLayout根节点下了。(这里需要提醒大家注意:所有的Activity视图的根节点都是FrameLayout)。如果你所创建的Layout并不是用FramLayout作为根节点(而是应用LinerLayout等定义root标签),就不能应用上边的例子 通过merge来优化UI结构了。

除了上边的例子外,meger还有另外一个用法:当应用Include或者ViewStub标签从外部导入xml结构时,可以将被导入的xml用merge作为根节点,这样当被嵌入父级结构中后可以很好的将它所包含的子集融合到父级结构中,而不会出现冗余节点。
另外有两点需要特别注意:
A.<merge/>只可以作为xml layout的根节点;
B.当需要扩充的xml layout本身是由merge作为根节点的话,需要将被导入的xml layout置于viewGroup中,同时需要设置attachToRoot为True。(更多说明请参见inflate()文档)

3、使用工具 hierarchyViewer 和 Layout Opt.

前边已经介绍了如何通过Layout优化系统资源,减少不必要的资源占用。基于如何在合理利用资源的前提下,更进一步的提升视觉表现力。这里所提到的视觉表现力并不是指直观所看到的视觉效果,而是性能的提升。
这里将包含两个主要内容:

  • Drawing(绘制的刷新率)
  • Startup Time (启动Activities的时间)

以上两个性能的优化都将依赖于 Window backGround drawable功能设置。
通过Window backGround标识会对部分人产生一定的误解,其实每次通过setContentView()来显示预先配置的界面时,Android仅仅是将你所创建的Views添加到Activiy的Window中。而且这个Window并不仅仅包含你所创建的Views,还包括Android为Activity预置的元素。通过Emulator运行你的程序,然后通过Hierarchy Viewer查看当前程序UI架构Root节点 DecorView,这个是Android额外添加的最顶层的节点。



实际上Window background drawable是由DecorView决定的。可以在Activity中调用getWindow().setBackgroundDrawable()方法来设置DecorView的background drawable。这里要特别注意这个方法是针对当前版本的Android平台,以后可能会因为版本的更新或不同的硬件设备而改变。(目前我们仅针对 G1,如果在其它环境下测试需要小心验证)
如果目前正在使用android默认的标准Themes,那么在调用getWindow().setBackgroundDrawable()方法之后,这个background drawable将会影响你的activities。通过一个例子来直观的比较性能提升的效果:

通过上边这个截图可以看到保持activity的redraw模式下,当前的FPS为39帧 /每秒,大概相当于25毫秒/每帧。由于这个例子中将ImageView设为全屏显示,并且完全覆盖了activity的背景,所以background drawable占用了不必要的计算资源。下边创建一个新的Theme并且应用在Activity中,创建res/values/theme.xml, XML的内容:

<resources>
    <style name="Theme.NoBackground" parent="android:Theme">
        <item name="android:windowBackground">@null</item>
    </style>
</resources>

同时也需要修改AndroidMainfest.xml文件,将上边所创建的Theme应用到Activity中,格式为:

<application android:icon="@drawable/icon" android:label="@string/app_name">
	<activity android:name=".EggImageViewer"
     android:label="@string/app_name"
     android:theme="@style/Theme.NoBackground">
 	    <intent-filter>
	        <action android:name="android.intent.action.MAIN" />
	        <category android:name="android.intent.category.LAUNCHER" />
	    </intent-filter>
	</activity>
</application>

(也可以将Theme应用于<Application />标签中)完成上边的修改后,再来看看当前的FPS发生了什么变化:

 

FPS可以增大到60+,性能得到如此大的提升,是不是比较难以置信呢?由此可以明白当应用MapView或者WebView全屏显示的应用程序时,可以借用这个简单设置的方法,来提升整体的性能。
通过上边的例子可以直观的了解window background drawable的优化方法,并且根据比较可以很明显的看到设置前后的性能对比,希望这个简单的技巧可以给你的应用带来帮助。
另外基于这个技巧的应用,还可以延展出另外一个优化功能。对于某些需要全屏显示的应用程序,可以通过Theme定义Window’s background的图片,从而提高Activity的启动速度。毕竟无需建立一个ImageView作为自定义的背景,而重复叠加在Activity window background。
实现方法:
创建 res/drawable/background_res.xml

<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@drawable/shelf_panel"
    android:tileMode="repeat" />

创建res/values/theme.xml

<resources>
    <style name="Theme.Shelves" parent="android:Theme">
        <item name="android:windowBackground">@drawable/background_res</item>
        <item name="android:windowNoTitle">true</item>
    </style>
</resources>

往往一些看似简单的方法,却能起到非常大的作用。还希望大家在实践中能不断的挖掘出非常实用的技巧,然后与你周围的人共享你的发现,同时在大家共同的见证下可以完善你的想法!

源码附件:

 

 

 

 

  • 大小: 6.4 KB
  • 大小: 2.4 KB
  • 大小: 63.6 KB
  • 大小: 7.1 KB
  • 大小: 24.4 KB
  • 大小: 6.8 KB
  • 大小: 6.8 KB
分享到:
评论

相关推荐

    android 7.0 SystemUI

    在Android系统架构中,SystemUI位于应用层与系统服务层之间,它提供了通知中心、状态栏、快速设置面板、锁屏界面以及各种系统级别的交互控件。深入理解SystemUI的源代码对于开发者优化系统UI性能、自定义系统行为或...

    Android8.1 SystemUI源码

    在Android系统中,SystemUI是用户界面的核心组成部分,它负责管理状态栏、通知中心、快速设置等关键功能。本文将深入探讨Android 8.1版本的SystemUI源码,介绍其结构、工作原理以及如何利用提供的gradle配置进行开发...

    Android UI 优化之merge标签的使用

    在Android开发中,UI性能优化是一项至关重要的任务,它直接影响到应用的用户体验。"merge"标签是Android XML布局文件中的一个特殊元素,主要用于减少视图层次,提高布局加载效率,从而提升UI性能。本文将深入探讨...

    Android 性能优化之UI优化源码

    在Android应用开发中,UI优化是一项至关重要的任务,它直接影响到用户体验和应用的性能。本文将深入探讨Android UI优化的源码层面,帮助开发者更好地理解并实现高效的UI更新与渲染。 首先,我们要明白Android UI的...

    uiautomatorviewer工具更新优化适配Android8.0以上系统

    随着Android系统的不断迭代,工具的兼容性和功能也需要随之升级。在面对Android 8.0(Oreo)及以上版本时,UIAutomatorViewer遇到了一些挑战,但通过特定的更新和优化,这些问题已经得到了解决。 UIAutomatorViewer...

    Android性能优化.pdf

    ANR(Application Not Responding)是指应用程序无响应,当用户界面无法及时响应用户的输入事件或者系统服务请求时,Android系统将提示ANR错误。主要分为四类:InputDispatching Timeout、BroadcastQueue Timeout、...

    android 模仿360UI

    10. **适配不同Android版本**:360UI需要兼容多版本的Android系统。开发者需要了解如何使用Support Library或AndroidX库来确保向后兼容性。 通过深入研究"android 模仿360UI"这个项目,开发者不仅可以提升自己的UI...

    Android 8.0 系统自带 SystemUI

    在SystemUI的源码中,你可以深入理解Android 8.0是如何实现状态栏和导航栏的动态行为、通知系统的优化、多窗口模式的改进等。源码中包含了大量Java和Kotlin类,如BroadcastReceivers、Services、Activities等,它们...

    Android源码——UI界面源码.rar

    在Android系统中,UI界面是用户与应用交互的桥梁,其设计和实现直接影响到应用的用户体验。本资源“Android源码——UI界面源码.rar”很可能是提供了Android UI设计的一些关键源代码,帮助开发者深入理解Android UI的...

    android 小米UI 自定义音量

    小米UI是小米公司为Android设备定制的用户界面,它在原生Android系统的基础上进行了一系列优化和改进,其中包括对音量控制的自定义设计。本文将深入探讨如何在Android原生系统中移植小米UI的自定义音量组件,并介绍...

    010_android 之UI线程阻塞及其优化

    Android系统为了保证用户界面的流畅性,规定所有的UI操作都必须在UI线程中执行。这是因为Android的渲染机制要求每一帧画面的绘制必须在16毫秒内完成,以达到60fps的流畅体验。如果UI线程执行耗时任务,就可能导致...

    Android things简单的UI

    这个平台基于Android系统,但针对物联网设备进行了优化,简化了硬件交互和固件更新流程。Android Things提供了一个稳定、安全的基础,用于构建各种智能设备,如智能家居控制器、智能音箱、工业自动化设备等。 **UI...

    Android 仿微信UI源码

    8. **动画与过渡效果**:微信UI中的动画效果丰富,如消息气泡的弹出、按钮的按压效果等,这些都是通过Android的动画系统实现的。 9. **图片选择器和上传**:微信支持选择本地图片或拍摄新照片,这通常涉及到Intent...

    android原生systemUI源码4.2.2

    在Android系统中,SystemUI是用户界面的重要组成部分,它包含了状态栏、通知栏、快速设置面板等关键元素的实现。Android 4.2.2版本的SystemUI源码为我们提供了深入理解Android UI系统工作原理的宝贵资料。接下来,...

    Android-聊天UIDemo支持文字表情语音图片的聊天UI界面

    在Android开发中,构建一个功能丰富的聊天用户界面(UI)是相当常见的需求,尤其是在社交应用、团队协作工具或者在线客服系统中。这个“Android-聊天UIDemo支持文字表情语音图片的聊天UI界面”是一个示例项目,它...

    android项目整体UI框架

    Fragment是Android系统提供的一种组件,它可以承载一部分用户界面并可以在Activity中动态添加、移除或替换。在大型项目中,通常会用多个Fragment来构建多视图界面,比如在底部任务栏的各个选项中展示不同的Fragment...

    android ui源码:自己设计的一个精美布局

    Android UI设计遵循Material Design规范,它提供了一套系统化的视觉语言,包括颜色、形状、动画和组件设计。理解这些基本元素可以帮助我们创建出符合平台标准且吸引人的界面。 2. **自定义布局组件**: 在Android...

    原生android SystemUI源码

    原生Android SystemUI源码是理解Android系统运行机制的关键部分,尤其对于系统级开发者和定制化ROM的制作人员来说,它是深入学习Android操作系统界面交互逻辑的重要资源。在Android 4.0(Ice Cream Sandwich,简称...

    android-UI.zip_android_android ui_android ui_android 漂亮_安卓好看ui

    下面将详细讨论Android UI设计中的关键知识点,以及如何利用这些资源提升你的应用设计。 1. **Material Design**: Android UI设计主要遵循Google的Material Design规范,这是一种现代、统一的设计语言,强调层次感...

    Android 4.4 SystemUI

    首先,让我们探讨一下SystemUI在Android系统中的作用。SystemUI主要包括以下几个组件: 1. **通知栏(Notification Bar)**:显示应用程序的通知,用户可以通过下拉通知栏查看并管理这些通知。开发者可以学习如何...

Global site tag (gtag.js) - Google Analytics