2009년 7월 14일 화요일

Android-Application Fundamentals_1

 

 

 

 

Application Fundamentals

 

Android applications are written in the Java programming language. The compiled Java code — along with any data and resource files required by the application — is bundled by the aapt tool into an Android package, an archive file marked by an .apk suffix. This file is the vehicle for distributing the application and installing it on mobile devices; it's the file users download to their devices. All the code in a single .apk file is considered to be one application.

 

Android app java로 쓰여진다. 프로그램의 soure 코드를 compile 하고 프로그램에 사용된 data resource들이 함께 묶여서 하나의 파일을 만든다. 파일은 .apk라는 확장자를 갖는다. 이파일은 application 배포나 설치의 하나의 단위이다.  .apk파일 하나가 하나의 application 나타낸다. 우리는 aapt tool 이를 package 있다.

 

In many ways, each Android application lives in its own world:

  • By default, every application runs in its own Linux process. Android starts the process when any of the application's code needs to be executed, and shuts down the process when it's no longer needed and system resources are required by other applications.
  • Each process has its own Java virtual machine (VM), so application code runs in isolation from the code of all other applications.
  • By default, each application is assigned a unique Linux user ID. Permissions are set so that the application's files are visible only that user, only to the application itself — although there are ways to export them to other applications as well.

It's possible to arrange for two applications to share the same user ID, in which case they will be able to see each other's files. To conserve system resources, applications with the same ID can also arrange to run in the same Linux process, sharing the same VM.

 

각각의 app 각각의 linux process를 갖는다. Android 어떤 app code 실행될 필요가 있으면 process 실행키고 필요가 없거나 다른 app에서 system resource 필요할 shut down된다.  예를 들어 A라는 app에서 B 어떤 code 필요하면 새로운 linux process 실행되고 process B code 실행한다는 같다. 그리고 각각의 process JVM 갖는다. 그래서 하나의 app 다른 app  관계없이 격리 되서 실행된다. 그리고 app linux user id 할당 받는다. user id 통해서 permission이 설정 된다. App files 동일한 userid 의해 보여진다. 말은 app files 자신의 app 의해서만 보여질 있다는 것이다. 물론 다른 app 있도록 export 있는 여러 방법이 있다. 예를 들어 개의 app 동일한 user id 공유하게 수도 있다. 이렇게 되면 서로의 files 있다. 동일한 user id 갖게 다음, app들이 하나의 process에서 동작하게 만들 있다. 이렇게 되면 system resource 절약된다. 왜냐하면 하나의 VM 사용하기 때문이다.

 

Application Components

 

A central feature of Android is that one application can make use of elements of other applications (provided those applications permit it). For example, if your application needs to display a scrolling list of images and another application has developed a suitable scroller and made it available to others, you can call upon that scroller to do the work, rather than develop your own. Your application doesn't incorporate the code of the other application or link to it. Rather, it simply starts up that piece of the other application when the need arises.

For this to work, the system must be able to start an application process when any part of it is needed, and instantiate the Java objects for that part. Therefore, unlike applications on most other systems, Android applications don't have a single entry point for everything in the application (no main() function, for example). Rather, they have essential components that the system can instantiate and run as needed. There are four types of components:

 

Android에서 가장 중요한 특징은 app들이 서로의 elements component 사용할 있다는 것이다. 물론 이것은 각각의 app들이 허락을 한다고 가정했을 얘기다. 예를 들어 A scroller 필요한데 B 이를 가지고 있다. 그럼 B scroller call해서 쓰면 된다. 직접 개발할 필요 없이.  여기서 다른 시스템과 다른 차이가 있다. 다른 시스템처럼 B scroller코드를 통합한다거나 link 연결 하는게 아니다. A에서 B scroller 호출하면 B process 동작하고 B jvm 실행된다. ..그럼 B 함수가 호출되면 B scroller 달랑 호출 되지 않을 아니냐? 이런 질문이 있을 있다. 왜냐하면 process 실행되면 process main이라는 entry point 실행되야 하기 때문에  하지만 android app들은 main이라는 단 한 개의 entry point 갖지 않는다. Android app system 필요에 따라 초기화 시키고 이를 실행시킬 있는 4개의 필수 component들을 갖고 있다. 4개의 component들이 entry point라고 말할 있다는 것이다.

 

Activities

 

An activity presents a visual user interface for one focused endeavor the user can undertake. For example, an activity might present a list of menu items users can choose from or it might display photographs along with their captions. A text messaging application might have one activity that shows a list of contacts to send messages to, a second activity to write the message to the chosen contact, and other activities to review old messages or change settings. Though they work together to form a cohesive user interface, each activity is independent of the others. Each one is implemented as a subclass of the Activity base class.

 

하나의 activity라는 것은 하나의 visual user interface이다. 말은 하나의 activity 화면을 갖는 user interface..같은 것이다. 예를 들면, 메뉴리스트, 사진을 보여주는 것처럼 사용자의 입력을 받거나 출력하는 기능을 하는게 activity이다. Sms app 생각해보면, 연락처리스트를 선택하고 메시지를 작성하고 예전메시지를 보거나 환경설정을 하는거 이런게 모두 activity이다. 연락처 list 화면에 보이고 글을 쓸수 있는 창이 보이고 환경설정 창이 보이고 이런것들이 모두 activity라는 것이다. activity들이 하나의 app 구성하기에 이들은 매우 밀접한 관련이 있지만, 또한 각각의 activity 다른 activity와는 독립적이다. 각각의 activity Activity라는 base class subclass이다.

 

An application might consist of just one activity or, like the text messaging application just mentioned, it may contain several. What the activities are, and how many there are depends, of course, on the application and its design. Typically, one of the activities is marked as the first one that should be presented to the user when the application is launched. Moving from one activity to another is accomplished by having the current activity start the next one.

 

App 개의 activity 이루어질 있고, 위에 말한 SMS app처럼 여러 개로 구성될 수도 있다. APP 어떤 activity 포함할 것인가, 얼마나 많은 activity 사용할 것인가는 설계를 어떻게 하느냐에 달려 있다. 우선 확실한 app 처음 실행될 보여주어야 하는 activity 반드시 존재한다는 점과 activity에서 다른 activity로의 이동은 이전 activity 시작(실행)시킨다는 것이다.

 

Each activity is given a default window to draw in. Typically, the window fills the screen, but it might be smaller than the screen and float on top of other windows. An activity can also make use of additional windows — for example, a pop-up dialog that calls for a user response in the midst of the activity, or a window that presents users with vital information when they select a particular item on-screen.

 

각각의 activity마다 default window가 있다. Window 화면을 채우는 건데, 이것이 실제 screen보다 작을 수도 있고 다른 window위에 있을 수도 있다. 그리고 필요하다면 activity default window말고 다른 Window 사용할 있다. 예를 들어 pop-up dialog 있다. Pop-up dialog 사용자에게 사용자에게 응답을 요청하는데, 이게 하나의 window에서 추가된 window라고 보면 된다. 사용자가 특정 item 선택했을 , 사용자에게 item 대한 어떤 정보를 알려주려면 다른 Window 보여줄 텐데, 그거 또한 추가된 window라고 보면 된다.

 

