잡스 전기

영어 본문 쪼갠 것 모음 1-22

1
A few days ago
    I wrote a post trying to correct a lot of the inaccurate statements(부정확한 진술들)         
        I have seen repeatedly
            mentioned about             
                how graphics on Android works.

This resulted in
    a lot of nice discussion,

  but unfortunately
    (this) has also lead some people
        to come up with (complaints)
            new, novel, and often technically inaccurate complaints
                about how Android works.

2
These new topics have been more about     
    some fundamental design decisions
        in Android,
    
    and why they are wrong.

I’d like to help people

    better understand (and judge) these discussions
        by giving some real background on
            why Android’s UI was designed the way it is
            and how it actually works.

3
One issue
    that has been raised
        is that
            Android doesn’t use thread priorities
                to reduce how much background work interrupts the user interface.

This is outright wrong.

It actually uses
    a number of priorities,
        which you can even find defined right here

http://developer.android.com/reference/android/os/Process.html#THREAD_PRIORITY_AUDIO in the SDK.

4
The most important of these
    are the background and default priorities.

User interface threads
    normally run at the default priority;

background threads
    run in the background priority.

Application processes
    that are in the background
        have all of their threads
            forced to the background priority.

5
Android’s background priority is actually pretty interesting.

It uses a Linux facility
    called cgroups
        to put all background threads
            into a special scheduling group
                which, all together, can’t use more than 10% of the CPU.

That is,
    if you have 10 processes in the background
        all trying to run at the same time,
            when combined
                they can't take away
                    more than 10% of the time
                        needed by foreground(표현?) threads.

This is enough
    to allow background threads (표현? 의미?)
        to make some forward progress,
            without having enough of an impact
                on the foreground threads
                    to be generally visible to the user.
                (foreground thread의 의미는?)
6
(You may have noticed
    that a “foreground” priority is also defined.

This is not used in current Android;

it was in the original implementation,

but we found that the Linux scheduler
    does not give enough preference to threads
        based on pure priority,
so (we) switched to cgroups in Android 1.6.)

7
I have also seen a number of claims
    that the basic Android design
        is fundamentally flawed and archaic
            because it doesn’t use a rendering thread like iOS.

There are certainly some advantages
    to how iOS work,
        but this view is too focused
            on one specific detail to be useful,

            and glosses over(얼버무리고 넘어가다)
                actual similarities
                    in how they behave.
8
Android had
    a number of very different original design goals
        than iOS did(had).

A key goal of Android
    was to provide an open application platform,
        using application sandboxes
            to create a much more secure(안전한?) environment
                that doesn’t rely on a central authority
                    to verify that applications do what they claim.

To achieve this,
    it uses Linux process isolation and user IDs
        to prevent each application
            from being able to access the system or other application
                in ways that are not controlled and secure.

9
This is very different from iOS’s original design constraints,
    which didn’t allow any third party applications at all.

10
An important part of achieving this security
    is having a way
        for individual UI elements to share the screen
            in a secure way.

(EDIT: It has been pointed out to me
    that iOS does in fact use multiple windows and multiple GL contexts.

Lesson to me, just don't talk about anything
    that I haven't directly verified. :)

That still doesn't change things for Android, though,
    where as I mention later
        we simply did not have hardware and drivers
            that could do multiple GL contexts until fairly recently.)

>> 그래서 안드로이드에 윈도우들이 있는 것이다.
응? 몬 의미?

This is why
    there are windows on Android.

The status bar and its notification shade
    are windows
        owned and drawn by the system.

>> 시스템이 가리키는 것은? OS? 안드로이드 시스템?

These are separate
    from the application’s window,
        so the application can not touch anything about the status bar,
            such as to scrape(긁어내다??)  the text of SMS messages
                as they are displayed there.

Likewise
    the soft keyboard is a separate window,
        owned by a separate application,

and it and the application
    can only interact with each other
        through a well defined and controlled interface.

(This is also why
    Android can safely support third party input methods.)

11
Another objective of Android
    was to allow close collaboration between applications,
        so that
            for example
            it is easy to implement a share API
                that launches a part of another application
                    integrated with the original application’s flow.

As part of this,
Android applications traditionally
    are split into pieces (called “Activities”)
        that handle a single specific part of the UI of the application.

For example, the contacts lists is one activity,
the details of a contact is another,
and editing a contact is a third.

Moving between those parts of the contacts UI
    means switching between these activities,

and each of these activities
    is its own separate window.

>> 각 activity마다 각각 별개의 창이 있는 것..

12

Now we can see something interesting:

