`
Teok
  • 浏览: 150736 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

AndroidUI学习

阅读更多
没搞过swing,也没丰富经验的j2me ui,ios的ui也没折腾过。说实话UI这块看得很辛苦,4天里断断续续的看,至今也没从我想象的高度来认识Android UI的设计细节。

没看明白归没看明白,至少还是有一些问题的。老样子,仔细分析冷冰博文第十二和十三篇: Android GEWS之Android窗口管理之基本架构 和 Android GEWS窗口管理。

下面是我想到的几点:

1. 按照冷冰的分析,为什么在Activity和WindowManager之间会存在一个Session的概念?

先看一张图:

再看Wiki上对Session的解释:

In computer science, in particular networking, a session is a semi-permanent interactive information interchange, also known as a dialogue, a conversation or a meeting, between two or more communicating devices, or between a computer and user (see Login session). A session is set up or established at a certain point in time, and torn down at a later point in time. An established communication session may involve more than one message in each direction. A session is typically, but not always, stateful, meaning that at least one of the communicating parts needs to save information about the session history in order to be able to communicate, as opposed to stateless communication, where the communication consists of independent requests with responses.

所以Session是一种半永久性的互动信息交换(直译,以免翻译错误导致误解)。

再看冷冰的一段话:

Activity建立一个主窗口后,在将主窗口添加到WindowManager时,首先要建立WindowManager代理对象,并打开一个会话(实现IWindowSession AIDL接口),并维持该会话。Activity将通过该会话与WindowManager建立联系,这个Session是C/S体系的基础,Client通过WindowSession将window加入到Window Manager中。

由此看来,C/S结构中,C与S不是能直接通信的(至少在当前场景下),所以Session就像一个中间件,连接一个Activity与WindowManager,使两者可以进行通讯(互动信息的交换)。在J2EE中,我所见到的Login Session也差不多是这样,每个客户端(Browser)和服务器(Server,Server就像这里的WindowManager,单例的)都存在一个维护通信现场和提供通信结构的session,当客户端的浏览器退出或者网页被关闭或者用户主动logout,那么session manager会立即或在未来某个时间关掉这个这个session(可以依据的一些session过期特征,例如过期时间)。

为了证明Session的交换特性,我试图找到Android IWindowSession这个interface的源文件,可惜没找到,只能从class文件来大概了解一下:
// Method descriptor #10 (Landroid/view/IWindow;Landroid/view/WindowManager$LayoutParams;ILandroid/graphics/Rect;Landroid/view/InputChannel;)I

public abstract int add(android.view.IWindow arg0, android.view.WindowManager.LayoutParams arg1, int arg2, android.graphics.Rect arg3, android.view.InputChannel arg4) throws android.os.RemoteException;

  // Method descriptor #16 (Landroid/view/IWindow;)V

public abstract void remove(android.view.IWindow arg0) throws android.os.RemoteException;
单从这两个方法就可以看出,IWindowSession接口的确定义了一些交互性的方法(add、remove等)。从设计模式的角度来看,有点适配器(Adapter)的味道(Android中有很明显的Adapter,各种ListView都会用到:它完成了从数据到视图的一个适配)。从应用开发者的角度来看,Session是无需关心的。

补充或者更正:

刚看到IWindowSession实际上是一个AIDL定义的接口,那么就是说,它工作于在linux平台层,而且从
public static IWindowSession getWindowSession(Looper mainLooper) {
        synchronized (mStaticInit) {
            if (!mInitialized) {
                try {
                    InputMethodManager imm = InputMethodManager.getInstance(mainLooper);
                    sWindowSession = IWindowManager.Stub.asInterface(
                            ServiceManager.getService("window"))
                            .openSession(imm.getClient(), imm.getInputContext());
                    mInitialized = true;
                } catch (RemoteException e) {
                }
            }
            return sWindowSession;
        }
    }

这段代码来看,IWindowSession实际上又是单例的(这跟J2EE中的session和wiki中定义的有些不同)。如果是单例的话,那就意味着这个session是长久的,它至少在android linux启动时被生成,关闭时被销毁,它不会被某个与之相关的WindowManager或者ViewRoot的存亡影响,WM也是单例的,所以它与WM一对一,与VR一对多。因此,android的设计者引入这样一个叫做IWindowSession的东西,并不意味者它就是一个session,也许它只有一些特征相似而已(说实在的,这里比较复杂了,我的小脑瓜实在转不过来,等慢慢理解了再回过头来补充)。

2. View组织结构

UI界面通常是一个树形结构,Android也不例外。那么这棵树的根节点是谁呢?是ViewRoot,这是一个不公开的类。给出两个比较明显的是“根”的特征:

1.继承ViewParent接口

2. ViewParent getParent方法返回null

在ViewRoot之下,冷冰认为有一个DecorView,它在具体的Window中负责组织各个具体View和ViewGroup(就是View或者ViewGroup的实现者)。但是我没找到这个DecorView,但是我也认同这个DecorView的存在,因为两点:

1.ViewRoot实现ViewParent但不实现ViewGroup,所以它不能组织子View元素;

2.ViewRoot持有一个IWindowSession,而这个session正是Activity与外界(WindowManager)交互的桥梁

所以ViewRoot作为根节点它同时肩负着与外界通信的能力,至于组织View结构这类工作就托付给另外一个抽象(DecorView)去做吧。现在来看冷冰的这张图就不难理解了:

ViewRoot并不属于Window空间,因为它更倾向于是Activity对外的桥梁,包括Window也是通过调用ViewRoot的门面方法(方法的实现者其实是IWindowSession的实现者,这点代码中可以印证)而加入到WindowManager中的。

在看ViewParent接口时我注意到一个api:
/**
     * Find the nearest view in the specified direction that wants to take focus
     *
     * @param v The view that currently has focus
     * @param direction One of FOCUS_UP, FOCUS_DOWN, FOCUS_LEFT, and FOCUS_RIGHT
     */
    public View focusSearch(View v, int direction);

是的,在UI结构中,focus路径是要关心的一个问题。我忘记了fclient中如何设计解决这个问题的(代码如果能找到的话再补充),在Android中下面的一张图就表述的很清晰:

要找到View22,首先从根部遍历(当然这个根部应该是DecorView,它本身就是一个ViewGroup),找到那个存在focused view的ViewGroup11,然后再在ViewGroup11中找到mFocused(源码中该私有变量的说明原文是这样的:The view contained within this ViewGroup that has or contains focus.) 。

3.事件分发

其实ViewRoot也是一个Handler,它处理或者分发了来自那边(WindowManager)的消息(包括焦点切换、key和pointer事件、die、checkfocus等等很多)。消息在handleMessage内经过switch case语句按照分支进行分发之后,由具体的处理方法去完成剩下的工作。我这里只举一个例子(key event的处理)来帮助自己对这个流程的理解。先看一段代码:
private void deliverKeyEvent(KeyEvent event, boolean sendDone) {
        // If mView is null, we just consume the key event because it doesn't
        // make sense to do anything else with it.
        boolean handled = mView != null
                ? mView.dispatchKeyEventPreIme(event) : true;
        if (handled) {
            if (sendDone) {
                finishInputEvent();
            }
            return;
        }
        // If it is possible for this window to interact with the input
        // method window, then we want to first dispatch our key events
        // to the input method.
        if (mLastWasImTarget) {
            InputMethodManager imm = InputMethodManager.peekInstance();
            if (imm != null && mView != null) {
                int seq = enqueuePendingEvent(event, sendDone);
                if (DEBUG_IMF) Log.v(TAG, "Sending key event to IME: seq="
                        + seq + " event=" + event);
                imm.dispatchKeyEvent(mView.getContext(), seq, event,
                        mInputMethodCallback);
                return;
            }
        }
        deliverKeyEventToViewHierarchy(event, sendDone);
    }

要被处理的消息被包装成KeyEvent并传递进来,首先一个mView会试图处理这个事件,mView又是什么呢,在给mView赋值的setView方法是这么说的:We have one child.那么,这个child就可能就是前面所指的DecorView(但是后来又发现好像不是),所以除过IME(输入法)的事件都给mView去处理(并且如果mView为null,那么该事件会被consume掉),它爱分发分发,爱处理处理,IME的事件呢,则在ViewRoot里面处理,就是第二个if块里面的代码,当然最后deliverKeyEventToViewHierarchy方法也只在处理IME事件时才生效。但实际上在IME之前处理键事件的情况很少,详见dispatchKeyEventPreIme方法的注释.

根据代码我大概得知mView是其实是与当前这个message有直接关系的那个View,所以mView的赋值,应该是由WindowManager这样的设施来负责,因为只有它们才能具体知道用户点击了哪个View。的下面的代码不分析了,很复杂也很多。。总体上感觉,Android事件处理的分发路径就像投石模型(把石头扔到水里,石头一直是下沉的,HTML的事件模型是冒泡),从根节点一直往下,不过这个只是感觉,并不准确(等我发现理解有误时再改正吧,主要是我发现为了举这个例子,我快掉进细节的泥沼了,得赶紧脱身才是,:))。

最后再来看一张图:

结合源码看这段,感觉精妙的很(冷冰大牛啊)。WindowManager、View、ViewRoot、WindowSession等的交互关系也是很准确,只是图略显凌乱,刚开始看不知所云,我也是结合代码看了好久才明白其含义。只是图中没有给清除左下角这些View到底是什么,要不我就比较确定的知道mView了。

4.在Android UI中有没有显示层这样的概念(就像html中的z-index),如果有,那它是怎么处理的?

有一个类似的概念叫做Z-order,在Window Service(注意:Android中I开头的接口通常是aidl接口,它们通常都继承自android.os.IInterface 接口,所以这里指的window service就是实现某个具体aidl接口的远程service),这个order也由该service来维护。这个我还没找到具体的代码来印证。
  • 大小: 12.1 KB
  • 大小: 26.3 KB
  • 大小: 36.6 KB
分享到:
评论

相关推荐

    Android UI学习

    "Android UI学习"的主题涵盖了如何构建类似米聊、口信和微信等流行即时通讯应用的界面和功能。 首先,让我们从基础开始。在Android开发中,UI通常是通过XML布局文件来设计的。例如,`activity_main.xml`这样的文件...

    Android UI控件组件库集合【源码】

    通过学习和理解这些源码,开发者不仅可以快速实现所需功能,还可以深入理解Android UI机制,提高开发效率。同时,这些控件可以作为模块化组件,方便在不同项目中复用,降低开发成本。 总的来说,这个"Android UI...

    《Android UI设计》PDF

    项目驱动 紧密结合初学者的学习习惯和认知规律,采用了大量简单而又实用的设计案例分析UI设计的基本理念。 强化技能 以移动UI设计师的核心岗位能力统筹全书的编写,代码设计突出项目开发的实战性与健壮性。 遵守...

    Android UI基础教程 高清带标签pdf

     《AndroidUI基础教程》是一本Android用户界面设计的基础入门图书。全书从最基础的技术概念开始介绍,深入讨论了UI设计的各项技术,涵盖了为应用程序创建UI的所有内容。本书不仅会告诉读者创建灵活布局的最佳方法,...

    android UI界面开发图片

    在Android平台上进行UI界面开发时,图片资源是至关重要的元素,它们不仅决定了应用的视觉吸引力,也直接影响用户体验。本文将围绕“Android UI界面开发图片”这一主题,深入探讨相关知识点,帮助开发者创建出美观且...

    android ui基础教程

    ### Android UI基础教程知识点概述 #### 一、Android UI基础知识 **1.1 Android UI简介** Android UI(用户界面)是Android应用程序与用户交互的主要方式。一个良好的UI设计能够极大地提升用户体验,使得用户更...

    Android UI 基础教程

    这份教程虽然以英文编写,但其内容深入浅出,对于学习Android UI设计的人来说具有很高的参考价值。 Android UI主要由各种组件、布局和主题等元素组成,这些元素共同构成了应用程序的视觉框架。在本教程中,你将了解...

    android UI大全

    学习如何定制它们的样式、监听用户交互和动态更新内容是Android UI开发的关键。 2. **布局管理器**:Android提供了多种布局,如LinearLayout、RelativeLayout、ConstraintLayout、GridLayout等,用于组织和定位应用...

    androidUI设计实践

    在Android平台上进行UI设计实践是一项至关重要的任务,它关乎到应用程序的用户体验、美观度以及功能易用性。本文将深入探讨Android UI设计的...通过不断学习和实践,才能打造出引人入胜、用户体验优秀的Android应用。

    android UI设计技巧

    在Android平台上进行UI设计是一项既具有挑战性又充满创意的工作。设计良好的用户界面不仅可以提升用户体验,还能使应用程序更具吸引力和易用性。...在实际设计过程中,持续学习和跟进Android的最新动态也是至关重要的。

    android UI 各种小例子

    在Android开发中,UI设计是至关重要的一环,它关乎到应用程序的用户体验和视觉吸引力。本压缩包中的"android UI 各种小例子"为初学者提供了丰富的实践资源,旨在帮助开发者掌握基本的Android用户界面设计技巧。每个...

    android UI 大全

    在Android平台上,UI(用户界面)设计是开发者和设计师必须关注的重要领域。Android UI大全是一个集成了各种Android...这个"android UI 教程"应该包含了这些内容的详细解释和实践指导,是Android UI学习者的宝贵资源。

    androidUI典型例子

    这个"androidUI典型例子"是基于模仿奇艺客户端,旨在帮助开发者掌握Android UI设计的基本原则和技巧。下面,我们将深入探讨这个主题,并结合"qiyi_UIPlayHD"这个压缩包中的文件,解析相关的知识点。 1. **布局管理...

    Android UI开发专题

    通过本专题的学习,我们了解到`android.content.res.Resources`类的强大功能以及如何利用`android.graphics`包中的类和方法来进行复杂的图像处理和绘制。这对于Android UI开发者来说是非常宝贵的资源,有助于他们更...

    androidUI详解文档

    Android UI详解文档主要涵盖的是...综上所述,"androidUI详解文档"将详细介绍这些概念,通过Index.html和ChildPage中的内容,开发者可以深入学习和掌握Android UI设计的各个方面,从而创建出更高质量的应用程序。

    android UI定制的一些资料

    在Android平台上,UI(用户界面)定制是一项关键的技术任务,它允许开发者根据需求和品牌风格创建独特的用户体验。这里,我们探讨的是"android UI定制的一些资料",这些资料可能包括设计原则、布局技巧、自定义视图...

    ANDROID UI设计工具

    在Android平台上进行UI(用户界面)设计是一项至关重要的任务,因为优秀的UI设计能够极大地提升用户体验,从而增加应用程序的吸引力和用户满意度。为了帮助开发者和设计师高效地创建美观且易用的Android界面,有许多...

    Android UI demo(远程医疗)

    在Android平台上,UI设计与实现是构建任何应用的基础,尤其是对于远程医疗这样的应用...通过学习和实践这个项目,开发者可以提升在Android UI设计和布局管理方面的技能,为创建更高级、功能丰富的医疗应用做好准备。

Global site tag (gtag.js) - Google Analytics