The visual content of the window is provided by a hierarchy of views — objects derived from the base View class. Each view controls a particular rectangular space within the window. Parent views contain and organize the layout of their children. Leaf views (those at the bottom of the hierarchy) draw in the rectangles they control and respond to user actions directed at that space. Thus, views are where the activity's interaction with the user takes place. For example, a view might display a small image and initiate an action when the user taps that image. Android has a number of ready-made views that you can use — including buttons, text fields, scroll bars, menu items, check boxes, and more.

A view hierarchy is placed within an activity's window by the Activity.setContentView() method. The content view is the View object at the root of the hierarchy. (See the separate User Interface document for more information on views and the hierarchy.)

 

각각의 activity default window 갖는다고 했다. window안에 들어가는 visual content view hierarchy 제공한다. 말은 view base클래스를 구현하는 object들만이 window 화면상의 내용물이 있다는 같다. 또한 view들이라는 hierarchy 구조로 되어 있다는 것이다.  각각의 view들은 window내의 특정한 사각영역을 제어한다. 또한 Parent view 자식 view들을 가지고 있으며, 또한 그들의 layout 조정할 있다. 말단에 있는 view들은 자기영역의 사각형을 그릴 있고 영역 안에서 사용자와 직접적으로 반응할 수도 제어도 가능하다는 것이다. 따라서 view라는 것은 activity 사용자와 interaction 발생하는 곳에 바로 view 있다는 말이다. 예를 들면 어떤 view 작은 이미지를 보여줄 수도 있고( 말은 view 자기영역의 사각형에서 이미지를 그린다는 ) 사용자가 이미지를 건들때 어떤 action 초기화하기도 한다. Android 이런 view들을 이미 여러 만들어 놓았다. 버튼, textfield, scrollbar, menu item 등등. Activity.setContentView메소드로 어떤 view hierarchy 특정 activity window 설정할 수가 있다. ContentView라는 것은 rootview 의미한다. 따라서 setContentView 설정하면 view root 된다는 .

 

Services

 

A service doesn't have a visual user interface, but rather runs in the background for an indefinite period of time. For example, a service might play background music as the user attends to other matters, or it might fetch data over the network or calculate something and provide the result to activities that need it. Each service extends the Service base class.

 

Service라는 것은 user interface 없지만 정해지지 않은 시간동안 background에서 동작할 있다. 예를 들어, 어떤 서비스는 사용자가 다른 일을 하고 있는 동안 음악을 뒤에서 재생하기도 한다. 아니면 뒤에서 네트웍 data 꺼낸다던지, 뭔가를 계산한다던지..등등..각각의 service Service라는 base클래스를 상속해서 사용한다.

attends to : 집중하다.

A prime example is a media player playing songs from a play list. The player application would probably have one or more activities that allow the user to choose songs and start playing them. However, the music playback itself would not be handled by an activity because users will expect the music to keep playing even after they leave the player and begin something different. To keep the music going, the media player activity could start a service to run in the background. The system would then keep the music playback service running even after the activity that started it leaves the screen.

It's possible to connect to (bind to) an ongoing service (and start the service if it's not already running). While connected, you can communicate with the service through an interface that the service exposes. For the music service, this interface might allow users to pause, rewind, stop, and restart the playback.

Like activities and the other components, services run in the main thread of the application process. So that they won't block other components or the user interface, they often spawn another thread for time-consuming tasks (like music playback). See Processes and Threads, later.

 예를 들면, Media player 음악 재생을 예로 있다. Media player app는 여러 개의 activity 가질 있다. 사용자가 음악을 선택하는 activity 음악을 start시키는 activity..그러나 음악재생 자체는 activity 의해 제어될 없다. 음악을 선택하거나, 음악을 단지 start시키는 것은 activity 제어가 가능하지만, 일단 음악이 start되면 이것은 activity에서 제어가 불가능하다는 같다. 이것은 사용자가 media player app leave하거나, 다른 일을 시작하더라도 음악을 듣기를 원하기 때문이다. 그래서 media player activity 음악 재생을 background에서 동작하는 service 시작하게 한다. 음악을 재생시킨 activity screen상에서 사라지더라도 음악은 계속 재생된다. 이것은 ongoing service 연결(bind)함으로써 가능하다. Ongoing service 연결되어 있다면, service 공개하는 interface 의해서 service communication이 가능하다. Music service에서 interface라는 것은 사용자가 음악을 중지하거나, rewind, stop, 재생..이런것을 가능하게 해준다. Activity 다른 process 마찬가지로 service app process main thread에서 동작한다. 그래서 service들은 다른 component user interface block 시키지 않는다. Service들은 종종 다른 thread 만든다. 이것은 time consuming 작업이다. 부분은 이해가 가지 않는다. Service main thread에서 동작하기 때문에 다른 component interface block시키지 않는다는 것과 time consuming하는 task spawn한다는 말은 지금은 이해가 가지 않는다. Process Thread편에서 다시 다룬다고 한다.

 

 

 

Broadcast receivers

 

A broadcast receiver is a component that does nothing but receive and react to broadcast announcements. Many broadcasts originate in system code — for example, announcements that the timezone has changed, that the battery is low, that a picture has been taken, or that the user changed a language preference. Applications can also initiate broadcasts — for example, to let other applications know that some data has been downloaded to the device and is available for them to use.

An application can have any number of broadcast receivers to respond to any announcements it considers important. All receivers extend the BroadcastReceiver base class.

 

Broadcast receiver 직접 무언가를 하진 않는 component이다. 단지 broadcast 공지를 받거나 이에 반응하는 component이다. 많은 broadcast라는 것은 system code 부터 기인한다. 예를 들면 timezone 변경이 되었다, 배터리가 낮다, 그림을 다운받았다. 사용자가 언어설정을 바꾸었다라는 공지들이 broadcast되는 것이다. App들은 또한 broadcast 날릴 수도 있다. 어떤 data 다운받았으니 data 사용가능하다라는 broadcast 다른 app에게 알릴 수가 있는 것이다. App는 또한 여러 개의 broadcast receiver 가질 있는데, 이것은 중요하다고 생각되는 공지에 대해 반응하기 위한 것이다. 모든 broadcast receiver BroadcastReceiver라는 base class 상속받는다.

 

 

 

Broadcast receivers do not display a user interface. However, they may start an activity in response to the information they receive, or they may use the NotificationManager to alert the user. Notifications can get the user's attention in various ways — flashing the backlight, vibrating the device, playing a sound, and so on. They typically place a persistent icon in the status bar, which users can open to get the message.

 

Broadcast receiver들은 user interface 보이지 않는다. 하지만 그들은 받은 정보에 따라, activity 실행시킨다던가, NotificationManager 통해 사용자에게 경고를 보낼 수는 있다. 이 경고는 여러 방식으로 사용자에게 관심을 불러 일으킬 있다. Backlight 키고, 진동을 일으킨다거나 소리를 내는 방식으로 말이다. 경고는 status bar icon으로 있어서 사용자가 메시지를 open해서 있다.

 

Content providers

 

A content provider makes a specific set of the application's data available to other applications. The data can be stored in the file system, in an SQLite database, or in any other manner that makes sense. The content provider extends the ContentProvider base class to implement a standard set of methods that enable other applications to retrieve and store data of the type it controls. However, applications do not call these methods directly. Rather they use a ContentResolver object and call its methods instead. A ContentResolver can talk to any content provider; it cooperates with the provider to manage any interprocess communication that's involved.

 