in almost all of the places in the original Android UI
    where you see animations,
        you are actually seeing windows animate.

>> 윈도우가 animate하는게 무슨 의미일까?

Launching Contacts is an animation
    of the home screen window and the contacts list window.

Tapping on a contact to see its details
    is an animation of
        the contacts list window
        and the contacts details window.

Displaying the soft keyboard
    is an animation of the keyboard window.

Showing the dialog
    where you pick an app to share with
        is an animation of a window
            displaying that dialog.
13

When you see a window on screen,
what you are seeing
    is actually something
        called a “surface”.

This is a separate piece of shared memory
        that the window draws its UI in,

    and (this) is composited with the other windows
        to the screen by a separate system service
            (in a separate thread,
                running at a higher than normal priority)
                    called the “surface flinger.”

Does this sound familiar?

In fact this is like
    what iOS is doing with its views
        being composited by a separate thread,
            just at a less fine-grained but significantly more secure level.

(And this window composition has been hardware accelerated in Android from the beginning.)

14

The other main interesting interaction in the UI
    is tracking your finger
        -- scrolling and flinging a list, swiping a gallery, etc.

These interactions involve updating the contents inside of a window,
    so require re-rendering that window
        for each movement.

However, being able to do this rendering off the main thread
    probably doesn’t gain you much.

These are not simple “move this part of the UI from X to Y,
and maybe tell me when you are done” animations

-- each movement is based on events
    received about the finger on the screen,
        which need to be processed
            by the application on its main thread.

15

That said,
    being able to avoid redrawing all of the contents
         of the parts of the UI that are moving
            can help performance.

And this is also a technique
    that Android has employed since before 1.0;

UI elements like a ListView
    that want to scroll their content
        can call
http://developer.android.com/reference/android/view/View.html#setDrawingCacheEnabled(boolean)
            to have that content rendered into a cache
                so that only the bitmap needs to be drawn as it moves.

16

Traditionally on Android,
    views only have their drawing cache
        enabled as a transient state,
            such as while scrolling or tracking a finger.

This is because
    they introduce a fair amount more overhead:
        extra memory for the bitmap
            (which can easily total to multiple times
                larger than the actual frame buffer
                    if there are a number of visual layers),

and when the contents inside of a cached view
    need to be redrawn
        it is more expensive
            because there is an additional step
                required to draw the cached bitmap back to the window.
17
So, all those things considered,
in Android 1.0
having each view
    drawn into a texture and those textures composited to the window in another thread

        is just not that much of a gain,
        with a lot of cost.

The cost is also in engineering time
-- our time was better spent
    working on other things like
        a layout-based view hierarchy
            (to provide flexibility in adjusting for different screen sizes)
        and “remote views”
            for notifications and widgets,
                which have significantly benefited the platform as it develops.

18
In fact it was just not feasible
    to implement hardware
        accelerated drawing inside windows until recently.

Because Android is designed
    around having multiple windows on the screen,

to have
    the drawing inside each window
        be hardware accelerated

    means
        requiring that
            the GPU and driver
                support multiple active GL contexts
                    in different processes running at the same time.

The hardware at that time
    just didn’t support this,
        even ignoring the additional memory needed for it
               that was not available.

Even today we are in the early stages of this
-- most mobile GPUs
    still have fairly expensive GL context switching.

19
I hope this helps people
    better understand how Android works.

And just to be clear again from my last point
-- I am not writing this to make excuses for
    whatever things people don’t like about Android,

I just get tired of seeing people
    write egregiously(터무니없게) wrong explanations
        about how Android works

    and worse present themselves
        as authorities on the topic.

20
There are of course many things
    that can be improved in Android today,
        just as there are many things that have been improved since 1.0.

As other more pressing(긴급한) issues are addressed,
    and hardware capabilities improve and change,

        we continue to push the platform forward and make it better.

21
One final thought.
I saw an interesting comment from Brent Royal-Gordon
on what developers sometimes need to do
to achieve 60fps scrolling in iOS lists: “

Getting it up to sixty is more difficult
—you may have to
    simplify the cell's view hierarchy,
    or delay adding some of the content,
    or remove text formatting
        that would otherwise require a more expensive text rendering API,
    or even rip the subviews out of the cell altogether
    and draw everything by hand.”

22
I am no expert on iOS,
so I’ll take that as as true.

These are the exact same recommendations
    that we have given to Android’s app developers,

and based on this statement
    I don't see any indication
        that there is something intrinsically(본질적으로) flawed(결함이 있는) about Android
            in making lists scroll at 60fps, any more than there is in iOS.

댓글

댓글 본문
graphittie 자세히 보기