본문 바로가기

Android

Android Abstraction Between Packages

아래는 Android Jetpack How to smartly use fragment in your UI(Google I/O 2018) 발표의 스크립트 중 일부입니다.

 

So before we talk about that, I think it's kind of important to go into a little bit about the package layering involved in the Android framewokr, specifically android.widget versus android.app

 

Now, android.widget is really kind of designed to hold all the mechanism for your UI.

That means that this is all the stuff that shows state to the user and things that reports user interaction events back to other higher level portion of your app.

And really that's it. Anything that's in the widget package is really meant to only do these two things.

android.widget 패키지는 사용자에게 상태를 보여주고, 유저 익터랙션 이벤트를 상위 레이어인 android.app에게 전달하는 일을 수행하는 것으로 그 역할을 끝마친다.

 

Whereas android.app, which is where Fragments lives, Acitivities lives, so on and so forth, that's where your policy goes.

 

This is what defines what state to bind to widgets. This is what defines how you should respond to those user interaction events and how to issus changes to your data model.

[UI Component]   -> android.widget
[UI Controller], respond to user action and change data model  -> android.app

Anything kind of that layer or above, no matter how you may factor it, this is kind of how it breaks down.

So this also brings us to this idea of inflatable components, which is something that comes up quite a bit.

 

위 발표에서 Android Framework team의 Adam Powell은 android.widget과 android.app 패키지가 서로 다른 역할을 수행한다는 것을 강조하고 있다.

 


 

What the Fragment? Google I/O 2016에서도 마찬가지로 Android abstraction between packages에 대해서 발표한 것을 찾아볼 수 있다.

android.appandroid.widget보다 상위 개념의 패키지이다.

 

즉, android.app에 해당하는 Activity나 Fragment에서 widget을 사용할 수 있지만, 엄밀히 말하면 widget package를 import해서 사용하는 것이라는 의미이다.

 

"Fragments implement UIs just by using Views. They compose Views. They wire things up to Views in order to do something more interesting. And this really comes down to a core idea that isn't communicated all that widely that we kind of keep this idea of an abstraction hierarchy across the different packages in the framework."

 

각 패키지가 수행하는 기능을 명확하게 인지하고, 제한적으로 사용해야함을 강조하고 있다. 프래그먼트(android.app)는 뷰(android.widget)들을 구성하고 하나로 묶는 역할을 수행한다.

그리고 위에 대한 예제로 View.OnClickListener에 대해 설명한다.

"An example of this is that you mihgt have a Fragment that depends on a View OnClickListener in order to implement that interface. This is an example of a Fragment just kind of applying policy to a series of Views that it's using."

  • android.widget은 UI mechanism을 의미한다.
    • 위 예제에서 사용자가 버튼(or View)을 클릭했다는 이벤트를 인지하는 것이 widget의 역할이다.
    • 그리고 버튼 클릭이 발생했음을 상위 레이어인 Fragment에게 전달하는것도 widget의 역할이다.

버튼이 클릭됐을 때, 어떤 일이 발생하는지는 widget의 역할을 넘어서는 영역이다. 전혀 고려되지 않는다.

  • android.app은 Views들을 묶고 관리하는 policy를 담당한다.
    • 위 예제에서 버튼 클릭 이벤트가 발생했을 때, 어떤 일을 수행할 것인지를 결정한다.
    • 그리고 그 수행된 결과를 UI에 반영한다.

 

우리가 프래그먼트에서 View.OnClickListener { void onClick(view) } onClick 메소드에 클릭이 발생했을 때 할일을 구현하는 것을 예로 들 수 있다.

 

다시 한번, 프래그먼트는 화면을 구성하는 여러 뷰들에 의존성을 갖고 있으며, 뷰는 프래그먼트에 대한 어떠한 정보도 갖고있지 않다.

그래서 프래그먼트는 여러가지 뷰 컴포넌트를 엮는 Glue 역할을 담당한다고도 할 수 있다.

 

Conclusion

 

흔히 Activity나 Fragment 자체가 UI라고 생각하는 경향이 있다.

하지만 실제로는 여러 개의 순수한 View 컴포넌트들을 Activity나 Fragment가 하나로 엮어서 컨트롤하고 있는 형태임을 패키지 레이어링을 살펴보면 알 수 있다.

 

android.widget은 사용자와 커뮤니케이션하는 순수한 UI구성을 위해 사용하는 패키지이다. (UI Mechanism)

android.app은 UI Controller의 기능을 한다. (Policy)

 

두 가지를 완전히 다른 파일로 분리하거나, 혹은 하나의 프래그먼트 내에서 사용하더라도 서로 역할이 분리된 패키지라는 것을 인지하고 코드를 작성해야될 것이다.