App 가지고 있는 data 다른 app 사용하는 것을 가능하게 하는것은 Content Provider 있기 때문입니다. Data file system 혹은 sqlite혹은 어떤 매체에도 저장될 있습니다. contentProvider ContentProvider base class 있고 이를 구현한 class data 대해 제어가 가능합니다. 말은 restore하거나 store 가능하다는 말이죠. 하지만, ContentProvider method 직접 호출 없습니다. ContentResolver라는 객체의 method 통해서 이를 호출할 수가 있는데요. ContentResolver라는 객체는 어떤 content provider와도 통신이 됩니다.

 

 

See the separate Content Providers document for more information on using content providers.

Whenever there's a request that should be handled by a particular component, Android makes sure that the application process of the component is running, starting it if necessary, and that an appropriate instance of the component is available, creating the instance if necessary.

 

ContentProvider 정보는 별도로 기술 했습니다.

어떤 component 요청이 있는 경우, 요청이란 contentResolver라는 객체의 method 통해 어떤 data 쓰고자하는 요청이곗죠..그럼 andoid component 동작이 계속되게 하면서 instance 필요에 따라 생성하거나 실행시킵니다. 부분은 모호함..

Activating components: intents

 

Content providers are activated when they're targeted by a request from a ContentResolver. The other three components — activities, services, and broadcast receivers — are activated by asynchronous messages called intents. An intent is an Intent object that holds the content of the message. For activities and services, it names the action being requested and specifies the URI of the data to act on, among other things. For example, it might convey a request for an activity to present an image to the user or let the user edit some text. For broadcast receivers, the Intent object names the action being announced. For example, it might announce to interested parties that the camera button has been pressed.

 

Component 4가지 종류가 있는데요. Activity, service, broadcast receiver, content provider 있죠.

각각의 component들이 어떨때 동작하는가에 대해 알아봅니다. Content Provider ContentResolver 요청하면 activate되는데요. app 어떤 content 사용하고 싶다면 contentResolver 통해 data(content) 꺼내 오는 method 호출하면 contentResolver 해당 ContentProvider 호출하겠죠. 이때 활성화 됩니다. 나머지 3(activity, service, broadcast receiver) intents라는 비동기 메시지에 의해 활성화 됩니다. Intent 메시지를 가지는 하나의 객체인데요,  activities service 경우 intent 우선 요청할 action 지정합니다. 그리고 action 수행될 data URI 기술하게 됩니다. 그런 intent activity service 보내면 activate되겠죠. 예를들면 image 사용자에게 보여 주라하는 요청이나, 사용자가 text 수정하게 하라라는 명령을 activity에게 보낼 있는 것이죠. Broadcast receiver 같은 component에서는 intent 공지에 대한 action 지정합니다. 예를 들면 카메라버튼이 눌렸다는 공지를 관심있는 그룹에게 공지할 있죠.

 

 

 

There are separate methods for activiating each type of component:

 

각각의 component 활성화하는 독립된 method들이 있다.

 

  • An activity is launched (or given something new to do) by passing an Intent object to Context.startActivity() or Activity.startActivityForResult(). The responding activity can look at the initial intent that caused it to be launched by calling its getIntent() method. Android calls the activity's onNewIntent() method to pass it any subsequent intents.
    One activity often starts the next one. If it expects a result back from the activity it's starting, it calls
    startActivityForResult() instead of startActivity(). For example, if it starts an activity that lets the user pick a photo, it might expect to be returned the chosen photo. The result is returned in an Intent object that's passed to the calling activity's onActivityResult() method.

Activity Component 시작하려면 Context.startActivity() Activity.startActivityForResult() 호출하면 된다. 인자로 intent객체를 전달한다.

intent객체를 Context.startActivity() or Activity.startActivityForResult() 전달하면 Activity 시작된다. 이렇게 시작된 activity getIntent() 통해 자신을 시작시킨 intent 무엇인지 있다. Android activity onNewIntent() 호출하면 나중에 오는 intents activity에게 건네준다. Activity 보통 다른 activity 실행시키는데 어떤 결과값을 return받고 싶으면 startActivityForResult() startActivity()대신 써야 한다. 예를 들면, 사진을 선택하는 activity 실행했다면, 이전 activity user 선택한 사진을 return 받고 싶을 것이다. onActivityResult() 호출하면 return값을 얻을 있다. Return값은 intent객체로 넘어 온다.

 

  • A service is started (or new instructions are given to an ongoing service) by passing an Intent object to Context.startService(). Android calls the service's onStart() method and passes it the Intent object.
    Similarly, an intent can be passed to
    Context.bindService() to establish an ongoing connection between the calling component and a target service. The service receives the Intent object in an onBind() call. (If the service is not already running, bindService() can optionally start it.) For example, an activity might establish a connection with the music playback service mentioned earlier so that it can provide the user with the means (a user interface) for controlling the playback. The activity would call bindService() to set up that connection, and then call methods defined by the service to affect the playback.
    A later section,
    Remote procedure calls, has more details about binding to a service.

 

Service Component 시작은 Context.startService() intent객체를 인자로 전달해서 호출하면 시작된다. 어떤 compoent에서 Context.startService() 호출하면서 intent객체를 넘겨주면, service가 시작한다. Android service onStart() 호출하고 service intent객체를 넘겨주면서 시작되는 것이다. 호출한 component service사이의 연결을 계속 유지하기 위해서 Context.bindService() 사용해서 intent 넘겨줄 수도 있다. Service onBind() intent 받는다. (만일 service 실행되지 않고 있다면, bindService() service 실행할 수도 있다.). 예를 들어, 어떤 activity 음악 재생 service controll하고 싶다면 bindService() 연결을 시도하고 service 제공하는 function activity 사용할 있는 것이다. 예를 들어, 음악을 pause한다 거나, stop하는 들을 있는 것이다. 나중에 Remote procedure calls에서 service binding하는 것에 대해 자세히 알아 것이다.

 

 

For more on intent messages, see the separate article, Intents and Intent Filters.

 

App broadcast 초기화 하기 위해서 Context.sendBroadcast(), Context.sendOrderedBroadcast() 그리고 Context.sendStickyBroadcast() 호출하면됩니다. 여기에 intent객체를 인자로 보내야 합니다. Android 관심있는 broadcast Receiver onReceive() 호출해서 intent 전달합니다. intent message 내용 intents and intent filters 독립적으로 나와 있습니다.

 

 

 

Shutting down components

 

A content provider is active only while it's responding to a request from a ContentResolver. And a broadcast receiver is active only while it's responding to a broadcast message. So there's no need to explicitly shut down these components.

Activities, on the other hand, provide the user interface. They're in a long-running conversation with the user and may remain active, even when idle, as long as the conversation continues. Similarly, services may also remain running for a long time. So Android has methods to shut down activities and services in an orderly way:

 

Content Provider contentResolver 요청에 대한 응답에 의해 활성화 됩니다. 또한 Broadcast receiver broadcast message 대한 응답에 의해 혹은 응답을 활성화되죠. 그래서 component들은 명확하게 종료할 필요가 없게 됩니다. 요청이 없으면 활성화가 안되니까.. 종료된 상태이니 까요. 하지만 activity service 그렇지 않습니다. Activity들은 user interface 갖는데요. 이말은 user 끊임없이 conversation하기도 혹은 idle상태에 있더라도 그들은 running상태라는 것입니다. 유사하게 service 마찬가지로 오랜시간 running상태를 유지하기도 하는데요.. 그래서 android 이들을 shut down 있는 method 제공합니다.

 

 

 

  • An activity can be shut down by calling its finish() method. One activity can shut down another activity (one it started with startActivityForResult()) by calling finishActivity().

 

Activity 자신을  종료하는 method finish()입니다. 다른 activity 종료할 있는데요. 왜냐하면 activity 다른 activity 실행할 있는데(startActivityForResult() 시작시킬 있다.) 이렇게 시작한 activity finishActivity() 종료 시키면 됩니다.

 

Service stopSelf() 종료가 되거나 Context.stopService() 종료합니다.

 

Components might also be shut down by the system when they are no longer being used or when Android must reclaim memory for more active components. A later section, Component Lifecycles, discusses this possibility and its ramifications in more detail.

 

Component들은 system 의해 종료 수도 있는데요. 이건 Android 다른 component 활성화 하기 위해 memory 필요할  쓰지 않는 component 있다면, 종료 시킵니다. 이것은 나중에 Component Lifecycles에서 다시 자세히 살펴 보기로 합시다.

 

 

The manifest file

 

Before Android can start an application component, it must learn that the component exists. Therefore, applications declare their components in a manifest file that's bundled into the Android package, the .apk file that also holds the application's code, files, and resources.

The manifest is a structured XML file and is always named AndroidManifest.xml for all applications. It does a number of things in addition to declaring the application's components, such as naming any libraries the application needs to be linked against (besides the default Android library) and identifying any permissions the application expects to be granted.

 

Android app component 실행할 있습니다. 하지만 그전에 android app 어떤 component들이 있는지 알아야 필요가 있습니다. 따라서 app manifest파일에 자신의 app 포함된 component 적습니다. 파일 app component 목록이 들어있는 manifest파일은 apk파일에 포함되어 있습니다. android package(apk) app code,file,resource 가지고 있습니다. manifest file xml 되어 있고, 이는 모든 app들이 AndroidManifest.xml 동일한 이름을 가지고 있습니다. manifest file component 이름을 나열하는 이외에 많은 일을 합니다. App 필요로 하는 library 이름도 나열하고 app 접근하기 위한 permission 적혀있습니다.

 

 

But the principal task of the manifest is to inform Android about the application's components. For example, an activity might be declared as follows:

하지만 manifest 주된 역할은 android에게 app 쓰고 있는 component 알리는 겁니다. 예를 들어,

<?xml version="1.0" encoding="utf-8"?>
<manifest . . . >
    <application . . . >
        <activity android:name="com.example.project.FreneticActivity"
                  android:icon="@drawable/small_pic.png"
                  android:label="@string/freneticLabel"
                  . . .  >
        </activity>
        . . .
    </application>
</manifest>

 

위의 file에서는 activity라는 component android에게 알려주고 있는데요. Name Activity 상속 구현한 class의 이름이구요. Icon label 사용자에게 보여질 activity icon label입니다.

The name attribute of the <activity> element names the Activity subclass that implements the activity. The icon and label attributes point to resource files containing an icon and label that can be displayed to users to represent the activity.

The other components are declared in a similar way — <service> elements for services, <receiver> elements for broadcast receivers, and <provider> elements for content providers. Activities, services, and content providers that are not declared in the manifest are not visible to the system and are consequently never run. However, broadcast receivers can either be declared in the manifest, or they can be created dynamically in code (as BroadcastReceiver objects) and registered with the system by calling Context.registerReceiver().

For more on how to structure a manifest file for your application, see The AndroidManifest.xml File.

 

다른 component들도 유사합니다. Service <service>  Broadcast receiver <receiver> content provider <provider> ..여기서 특징적인것은 Activity, service, provider 경우 manifest file 기술되지 않는다면 system에서 실행되지 않는 다는 것입니다. 하지만, Broadcast receiver 경우 manifest 파일 안에 기술되지 않아도 동적으로 생성하고 이를 Context.registerReceiver() 등록하면 실행시킬 있다는 점인데요. 자세한 내용은 The androidManifest.xml File이라는 장에서 설명합니다.

 

Intent filters

 

An Intent object can explicitly name a target component. If it does, Android finds that component (based on the declarations in the manifest file) and activates it. But if a target is not explicitly named, Android must locate the best component to respond to the intent. It does so by comparing the Intent object to the intent filters of potential targets. A component's intent filters inform Android of the kinds of intents the component is able to handle. Like other essential information about the component, they're declared in the manifest file. Here's an extension of the previous example that adds two intent filters to the activity:

 

하나의 intent객체는 하나의 target Component 지정한다. 그렇다면 Android intent객체가 지정한 Component manifest file에서 찾고 Component 활성화 것이다. 그러나 target Component 명확히 지정이 안되어 있다면, android intent 응답하기 위해 최적의 Component 찾아야 한다. 어떻게 최적의 Component 찾을 것인가? Intent객체와 intent filter 비교해서 찾는다. 하나의 component intent filter 자신(component) handle하는 intent list android에게 알려주기 때문이다. Component 중요한 정보들이 manifest file 기술된 것과 같이 intent filter들도 기술 되어 있다. 아래는 위에서 사용한 예제에 activity라는 component 가지 intent filter 추가한 내용이다.

해석이 어렵다. 왜냐면..내가 intent 어떻게 쓰이는지 아직 hello world조차 해보지 않았기 때문이다.

<?xml version="1.0" encoding="utf-8"?>
<manifest . . . >
    <application . . . >
        <activity android:name="com.example.project.FreneticActivity"
                  android:icon="@drawable/small_pic.png"
                  android:label="@string/freneticLabel"
                  . . .  >
            <intent-filter . . . >
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <intent-filter . . . >
                <action android:name="com.example.project.BOUNCE" />
                <data android:mimeType="image/jpeg" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
        . . .
    </application>
</manifest>

The first filter in the example — the combination of the action "android.intent.action.MAIN" and the category "android.intent.category.LAUNCHER" — is a common one. It marks the activity as one that should be represented in the application launcher, the screen listing applications users can launch on the device. In other words, the activity is the entry point for the application, the initial one users would see when they choose the application in the launcher.

The second filter declares an action that the activity can perform on a particular type of data.

번째 filter action category 이루어진 일반적인 filter이다. 이것은 activity application launcher 표시된다는 것을 의미한다. Application launcher 사용자가 실행할 있는 application list 보여지는 화면을 의미한다.(주절이 끝난 다음 ,뒤에 명사가 나와 조금 당황했음 왜냐? In the application launcher and the screen으로 해석해야 하는가에 대해..하지만 which is 생략 되었다고 해석함) 다시 말해서, activity application entry point 의미한다는 것이다.  번째 filter activity 하는 action 정의한다.

 

A component can have any number of intent filters, each one declaring a different set of capabilities. If it doesn't have any filters, it can be activated only by intents that explicitly name the component as the target.

 

하나의 component 여러 개의 intent filter 가질 있고 그들 각각은 서로 다른 기능을 한다. 만일 filter 없다면, component intent 명시적으로  target Component 지정했어야 한다.

 

For a broadcast receiver that's created and registered in code, the intent filter is instantiated directly as an IntentFilter object. All other filters are set up in the manifest.

 

Broadcast receiver 경우, intent filter code상으로 만들어지고 등록되어 진다. Intent filter manifest파일에서 설정하지 않고 IntentFilter라는 객체로 생성시킨다.

 

For more on intent filters, see a separate document, Intents and Intent Filters.

 

Intent filter 대해서는 다음 문서를 봐라.

 

Activities and Tasks

 

As noted earlier, one activity can start another, including one defined in a different application. Suppose, for example, that you'd like to let users display a street map of some location. There's already an activity that can do that, so all your activity needs to do is put together an Intent object with the required information and pass it to startActivity(). The map viewer will display the map. When the user hits the BACK key, your activity will reappear on screen.

To the user, it will seem as if the map viewer is part of the same application as your activity, even though it's defined in another application and runs in that application's process. Android maintains this user experience by keeping both activities in the same task. Simply put, a task is what the user experiences as an "application." It's a group of related activities, arranged in a stack. The root activity in the stack is the one that began the task — typically, it's an activity the user selected in the application launcher. The activity at the top of the stack is one that's currently running — the one that is the focus for user actions. When one activity starts another, the new activity is pushed on the stack; it becomes the running activity. The previous activity remains in the stack. When the user presses the BACK key, the current activity is popped from the stack, and the previous one resumes as the running activity.

The stack contains objects, so if a task has more than one instance of the same Activity subclass open — multiple map viewers, for example — the stack has a separate entry for each instance. Activities in the stack are never rearranged, only pushed and popped.

A task is a stack of activities, not a class or an element in the manifest file. So there's no way to set values for a task independently of its activities. Values for the task as a whole are set in the root activity. For example, the next section will talk about the "affinity of a task"; that value is read from the affinity set for the task's root activity.

 

이전에 말했듯이 activity 다른 activity 실행한다. 이것은 다른 app activity 실행할 있다는 것이다.  user에게 어떤 지역의 street map 보여주고 싶다고 가정하자. 근데 이런 일을 하는 activity 이미 있다. 그럼 너가 해야 하는 것은 intent객체를 만들어서 startActivity() activity 실행 시키면 되는 것이다. 이렇게 시작된 map viewer map 보여줄 것이다. 사용자가 back키를 누르면 너의 activity 다시 화면에 나타날 것이다. 사용자는 map viewer 동일한 app에서 실행되는 것처럼 보일 것이다. 하지만 map viewer 다른 app에서 정의된 activity 있는 것이다. 하지만 android  개의 activity 동일한 task 유지함으로써 user experience 유지 시킨다. 사용자가 하나의 app라고 생각되는 것은 하나의 task라는 것이다. task 관련한 activity group이고 stack 쌓여져 있다. Stack root activity task 시작하는 activity이다. 또한 user app launcher에서 선택하는 activity이기도 하다. Stack 제일 위의 activity 현재 실행되는 activity이다. Root activity top activity 다르다. 조금 설명하자면 root acitivity 시작 activity라고 있다. App launcher에서 app 실행하면 처음으로 보여지는 activity, 그것이 root activity이다. 그런데 activity 다른 activity 실행시킬 있다. 이렇게 다른 activity 실행하면 activity stack top push되는데 이게 current activity라고 있는것이다. 예를 들어  A라는 activity 다른 B라는 activity 시작하면 B stack top 삽입된다. 그렇다고 A라는 activity 사라지지 않는다. 그대로 stack 남겨져 있다. 하지만 사용자가 Back키를 누르면 top 있던 B activity stack에서 pop된다. 대신 A activity running activity가 된다. Stack object 저장한다. 만일 어떤 task 동일한 activity instance 여러 가지고 있을 경우 stack 각각의 instance 대해 독립적인 entry를 갖는다. Stack 있는 각각의 activity들은 재배열 되지 않는다. 단지 push되고 pop 뿐이다. 부분이 이해가 안간다. Stack 독립적인 entry를 갖는다? Stack 재배열 되지 않는다? 이말이 나오게 되는지...요약하면 하나의 task activity 이루어 하나의 stack이다.  Manifest파일에서 정의된 class라던가 element 포함되지 않는다. 그래서 task activity 값을 설정할 방법이 없다. Task 모든 값들은 root activity안에서 설정된다. 이부분도 이해가 안감..task 하나의 stack이라고 했고 stack에는 여러 개의 activity 있다는거는 알겠다. activity stack 있는 activity class 아니라 instance이기 때문에 설정을 방법이 없다라고 했는데, root activity에서 설정이 가능하다? 그리고 어떤걸 설정한다는 말인가?다음장에서 affinity of task관해 얘기한다고 하니.. 들어보자.

 

  • User experience 용어

User experience를 디자인 한다는 것이 무엇인지 알아보기 전에, 그 단어가 의미하는 것이 무엇인지 알아보는 것이 좋을 것 같다. :

User experience는 사용자가 어떤 상품이나 시스템을 사용할 때 하게 되는 경험과 만족도를 표현하는 단어이다. 그 단어는 '웹상에서 판매' 와 같이 주로 소프트웨어나 비즈니스 관련 주제를 혼합해서 사용하는데, 이것은 interaction design의 결과물로 나타난다. Wikipedia definition

이 정의에 따르면, user experience는 사용자가 어떤 상품을 사용할때 느끼는 감정적인 특징이라 할 수 있다. user experience는 자동차에서 모바일 폰아나 잡지 혹은 장난감에 이르기까지 그 영역이 확장된다. 일반적으로 user experience라는 단어는 특별히 소프트웨어나 웹 어플리케이션 그리고 디지털 장비에 주로 사용하고 더 일반적인 제품의 경우는 experience design이라 한다.

=> 여기서는 사용자가 기존에 알고 있던 상식이라고 해석하면 된다. 사용자의 상식상 app 하나의 task 아닌가..이걸 말한다.

 

 

All the activities in a task move together as a unit. The entire task (the entire activity stack) can be brought to the foreground or sent to the background. Suppose, for instance, that the current task has four activities in its stack — three under the current activity. The user presses the HOME key, goes to the application launcher, and selects a new application (actually, a new task). The current task goes into the background and the root activity for the new task is displayed. Then, after a short period, the user goes back to the home screen and again selects the previous application (the previous task). That task, with all four activities in the stack, comes forward. When the user presses the BACK key, the screen does not display the activity the user just left (the root activity of the previous task). Rather, the activity on the top of the stack is removed and the previous activity in the same task is displayed.

 

Task 모든 activity들은 하나의 단위로 같이 움직인다. 전체 task foreground혹은 background 가져다 놓을 있다. 옮길 있다. 가정해 보자. 4개의 activity 하나의 stack 놓여져 있다. (task 하나의 stack 갖기 때문에, 하나의 task 4개의 activity 있다고 생각해도 될듯) . 간단히 이를 A task라고 하자. A task 실행중이기 때문에 A task top activity current running activity 것이다. 상태에서 사용자가 HOME키를 눌러 application launcher 이동하고 거기서 다른 B라는 app 실행한다. 그럼 A라는 task background 가고 B task root activity 화면에 보여진다. 잠시 후에 다시 사용자가 다시 뒤로 돌아가 A task 선택하면 이전 background에서 돌던 A task 다시 foreground 돌아오는 것이다. 사용자가 BACK키를 누르면, 이전 task 작업중이던 screen 보이지 않는다. 대신, stack top 있는 activity 제거되고 동일한 task activity 보여진다. 이말이 혼란 스럽다. 아직 개념을 모르기 때문에...여튼 계속 진행한다. 

 

The behavior just described is the default behavior for activities and tasks. But there are ways to modify almost all aspects of it. The association of activities with tasks, and the behavior of an activity within a task, is controlled by the interaction between flags set in the Intent object that started the activity and attributes set in the activity's <activity> element in the manifest. Both requester and respondent have a say in what happens.

In this regard, the principal Intent flags are:

 

설명한 동작들이 기본적인 task activity 동작들이다. 하지만, 모든 것은 수정 가능하다. Task activity 관계라던가, task내에서 activity 동작은 intent객체를( activity 시작시키는 intent flag) 설정하고 또한 manifest file에서 <activity> 속성을 setting해서 수정하는 것이다. 아래는 속성들이다.

FLAG_ACTIVITY_NEW_TASK

FLAG_ACTIVITY_CLEAR_TOP

FLAG_ACTIVITY_RESET_TASK_IF_NEEDED

FLAG_ACTIVITY_SINGLE_TOP

The principal <activity> attributes are:

taskAffinity

launchMode

allowTaskReparenting

clearTaskOnLaunch

alwaysRetainTaskState

finishOnTaskLaunch

The following sections describe what some of these flags and attributes do, how they interact, and what considerations should govern their use.

 

Affinities and new tasks

 

By default, all the activities in an application have an affinity for each other — that is, there's a preference for them all to belong to the same task. However, an individual affinity can be set for each activity with the taskAffinity attribute of the <activity> element. Activities defined in different applications can share an affinity, or activities defined in the same application can be assigned different affinities. The affinity comes into play in two circumstances: When the Intent object that launches an activity contains the FLAG_ACTIVITY_NEW_TASK flag, and when an activity has its allowTaskReparenting attribute set to "true".

 

기본적으로, 모든 activity들은 affinity(선호도)라는 값을 갖는다. 동일한 task 있는 모든 activity들이 affinity 갖고 있단 말이다. 값은 manifest에서 <activity>안의 taskaffinity속성에 값을 지정함으로써 각각의 activity들이 affinity값을 가질 있다. 말이 복잡한다. 그냥 한마디로 manifest파일에서 각각의 activity 어떤 속성을 설정할 있었는데, 속성중에 affinity 있다는 말이다. 그래서 값을 설정할 있다는 말이다. 서로 다른 app에서 정의된 activity 동일한 하나의 affinity 가질 있고, 동일한 app activity들이라도 다른 affinity 가질 있다. Affinity 두개의 환경에서 등장한다. Intent객체에 FLAG_ACTIVITY_NEW_TASK 설정해서 activity 시작할 , 그리고 activity 설정사항을 담은 manifest 파일의 allowtaskReparenting attribute true 설정하면 된다.

comes into play: 등장하다.

The FLAG_ACTIVITY_NEW_TASK flag

As described earlier, a new activity is, by default, launched into the task of the activity that called startActivity(). It's pushed onto the same stack as the caller. However, if the Intent object passed to startActivity() contains the FLAG_ACTIVITY_NEW_TASK flag, the system looks for a different task to house the new activity. Often, as the name of the flag implies, it's a new task. However, it doesn't have to be. If there's already an existing task with the same affinity as the new activity, the activity is launched into that task. If not, it begins a new task.

 

..affinity라는 activity task와의 관계를 나타내는 같다. 우선 해석을 해보자. Activity 실행 시킬 intent객체를 생성하고 이를 startActivity() 인자로 실행 시키면 새로운 activity 생성되는 것을 우리는 이미 알고 있다. intent 설정할 FLAG_ACTIVITY_NEW_TASK라고 설정을 하면 새로운 activity 포함될 task 이전 activity, 자신을 실행 시킨 activity 포함된 task( stack) 아닌 다른 task(stack)에서 실행된다는 것이다. 물론 new task(새로운 stack)에서 activity 실행 있겠지만, system 먼저 activity 가지고 있는 affinity 동일한 (affinity) 가진 task 있다면  task 새로운 activity launch시킨다는 것이다. 없다면 그대로 새로운 task에서 activity 실행 시키는 것이다.

 

 

The allowTaskReparenting attribute

If an activity has its allowTaskReparenting attribute set to "true", it can move from the task it starts in to the task it has an affinity for when that task comes to the fore. For example, suppose that an activity that reports weather conditions in selected cities is defined as part of a travel application. It has the same affinity as other activities in the same application (the default affinity) and it allows reparenting. One of your activities starts the weather reporter, so it initially belongs to the same task as your activity. However, when the travel application next comes forward, the weather reporter will be reassigned to and displayed with that task.

If an .apk file contains more than one "application" from the user's point of view, you will probably want to assign different affinities to the activities associated with each of them.

 

어떤 Activity allowTaskReparenting속성이 true라면 activity task사이를 이동할 있다는 말이다. 예를 들면, weather condition report하는 A라는 activitiy 있다고 하자. A 원래 travel app 속하는 activity이다. Travel app 속하기 때문에 원래 A affinity travel app 속한 다른 activitiy 마찬가지로 동일한 affinity값을 가지고 있을것이다. 그런데 activity 다른 app에서 실행을 시키면 어떻게 될까? 물론 실행은 app에서 시키는게 아니고 app 포함된 activity가 시작하겠지..어쨌 A라는 activity 자신을 시작한 activity 포함된 task 포함되 있다는 것이다. 말은 A 시작한 task(stack)에서 실행되고 있다는 것이지, 여기서 사용자가 갑자기 travel app 실행시키면 어떻게 되는것인가? Travel app weather report라는 activity 다시 하나 생성되는가? 아니다, 이미 사용된 weather report 다시 이동된다. Travel app stack으로 재할당 되고 여기서 보여진다. 만일 apk가 여러 개의 application 가지고 있다면, 아마도 다른 affinity activity들에 할당하지 않았을까? 참고로 apk파일은 manifest file이고 manifest file은 하나의 app당 한 밖에 없다.

 

Launch modes

 

There are four different launch modes that can be assigned to an <activity> element's launchMode attribute:

"standard" (the default mode)

"singleTop"

"singleTask"

"singleInstance"

The modes differ from each other on these four points:

 

Activity 4개의 launch mode 가지고 있는데, 이것은 apk파일에서 <activity>element 설정되어 있다.

Standard(default)

Single top

Singtask

singleInstance

모드들의 차이점은 4가지가 있다.

  • Which task will hold the activity that responds to the intent. For the "standard" and "singleTop" modes, it's the task that originated the intent (and called startActivity()) — unless the Intent object contains the FLAG_ACTIVITY_NEW_TASK flag. In that case, a different task is chosen as described in the previous section, Affinities and new tasks.
    In contrast, the "
    singleTask" and "singleInstance" modes mark activities that are always at the root of a task. They define a task; they're never launched into another task.

 

어떤 task activity 가질 것인가? Standard singleTop모드는 activity 시작하는 activity 시작한 task에서 실행된다는 의미한다. 하지만 intent 만들 , 속성을 FLAG_ACTIVITY_NEW_TASK 한다면 activity affinity 같은 task 찾거나, 같은게 없다면 새로운 task에서 실행이 된다. 정적으로 정의하는(manifest file)보다 동적으로 정의가(intent객체) 우세하다는 보여준다. 그런데, singleTask singleInstance activity launch mode 정의 된다면, 상황이 달라진다. 만일 어떤 activity singleTask 혹은 singleInstance 정의 되어 있다면, activity 다른 activity에서 activity 시작해서 activity 시작한 activity task 놓을 것인가 혹은 다른 task 놓을 것인가 하는 문제가 아니다. Activity 이렇게 singleTask singleInstance 놓게 되면, activity root activity 의미하고 이것은 application launcher에서 사용자가 선택하는 activity이기 때문에 당연히 다른 activity에서 실행되는 activity 아니라는 말이다. 오직 application launcher에서 실행되는 activity라는 것을 알려준다.

 

 

  • Whether there can be multiple instances of the activity. A "standard" or "singleTop" activity can be instantiated many times. They can belong to multiple tasks, and a given task can have multiple instances of the same activity.
    In contrast, "
    singleTask" and "singleInstance" activities are limited to just one instance. Since these activities are at the root of a task, this limitation means that there is never more than a single instance of the task on the device at one time.

 

Activity standard singleTop으로 설정을 하면, 여러 instance 있다. 말은...예를들어 A라는 activity B라는 activity 시작(실행)했고 B라는 activity B라는 activity 실행하면 어떻게 될까? B라는 activity 2 instance화 된다. 여러 instance화가 가능하다는 말이다.

반면 activity singleTask singleInstance 설정이 되면, 이건 한번만 instance 된다. 그것이 task root activity이기 때문이다.

 

  • Whether the instance can have other activities in its task. A "singleInstance" activity stands alone as the only activity in its task. If it starts another activity, that activity will be launched into a different task regardless of its launch mode — as if FLAG_ACTIVITY_NEW_TASK was in the intent. In all other respects, the "singleInstance" mode is identical to "singleTask".
    The other three modes permit multiple activities to belong to the task. A "
    singleTask" activity will always be the root activity of the task, but it can start other activities that will be assigned to its task. Instances of "standard" and "singleTop" activities can appear anywhere in a stack.

 

singleInstance 정의된 activity 다른 activity 시작(실행) 경우 시작된 activity 자신과 동일한 task 있을까? 정답은 아니다. singleInstance라고 정의되면, task자체는 오직 하나의 activity 갖는다. root activity 이루어진 하나의 task 갖는다고 선언하는 것이다. singleInstance 정의된 activity 물론 다른 activity 시작(실행) 있다. 다른 activity 실행하면 실행되는 activity 어떤 launch mode 갖고 있던간에, 그거와 상관없이, 마치 intent에서 FLAG_ACTIVITY_NEW_TASK 설정한 것처럼, 다른 task에서 시작(실행)된다.  이것외 모든 부분에 있어서, singleInstance singleTask 동일하다.  그럼 singleTask 정의된 activity에서 다른 activity 실행 시키면 어떻게 되는가? singleTask 정의된 activity root activity 되고 자신이 실행 시킨 activity 실행 시킬 , intent 별다른 FLAG설정을 하지 않았다면, activity 동일한 task 사용한다. 다른 standard singleTop 마찬가지로 동일한 stack(task)에서 실행 된다.

 

 

  • Whether a new instance of the class will be launched to handle a new intent. For the default "standard" mode, a new instance is created to respond to every new intent. Each instance handles just one intent. For the "singleTop" mode, an existing instance of the class is re-used to handle a new intent if it resides at the top of the activity stack of the target task. If it does not reside at the top, it is not re-used. Instead, a new instance is created for the new intent and pushed on the stack.
  • Standard모드에서는 모든 새로운 intent 대해 새로운 activity 만들어지고 새로운 activity 단지 하나의 intent만을 관리한다. singleTop모드에서는 만약 activity task에서 top 있을 경우 새로운 activity 만들어지는게 아니고 재사용 된다. 그래서 새로 만들어진 intent 관리하는 것은 top 있는 activity 관리한다. 만일 activity top 있지 않을 경우, 새로운 intent 대응되는 새로운 activity 만들어지고 만들어진 activity task 삽입된다.

 

For example, suppose a task's activity stack consists of root activity A with activities B, C, and D on top in that order, so the stack is A-B-C-D. An intent arrives for an activity of type D. If D has the default "standard" launch mode, a new instance of the class is launched and the stack becomes A-B-C-D-D. However, if D's launch mode is "singleTop", the existing instance is expected to handle the new intent (since it's at the top of the stack) and the stack remains A-B-C-D.

예를 들어, task stack root activity B,C,D 있다면, stack 순서는 A-B-C-D이다. Standard mode 가진 D activity에서 새로운 activity 생성하기위해 intent 만들어 startActivity() 호출했다고 하자. 물론 intent 지시하는 activity D class라고 하면, 새로운 activity instance 만들어져 stack 삽입된다. 그래서 결과는 A-B-C-D-D 된다. 하지만, D activity singleTop mode였다면, D type activity 사용하려고 intent 생성하여 전달해도 새로운 activity 생기는게 아니고 자기자신이 intent 처리한다.

 

If, on the other hand, the arriving intent is for an activity of type B, a new instance of B would be launched no matter whether B's mode is "standard" or "singleTop" (since B is not at the top of the stack), so the resulting stack would be A-B-C-D-B.
As noted above, there's never more than one instance of a "
singleTask" or "singleInstance" activity, so that instance is expected to handle all new intents. A "singleInstance" activity is always at the top of the stack (since it is the only activity in the task), so it is always in position to handle the intent. However, a "singleTask" activity may or may not have other activities above it in the stack. If it does, it is not in position to handle the intent, and the intent is dropped. (Even though the intent is dropped, its arrival would have caused the task to come to the foreground, where it would remain.)

When an existing activity is asked to handle a new intent, the Intent object is passed to the activity in an onNewIntent() call. (The intent object that originally started the activity can be retrieved by calling getIntent().)

 

만일, arriving intent B type activity라면, B launch mode singleTop이건, standard이건 상관없다. 여기서 표현하는 arriving intent라는 표현이 어색하다. 어쨌든, 결과는 A-B-C-D-B 된다.  위에 언급했듯이 singleTask singleInstance activity 하나 이상이 없다. 그래서 singleTask singleInstance 생성되는 activity 새로운 intent만을 다룬다. singleInstance 오직 하나의 root activity만을 task 갖는다. 따라서 stack top 위치에 있다.  이것은 singleInstance activity intent 다루기에 적합하다. 하지만, singleTask 위에 activity 있을 수도 없을 수도 있다. 만일 위에 activity 있다면, intent 다루기에 적절치 않다.  그리고 intent가 dropped된다. Intent drop되더라도 task foreground 간다. 이미 있는 activity에게 새로운 intent handle하도록 요청할 , intent객체는 onNewIntent() 전달된다. getIntent() 이전 activity intent객체를 꺼낸다. 부분은 나중에 반드시 재해석이 필요하다. Intent arrive되고 onNewIntent() 어떤 일을 하는지에 대해 재해석이 필요하다.

Note that when a new instance of an Activity is created to handle a new intent, the user can always press the BACK key to return to the previous state (to the previous activity). But when an existing instance of an Activity handles a new intent, the user cannot press the BACK key to return to what that instance was doing before the new intent arrived.

For more on launch modes, see the description of the <activity> element.

새로운 intent 다루기 위해서 activity 객체가 생성되면, 사용자는 back키를 눌러서 이전의 activity 돌아갈 있다. 하지만, 새로운 intent 대해 새로운 activity 생기는 아니고, 이전 activity 새로운 intent 받는 경우를 생각하자. 그런 경우, 사용자는 Back키를 눌러 새로운 intent 도착하기 앞서 이전의 activity 돌아 없다.  알기 위해서는 <activity> element 참고해라.

 

Clearing the stack

If the user leaves a task for a long time, the system clears the task of all activities except the root activity. When the user returns to the task again, it's as the user left it, except that only the initial activity is present. The idea is that, after a time, users will likely have abandoned what they were doing before and are returning to the task to begin something new.

 

오랜 시간 동안 사용자가 task 사용하지 않는다면, system root activity 남겨두고 task 있는 모든 activity clear한다. 사용자가 다시 task 돌아가면 초기 activity(root activity) 남아 있다. 생각은 사용자가 일정시간이 지나면 이전에 했던 모든 작업을 버리고 새롭게 task 시작 한다는 생각이기 때문이다.

 

That's the default. There are some activity attributes that can be used to control this behavior and modify it:

물론 이것은 default.  이런 동작을 수정하거나 제어하는 activity 속성이 있다.

 

The alwaysRetainTaskState attribute

If this attribute is set to "true" in the root activity of a task, the default behavior just described does not happen. The task retains all activities in its stack even after a long period.

Root activity에서 속성이 true이면 , task 모든 activity 일정 시간이 지나도 사라지지 않는다.

 

The clearTaskOnLaunch attribute

If this attribute is set to "true" in the root activity of a task, the stack is cleared down to the root activity whenever the user leaves the task and returns to it. In other words, it's the polar opposite of alwaysRetainTaskState. The user always returns to the task in its initial state, even after a momentary absence.

 

속성은 위의 alwaysRetainTaskState 완전 반대다. 이건 사용자가 다른 task 갔다가 돌아오면 root위의 activity 모두 clear된다. 시간이 순간일지라도..

 

The finishOnTaskLaunch attribute

This attribute is like clearTaskOnLaunch, but it operates on a single activity, not an entire task. And it can cause any activity to go away, including the root activity. When it's set to "true", the activity remains part of the task only for the current session. If the user leaves and then returns to the task, it no longer is present.

 

속성은 clearTaskOnLaunch속성과 비슷하다. clearTaskOnLaunch속성이 task 모든 activity 통제하고 root activity에서 설저되는 것과는 달리 이속성은 root activity 아니라 일반적인 activity들에게 모두 설정이 가능하다. 말은 activity각각에 대해 설정이 가능하다는 의미한다. 만일 이게 어떤 activity true라고 설정이 되어 있다고 한다면, 사용자가 다른 task에서 task return하면 설정된 activity clear된다.

 

There's another way to force activities to be removed from the stack. If an Intent object includes the FLAG_ACTIVITY_CLEAR_TOP flag, and the target task already has an instance of the type of activity that should handle the intent in its stack, all activities above that instance are cleared away so that it stands at the top of the stack and can respond to the intent. If the launch mode of the designated activity is "standard", it too will be removed from the stack, and a new instance will be launched to handle the incoming intent. That's because a new instance is always created for a new intent when the launch mode is "standard".

 

Activity stack에서 제거하는 또다른 방식이 있다. Intent FLAG_ACTIVITY_CLEAR_TOP이란 flag 설정하고 startActivity() 호출했다고 하자. 해당 activity 이미 stack 있다면, intent handle하는 instant위의 activity들은 모두 stack에서 사라진다. 만일 지정된 activity launch mode standard 경우 자신도 stack에서 사라지고 intent 받아들일 새로운 instance 만들어진다. 이것은 새로운 intent handle 새로운 instance 생성되기 때문이다. 단락도 모호하다.

FLAG_ACTIVITY_CLEAR_TOP is most often used in conjunction with FLAG_ACTIVITY_NEW_TASK. When used together, these flags are a way of locating an existing activity in another task and putting it in a position where it can respond to the intent.

 

FLAG_ACTIVITY_CLEAR_TOP 종종 FLAG_ACTIVITY_NEW_TASK 연관되서 사용된다. 함께 사용될때, flag들은 다른 task 있는 이미 있는 activity 찾게 하고 intent 대응하는 위치에 activity 삽입한다.

 

Starting tasks

An activity is set up as the entry point for a task by giving it an intent filter with "android.intent.action.MAIN" as the specified action and "android.intent.category.LAUNCHER" as the specified category. (There's an example of this type of filter in the earlier Intent Filters section.) A filter of this kind causes an icon and label for the activity to be displayed in the application launcher, giving users a way both to launch the task and to return to it at any time after it has been launched.

 

Activity entry point 설정하려면 어떻게 해야 하는가? Intent filter action에는 android.intent.action.MAIN으로 category android.intent.category.LAUNCHER 지정하면 activity entry point 된다. 이렇게 filter 설정하면 application launcher에서 activity 식별할 있게 icon label 생성이 된다. 이것은 사용자가 activity 실행할 있고 시작된 activity 다시 돌아갈 있는 것이다.

 

This second ability is important: Users must be able to leave a task and then come back to it later. For this reason, the two launch modes that mark activities as always initiating a task, "singleTask" and "singleInstance", should be used only when the activity has a MAIN and LAUNCHER filter. Imagine, for example, what could happen if the filter is missing: An intent launches a "singleTask" activity, initiating a new task, and the user spends some time working in that task. The user then presses the HOME key. The task is now ordered behind and obscured by the home screen. And, because it is not represented in the application launcher, the user has no way to return to it.

 

위의 filter 설정하면 activity 실행할 있고 다시 activity 돌아갈 있다고 했다. 사용자에게 있어 두번째 특성은 중요하다. 이런 이유 때문에, 개의 launch mode singleTask singleInstance activity MAIN LAUNCHER filter 가질 때만 사용될 있는 것이다. 만일 intent filter 없다고 생각해보자. 어떤 intent 새로운 task 시작하기 위해 singleTask activity 시작했다. 그리고 user task에서 작업을 하고 있다. 사용자가 HOME 키를 누르면, Home screen task application launcher 보이지 않는다. 이러면 다시 돌아갈 방법이 없게 된다.

 

A similar difficulty attends the FLAG_ACTIVITY_NEW_TASK flag. If this flag causes an activity to begin a new task and the user presses the HOME key to leave it, there must be some way for the user to navigate back to it again. Some entities (such as the notification manager) always start activities in an external task, never as part of their own, so they always put FLAG_ACTIVITY_NEW_TASK in the intents they pass to startActivity(). If you have an activity that can be invoked by an external entity that might use this flag, take care that the user has a independent way to get back to the task that's started.

For those cases where you don't want the user to be able to return to an activity, set the <activity> element's finishOnTaskLaunch to "true". See Clearing the stack, earlier.

 

비슷한 어려움은 FLAG_ACTIVITY_NEW_TASK에도 있다. 만일 flag 새로운 task 시작하기 위해 activity 시작하고 user task 벗어나기 위해 HOME키를 눌렀다면, user 이전의 task 돌아갈 방법이 있어야 한다. 어떤 entity들은(예를 들면 notification manager) sctivity 외부 task에서 실행한다. entity들은 intent FLAG_ACTIVITY_NEW_TASK 설정하고 startActivity() 호출하는 것이다. 만일 외부의 task에서 호출되는 activity 있다면, 다시 말해 외부에서 이런 flag intent에서 설정해서 시작할 있는 activity 너의 task 가지고 있다면, user 다시 이전 task 돌아갈 있게 하는 방법이 있게 신경써야 한다. 이런경우는 보통 사용자가 이전 task 돌아갈 필요가 없을 경우 인데 이럴경우 <activity> finishOnTaskLaunch true 설정한다.

댓글 없음:

댓글 쓰기