• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1page.title=동작 변경 사항
2page.keywords=preview, sdk, 호환성
3meta.tags="preview", "compatibility"
4page.tags="preview", "developer preview"
5page.image=images/cards/card-n-changes_2x.png
6@jd:body
7
8
9<div id="qv-wrapper">
10<div id="qv">
11
12<h2>이 문서의 내용</h2>
13
14<ol>
15  <li><a href="#perf">성능 향상</a>
16    <ol>
17      <li><a href="#doze">잠자기 모드</a></li>
18      <li><a href="#bg-opt">백그라운드 최적화</a></li>
19    </ol>
20  </li>
21  <li><a href="#perm">권한 변경</a>
22  </li>
23  <li><a href="#sharing-files">앱 사이의 파일 공유</a></li>
24  <li><a href="#accessibility">접근성 향상</a>
25    <ol>
26      <li><a href="#screen-zoom">화면 확대/축소</a></li>
27      <li><a href="#vision-settings">설정 마법사의 Vision Settings</a></li>
28    </ol>
29  </li>
30  <li><a href="#ndk">플랫폼 라이브러리에 연결되는 NDK 앱</a></li>
31  <li><a href="#afw">Android for Work</a></li>
32  <li><a href="#annotations">주석 보존</a></li>
33  <li><a href="#other">기타 중요한 사항</a></li>
34</ol>
35
36<h2>참고 항목</h2>
37<ol>
38  <li><a href="{@docRoot}preview/api-overview.html">
39    Android N API 개요</a></li>
40</ol>
41
42</div>
43</div>
44
45
46<p>
47  Android N에는 새로운 기능 및 특징과 더불어
48다양한 시스템 변경 사항 및 API 동작 변경 사항이 포함되어 있습니다. 이 문서에서는
49여러분이 앱에서 숙지하고 고려해야 하는 몇 가지
50주요 변경 사항을 소개하겠습니다.
51</p>
52
53<p>
54  이전에 Android용 앱을 게시한 적이 있으신 경우, 이와 같은
55 플랫폼 변경으로 인해 앱이 영향을 받을 수 있다는 점을 유의하세요.
56</p>
57
58
59<h2 id="perf">배터리와 메모리</h2>
60
61<p>
62Android N에는 기기의 배터리 수명을 연장하고 RAM 사용량을 감소시키기 위한
63시스템 동작 변경 사항이 포함됩니다. 이러한 변경 사항은, 앱이 특정한 암시적 인텐트를 통해
64다른 앱과 상호 작용하는 방식과 함께, 시스템 리소스에 대한
65앱의 액세스에 영향을 미칠 수 있습니다.
66</p>
67
68<h3 id="doze">잠자기 모드</h3>
69
70<p>
71  Android 6.0(API 레벨 23)에 도입된 잠자기 모드는 사용자가 기기의
72플러그를 뽑고 정지 상태에서 화면이 꺼져 있을 때 CPU 및
73네트워크 액티비티를 지연시켜서 배터리 수명을 개선해 줍니다. Android N에서는
74기기의 플러그를 뽑고 화면이 꺼져 있는 동안
75CPU 및 네트워크 제한의 하위 세트를 적용하여 잠자기 모드를 더욱
76향상시켜 주지만, 반드시 정지 상태일 필요는 없습니다(예: 핸드셋을 사용자의 주머니에 넣고 다니는 경우).
77</p>
78
79
80<img src="{@docRoot}preview/images/doze-diagram-1.png" alt="" height="251px" id="figure1" />
81<p class="img-caption">
82  <strong>그림 1.</strong> 잠자기 모드에서 배터리 수명을 개선하기 위해 첫 번째 레벨의 시스템 액티비티 제한을
83적용하는 방법에 대한 그림.
84</p>
85
86<p>
87  기기가 배터리 전원에 연결되고 일정 시간 동안 화면이 꺼져 있는 경우
88기기가 잠자기 모드로 전환되고 첫 번째 하위 세트의 제한을 적용합니다. 기기는 앱
89네트워크 액세스를 차단하고, 작업과 동기화를 지연시킵니다. 기기가 잠자기 모드로
90전환된 후 일정 시간 동안 정지 상태에 있으면, 시스템은 잠자기 모드의 나머지 제한 사항을 {@link android.os.PowerManager.WakeLock},
91{@link android.app.AlarmManager} 알람, GPS 및 Wi-Fi 스캔에
92적용합니다. 일부 잠자기 모드 제한이
93적용되든 모든 잠자기 모드 제한이 적용되든 상관없이,
94시스템은 잠시 동안의 유지 관리 기간 중에 기기를 깨우며, 이 기간 중에는
95애플리케이션의 네트워크 액세스가 허용되고 지연된 작업/동기화가 실행됩니다.
96</p>
97
98
99<img src="{@docRoot}preview/images/doze-diagram-2.png" alt="" id="figure2" />
100<p class="img-caption">
101  <strong>그림 2.</strong> 기기가 일정 시간 동안 정지 상태에 있은 후에
102잠자기 모드에서 두 번째 레벨의 시스템 액티비티 제한을 적용하는 방법에 대한 그림.
103</p>
104
105<p>
106  화면을 활성화하거나 기기의 플러그를 꽂으면 잠자기 모드가
107종료되고 이러한 처리 제한이 제거됩니다. <a href="{@docRoot}training/monitoring-device-state/doze-standby.html">잠자기 및 앱 대기
108모드 최적화</a>에서 설명한 대로, Android 6.0(API 레벨 23)에 도입된
109이전 버전의 잠자기 모드에 맞춰 앱을 조정할 경우에는 이러한 추가적인 동작이
110권장 사항 및 모범
111사례에 영향을 미치지 않습니다. 하지만
112여전히 해당 권장 사항을 따라야 합니다. 예를 들어, GCM(Google Cloud Messaging)을 사용하여 메시지를
113송수신하고 추가적인 잠자기 모드 동작을 수용하기 위한 업데이트 계획을
114시작해야 합니다.
115</p>
116
117
118<h3 id="bg-opt">Project Svelte: 백그라운드 최적화</h3>
119
120<p>
121  Android N에서는 메모리 사용량 및 전원 소비량을 최적화하기 위해
122 세 가지 암시적 브로드캐스트를 제거합니다. 이렇게 변경해야 하는
123이유는, 암시적 브로드캐스트는 백그라운드에서 브로드캐스트를
124수신하도록 등록된 앱을 자주 시작하기 때문입니다. 이들 브로드캐스트를 제거하면 기기 성능과 사용자 환경이
125상당히 향상될 수 있습니다.
126</p>
127
128<p>
129  모바일 기기의 경우 연결 변경이 자주 나타납니다(예: Wi-Fi와
130 모바일 데이터 간의 이동 시). 현재는
131암시적 {@link
132 android.net.ConnectivityManager#CONNECTIVITY_ACTION} 브로드캐스트의 수신기를
133매니페스트에 등록하여 앱이 이러한 연결 변경을 모니터링할 수 있습니다. 많은 앱들이 이 브로드캐스트를 수신하도록
134 등록하기 때문에, 단일 네트워크 스위치가 모든 앱을 깨우고 이들 앱이 해당 브로드캐스트를
135 동시에 처리하도록 할 수 있습니다.
136</p>
137
138<p>
139  마찬가지로, 이전 버전의 Android에서는 앱이 다른 앱(예: 카메라)에서 암시적 {@link
140 android.hardware.Camera#ACTION_NEW_PICTURE} 및 {@link
141 android.hardware.Camera#ACTION_NEW_VIDEO} 브로드캐스트를
142수신하도록 등록할 수 있었습니다. 사용자가 카메라 앱으로 사진을 찍으면, 이들 앱이 깨어나서 해당 브로드캐스트를
143 처리합니다.
144</p>
145
146<p>
147  이런 문제를 완화하기 위해, Android N은 다음과 같은 최적화를
148 적용합니다.
149</p>
150
151<ul>
152  <li>Android N을 대상으로 하는 앱은 해당 이벤트의 알림을 요청하는 매니페스트 항목이 있더라도 {@link
153 android.net.ConnectivityManager#CONNECTIVITY_ACTION} 브로드캐스트를
154수신하지 않습니다. 실행 중인
155앱은 {@link android.content.BroadcastReceiver}로 알림을 요청하면
156여전히 기본 스레드에서 {@code CONNECTIVITY_CHANGE}를 수신할 수 있습니다.
157  </li>
158
159  <li>앱은 {@link
160 android.hardware.Camera#ACTION_NEW_PICTURE} 또는 {@link
161 android.hardware.Camera#ACTION_NEW_VIDEO} 브로드캐스트를 송수신할 수 없습니다. 이 최적화는 Android N을 대상으로
162 하는 앱뿐 아니라 모든 앱에 영향을 미칩니다.
163  </li>
164</ul>
165
166<p>앱이 이들 인텐트 중 하나라도 사용하는 경우에는,
167 Android N 기기를 올바로 대상으로 삼을 수 있도록 이들 인텐트에 대한 종속성을 최대한 빨리 제거해야 합니다.
168  Android 프레임워크는 이러한 암시적 브로드캐스트의
169 필요성을 줄이기 위한 여러 가지 해결책을 제공합니다. 예를 들어, {@link
170 android.app.job.JobScheduler} API는 지정된 조건(예:
171고정 요금제 네트워크에 연결)이 충족될 경우 네트워크 운영을 예약할 수 있는
172강력한 메커니즘을 제공합니다. 심지어 {@link
173 android.app.job.JobScheduler}를 사용하여 콘텐츠 공급자의 변경 사항에 대응할 수도 있습니다.
174</p>
175
176<p>
177  N에서 백그라운드 최적화와 앱을 조정하는 방법에 대한 자세한 내용은
178 <a href="{@docRoot}preview/features/background-optimization.html">백그라운드 최적화</a>를
179 참조하세요.
180</p>
181
182<h2 id="perm">권한 변경</h2>
183
184<p>
185  Android N에는 앱에 영향을 미칠 수도 있는 권한 변경이 포함되어 있습니다.
186</p>
187
188<h3 id="permfilesys">파일 시스템 권한 변경</h3>
189
190<p>
191  개인 파일의 보안을 강화하기 위해, Android N 이상을 대상으로 하는 앱의 개인
192 디렉터리는 액세스가 제한됩니다(<code>0700</code>).
193  이 설정은 크기 또는
194존재 여부와 같은 개인 파일의 메타데이터 유출을 막아줍니다. 이러한 권한 변경은 여러 가지 부작용이 있습니다.
195</p>
196
197<ul>
198  <li>
199    소유자가 개인 파일의 파일 권한을
200더 이상 완화해서는 안 되며,
201{@link android.content.Context#MODE_WORLD_READABLE} 및/또는
202{@link android.content.Context#MODE_WORLD_WRITEABLE}을 사용하여 권한을 완화하려고 시도하면
203{@link java.lang.SecurityException}이 트리거됩니다.
204    <p class="note">
205      <strong>참고:</strong> 아직까지는 이 제한이 완전히 적용되지 않습니다.
206      앱이 여전히 기본
207API 또는 {@link java.io.File File} API를 사용하여 개인 디렉터리에 대한 권한을 수정할 수도 있습니다. 하지만
208개인 디렉터리에 대한 권한은 부득이한 경우가 아니라면 완화하지 않는 것이 좋습니다.
209    </p>
210  </li>
211  <li>
212    패키지 도메인 외부에서 <code>file://</code> URI를 전달하면 수신기가 액세스 불가능한 경로로
213 남아 있을 수 있습니다. 따라서
214<code>file://</code> URI를 전달하려고 시도하면
215<code>FileUriExposedException</code>이 트리거됩니다. 개인 파일의 내용을 공유하기 위해
216권장되는 방법은 {@link
217 android.support.v4.content.FileProvider}를 사용하는 것입니다.
218  </li>
219  <li>
220    {@link android.app.DownloadManager}는 비공개로
221저장된 파일을 더 이상 파일 이름별로 공유할 수 없습니다. 레거시 애플리케이션은 {@link
222 android.app.DownloadManager#COLUMN_LOCAL_FILENAME}에 액세스할 때
223액세스가 불가능한 경로가 될 수 있습니다. Android N 이상을
224대상으로 하는 앱은 {@link android.app.DownloadManager#COLUMN_LOCAL_FILENAME}에 액세스할 때 {@link java.lang.SecurityException}을
225트리거합니다.
226
227
228{@link
229 android.app.DownloadManager.Request#setDestinationInExternalFilesDir
230 DownloadManager.Request.setDestinationInExternalFilesDir()} 또는
231 {@link
232 android.app.DownloadManager.Request#setDestinationInExternalPublicDir
233 DownloadManager.Request.setDestinationInExternalPublicDir()}
234을 사용하여 다운로드
235위치를 공용 위치로 설정하는 레거시 애플리케이션은
236{@link android.app.DownloadManager#COLUMN_LOCAL_FILENAME}에 있는 경로에 여전히 액세스할 수 있지만, 이
237 메서드는 부득이한 경우가 아니라면 사용하지 않는 것이 좋습니다. {@link android.app.DownloadManager}에 의해 노출되는 파일에
238액세스하는 좋은 방법은
239{@link android.content.ContentResolver#openFileDescriptor
240 ContentResolver.openFileDescriptor()}를 사용하는 것입니다.
241  </li>
242</ul>
243
244<h2 id="sharing-files">앱 사이의 파일 공유</h2>
245
246<p>
247Android N을 대상으로 하는 앱의 경우, Android 프레임워크는 앱 외부에서 {@code file://} URI의 노출을
248금지하는 {@link android.os.StrictMode} API 정책을
249적용합니다. 파일 URI를 포함하는 인텐트가 앱을 떠나면
250{@code FileUriExposedException} 예외가 생기면서 앱에 오류가 발생합니다.
251</p>
252
253<p>
254애플리케이션 간에 파일을 공유하려면 {@code content://} URI를
255보내고 이 URI에 대해 임시 액세스 권한을 부여해야 합니다. 이 권한을 가장 쉽게 부여하는 방법은
256{@link android.support.v4.content.FileProvider} 클래스를 사용하는 방법입니다. 권한과 파일 공유에
257대한 자세한
258내용은 <a href="{@docRoot}training/secure-file-sharing/index.html">파일 공유</a>를 참조하세요.
259</p>
260
261<h2 id="accessibility">접근성 향상</h2>
262
263<p>
264  Android N에는 시력이 나쁘거나 손상된 사용자를 위해 플랫폼의
265 사용성을 개선하기 위한 변경 사항이 포함되어 있습니다. 이러한 변경 사항에서는 일반적으로
266 앱의 코드를 변경할 필요가 없지만, 사용자 환경에
267 미치는 잠재적인 영향을 평가하기 위해 이들 기능을 검토하고
268 앱으로 테스트해야 합니다.
269</p>
270
271
272<h3 id="screen-zoom">화면 확대/축소</h3>
273
274<p>
275  Android N에서는 사용자가 <strong>Display size</strong>를 설정할 수
276있으며, 이 설정에서 화면의 모든 요소를 확대하거나 축소할 수 있으므로, 시력이
277나쁜 사용자의 기기 접근성이 향상됩니다. 최소 화면 너비인 <a href="http://developer.android.com/guide/topics/resources/providing-resources.html">sw320dp</a>를 초과하는 화면은 사용자가 확대/축소할
278 수 없으며, 이 너비는 일반적인 중간 크기 전화기인 Nexus 4의
279 너비입니다.
280</p>
281
282<div class="cols">
283
284<div class="col-6">
285  <img src="{@docRoot}preview/images/screen-zoom-1.png" alt="" height="XXX" id="figure1" />
286</div>
287<div class="col-6">
288  <img src="{@docRoot}preview/images/screen-zoom-2.png" alt="" height="XXX" id="figure1" />
289</div>
290
291</div> <!-- end cols -->
292<p class="img-caption">
293  <strong>그림 3.</strong> 오른쪽 화면은 Android N 시스템 이미지가
294실행 중인 기기의 Display size를 늘릴 때의 효과를 보여줍니다.
295</p>
296
297
298<p>
299  기기 밀도가 변경되면 시스템은 다음과 같은 방식으로 실행 중인
300 앱에게 알립니다.
301</p>
302
303<ul>
304  <li>앱이 API 레벨 23 이하를 대상으로 하는 경우 시스템에서는
305모든 백그라운드 프로세스를 자동으로 종료합니다. 즉, 사용자가 이들
306 앱으로부터 전환하여 <em>Settings</em> 화면을
307 열고 <strong>Display size</strong> 설정을 변경하면, 시스템은 저용량 메모리
308 상황에서와 동일한 방식으로 앱을 종료합니다. 앱에 포그라운드 프로세스가
309 있는 경우, <a href="{@docRoot}guide/topics/resources/runtime-changes.html">런타임 변경 처리</a>에 설명된 대로, 시스템은
310 마치 기기의 방향이 변경된
311 것처럼 구성 변경을 해당 프로세스에 알립니다.
312  </li>
313
314  <li>앱이 Android N을 대상으로 하는 경우,
315<a href="{@docRoot}guide/topics/resources/runtime-changes.html">런타임 변경 처리</a>에 설명된
316대로, 구성 변경을 모든 프로세스(포그라운드 및 백그라운드)에
317알립니다.
318  </li>
319</ul>
320
321<p>
322  앱이 Android 모범 사례를 따르기만 한다면, 대부분의 앱은 이 기능을
323 지원하기 위해 어떠한 변경도 수행할 필요가 없습니다. 확인할 사항은 구체적으로 다음과 같습니다.
324</p>
325
326<ul>
327  <li>화면 너비가 <code><a href=
328  "{@docRoot}guide/topics/resources/providing-resources.html">sw320dp</a></code>인 기기에서 앱을 테스트하고 적절하게 작동하는지
329 확인하세요.
330  </li>
331
332  <li>기기 구성이 변경되는 경우, 밀도에 종속된 모든 캐시된
333정보(예: 캐시된 비트맵 또는 네트워크에서 로드된 리소스)를
334업데이트하세요. 앱이 일시 정지 상태에서 다시 시작하는 경우 구성
335 변경을 확인하세요.
336    <p class="note">
337      <strong>참고:</strong> 구성에 종속된 데이터를 캐시하는 경우,
338 해당 데이터에 적절한 화면 크기 또는 픽셀 밀도와 같은 관련 메타데이터를
339 포함시키는 것이 좋습니다. 이 메타데이터를 저장해 놓으면,
340 구성이 변경된 후에 캐시된 데이터를 새로 고칠지 여부를
341 결정할 수 있습니다.
342    </p>
343  </li>
344
345  <li>픽셀 단위는 화면 밀도에 따라
346 변하지 않으므로, 이 단위로 치수를 지정하지 마세요. 그 대신, <a href="{@docRoot}guide/practices/screens_support.html">밀도에 독립적인 픽셀</a>(<code>dp</code>) 단위로
347 치수를 지정하세요.
348  </li>
349</ul>
350
351<h3 id="vision-settings">설정 마법사의 Vision Settings</h3>
352
353<p>
354  Android N에는 Welcome 화면에 Vision Settings가 포함되어
355있으며, 여기서 사용자는
356  <strong>Magnification gesture</strong>, <strong>Font size</strong>,
357<strong>Display size</strong> 및 <strong>TalkBack</strong>의 접근성 설정을 새 기기에 구성할 수 있습니다. 이러한
358변경은 다른 화면 설정에 관련된 버그의 가시성을 증대시킵니다. 이 기능의 영향을 평가하려면,
359 이들 설정을 활성화하여 앱을
360 테스트해야 합니다. 이 설정은 <strong>Settings &gt;
361  Accessibility</strong> 아래에 있습니다.
362</p>
363
364<h2 id="ndk">플랫폼 라이브러리에 연결되는 NDK 앱</h2>
365
366<p>
367  비공개 API가 로드되는 것을 막기 위해 Android N에는 네임스페이스 변경이 포함되어 있습니다.
368  NDK를 사용하는 경우에는 Android 플랫폼에서
369 공개 API를 사용해야만 합니다. Android의 다음 번 공식 릴리스에서 비공개 API를 사용하면 앱 작동이 중단될 수
370 있습니다.
371</p>
372
373<p>
374  비공개 API의 사용을 여러분에게 경고하기 위해, Android N 기기에서 실행
375 중인 앱은 어떤 앱이 비공개 API를 호출할 때 logcat 출력에 오류를 생성합니다.
376  또한, 이런 상황이 잘 인식될 수 있도록
377 이 오류가 기기 화면에도 메시지로 표시됩니다. 여러분이 앱 코드를 검토하여
378 비공개 플랫폼 API의 사용을 제거해야 하며, 프리뷰 기기 또는
379 에뮬레이터를 사용하여 앱을 철저히 테스트해야 합니다.
380</p>
381
382<p>
383  앱이 플랫폼 라이브러리에 종속된 경우, 개인 API를 이와 동등한
384 공개 API로 바꾸기 위한 일반적인 수정 사항을 NDK 문서에서 참조하세요.
385  또한, 자신도 모르는 사이에 플랫폼 라이브러리에
386 연결되어 있을 수가 있으며, 특히 여러분의 앱이 사용하는 라이브러리가 플랫폼의
387 일부(예: <code>libpng</code>)이지만 NDK의 일부가 아닌 경우에는 더 그렇습니다. 이 경우에는 연결에
388필요한 모든 .so 파일이 APK에 포함되어 있는지 확인하세요.
389</p>
390
391<p class="caution">
392  <strong>주의:</strong> 일부 타사 라이브러리가 비공개 API에
393 연결될 수도 있습니다. 앱이 이들 라이브러리를 사용하는 경우, Android의
394 다음 번 공식 릴리스에서 실행할 때 앱 작동이 중단될 수 있습니다.
395</p>
396
397<p>
398  앱은 NDK에 포함되지 않은 고유 라이브러리를 사용하거나
399 이에 종속되어서는 안 됩니다. 왜냐하면 이 라이브러리는 특정
400 Android 릴리스에서 다른 릴리스로 변경되거나 제거될 수 있기 때문입니다. OpenSSL에서 BoringSSL로의 전환은 이러한 변경의 한 예입니다.
401  또한, NDK에 포함되지 않은
402플랫폼 라이브러리에는 호환성 요구 사항이 없기 때문에, 다른 장치에서는
403호환성 레벨이 다를 수도 있습니다. 구형 기기에 있는 비 NDK 라이브러리에 액세스해야 하는 경우
404Android API 레벨에 따라 로드를 수행하세요.
405</p>
406
407<p>
408  이러한 유형의 문제를 진단하는 데 도움을 주기 위해, 여기서는
409 Android N으로 앱을 빌드할 때 발생할 수 있는 Java 및 NDK 오류의 몇 가지 예를 보여줍니다.
410</p>
411
412<p>Java 오류의 예:</p>
413<pre class="no-pretty-print">
414java.lang.UnsatisfiedLinkError: dlopen failed: library "/system/lib/libcutils.so"
415    is not accessible for the namespace "classloader-namespace"
416</pre>
417
418<p>NDK 오류의 예:</p>
419<pre class="no-pretty-print">
420dlopen failed: cannot locate symbol "__system_property_get" referenced by ...
421</pre>
422
423
424<p>
425  다음은 이러한 유형의 오류가 발생한 앱의 몇 가지 일반적인 수정사항입니다.
426</p>
427
428<ul>
429  <li>libandroid_runtime.so에서 getJavaVM 및 getJNIEnv 사용은 표준
430 JNI 함수로 교체될 수 있습니다.
431<pre class="no-pretty-print">
432AndroidRuntime::getJavaVM -&gt; GetJavaVM from &lt;jni.h&gt;
433AndroidRuntime::getJNIEnv -&gt; JavaVM::GetEnv or
434JavaVM::AttachCurrentThread from &lt;jni.h&gt;.
435</pre>
436  </li>
437
438  <li>{@code libcutils.so}에서 {@code property_get} 기호 사용은 공개
439 {@code alternative __system_property_get}으로 교체될 수 있습니다.
440   이렇게 하려면, 다음의 include와 함께 {@code __system_property_get}을 사용하세요.
441<pre>
442#include &lt;sys/system_properties.h&gt;
443</pre>
444  </li>
445
446  <li>{@code libcrypto.so}에서 {@code SSL_ctrl} 기호 사용은 앱
447로컬 버전으로 교체되어야 합니다. 예를 들어, {@code .so} 파일에서
448 {@code libcyrpto.a}를 정적으로 링크하거나 BoringSSL 또는 OpenSSL에서
449 {@code libcrypto.so}를 동적으로 앱에 포함시켜야 합니다.
450  </li>
451</ul>
452
453<h2 id="afw">Android for Work</h2>
454<p>
455  Android N에는 Android for Work를 대상으로 하는 앱에 대한 변경 사항이
456포함되어 있습니다. 인증서 설치, 비밀번호 재설정,
457보조 사용자 관리 및 기기 식별자 액세스에 대한 변경 사항이 이에 포함됩니다. Android for Work 환경용 앱을 빌드하는 경우에는 이러한
458 변경 사항을 검토하고 그에 따라
459앱을 수정해야 합니다.
460</p>
461
462<ul>
463  <li>DPC가 인증서를 설정할 수 있으려면, 위임된 인증서 설치 관리자를 여러분이 먼저
464 설치해야 합니다. N SDK를 대상으로 하는 프로필 소유자
465 앱 및 기기 소유자 앱의 경우, 기기 정책 컨트롤러(DPC)가 <code>DevicePolicyManager.setCertInstallerPackage()</code>를 호출하기
466 전에, 위임된 인증서 설치 관리자를 여러분이 먼저
467설치해야 합니다. 아직 설치 관리자가
468설치되지 않은 경우 시스템에서 <code>IllegalArgumentException</code>이
469발생합니다.
470  </li>
471
472  <li>이제 기기 관리자의 비밀번호 재설정 제한이 프로필 소유자에게도
473 적용됩니다. 기기 관리자는 이미 설정된 암호를 변경하거나
474 지우기 위해 {@code DevicePolicyManager.resetPassword()}를 더 이상 사용할
475 수 없습니다. 기기 관리자는
476 기기에 비밀번호, PIN 또는 패턴이 없는 경우에만 비밀번호를 설정할 수 있습니다.
477  </li>
478
479  <li>제한이 설정되어 있더라도 기기 소유자 및 프로필 소유자는
480 계정을 관리할 수 있습니다. <code>DISALLOW_MODIFY_ACCOUNTS</code> 사용자
481 제한이 있더라도 기기 소유자 및 프로필 소유자는 계정 관리 API를 호출할 수 있습니다.
482  </li>
483
484  <li>기기 소유자는 보조 사용자를 보다 쉽게 관리할 수 있습니다. 기기가
485기기 소유자 모드에서 실행 중인 경우 <code>DISALLOW_ADD_USER</code> 제한이
486자동으로 설정됩니다. 이렇게 하면 사용자는 관리되지 않는 보조 사용자를 생성할 수
487없습니다. 또한, <code>CreateUser()</code> 및
488 <code>createAndInitializeUser()</code> 메서드가 사용 중단되었으며, 새로운
489<code>DevicePolicyManager.createAndManageUser()</code> 메서드로 대체되었습니다.
490  </li>
491
492  <li>기기 소유자는 기기 식별자에 액세스할 수 있습니다. 기기
493소유자는 <code>DevicePolicyManagewr.getWifiMacAddress()</code>를 사용하여 기기의
494 Wi-Fi MAC 주소에 액세스할 수 있습니다. 기기에서
495Wi-Fi가 활성화된 적이 없는 경우 이 메서드는 {@code null} 값을 반환합니다.
496  </li>
497
498  <li>Work Mode 설정은 업무용 앱에 대한 액세스를 제어합니다. 작업 모드가 해제되면
499시스템 런처에서는 업무용 앱을 회색으로 표시하여 해당 앱이 사용될 수 없음을 나타냅니다. 작업 모드를
500 다시 활성화하면 정상적인 동작이 복원됩니다.
501</ul>
502
503<p>
504  Android N에서 Android for Work의 변경 사항에 대한 자세한 내용은
505<a href="{@docRoot}preview/features/afw.html">Android for Work 업데이트</a>를 참조하세요.
506</p>
507
508<h2 id="annotations">주석 보존</h2>
509
510<p>
511Android N에서는 주석의 표시 여부가 무시되던 버그가 수정되었습니다. 이 문제로 인해 런타임이 액세스할 수 없어야 하는 주석에 액세스할 수 있었습니다.
512
513 이러한 주석으로는 다음이 포함됩니다.
514</p>
515
516<ul>
517   <li>{@code VISIBILITY_BUILD}: 빌드 시에만 표시되어야 합니다.</li>
518   <li>{@code VISIBILITY_SYSTEM}: 런타임에
519기본 시스템에만 표시되어야 합니다.</li>
520</ul>
521
522<p>
523앱이 이 동작에 의존했다면, 런타임에 사용할 수 있어야 하는
524주석에 보존 정책을 추가하세요. {@code @Retention(RetentionPolicy.RUNTIME)}을 사용하여 추가하면 됩니다.
525</p>
526
527<h2 id="other">기타 중요한 사항</h2>
528
529<ul>
530<li>앱이 Android N에서 실행 중일 때 API 레벨이 낮고 사용자가 표시
531크기를 변경하는 경우, 해당 앱 프로세스가 종료됩니다. 앱은 이
532시나리오를 매끄럽게 처리할 수 있어야 합니다. 그렇지 않으면 사용자가 Recents에서
533앱을 복원할 때 앱 작동이 중단됩니다.
534
535<p>
536이러한 동작이 발생하지 않도록 앱을 테스트해야 합니다.
537DDMS를 통해 수동으로 앱을 종료할 때
538동일한 작동 중단을 유발시킴으로써 테스트를 수행할
539수 있습니다.
540</p>
541
542<p>
543N 이상을 대상으로 하는 앱은 밀도 변경 시에 자동으로 종료되지 않지만,
544구성 변경에는 제대로 응답하지 못할 수도 있습니다.
545</p>
546</li>
547
548<li>
549Android N에서 앱은 구성 변경을 매끄럽게 처리할 수 있어야 하며,
550이후에 시작할 때도 작동이 중단되어서는 안 됩니다. 글꼴
551크기(<strong>Setting</strong> &gt;
552<strong>Display</strong> &gt; <strong>Font size</strong>)를 변경하여 앱 동작을 검사한 다음, Recents에서
553앱을 복원할 수 있습니다.
554</li>
555
556<li>
557이전 버전의 Android에서는 버그 때문에, 시스템이 주 스레드에서
558TCP 소켓에 대한 쓰기를 엄격 모드 위반으로서 플래그하지 못했습니다. Android N에서는 이 버그가 수정되었습니다.
559이 동작을 보이는 앱에서는 이제 {@code android.os.NetworkOnMainThreadException}이 발생합니다.
560일반적으로, 주 스레드에서 네트워크 작업을 수행하면 일반적으로
561테일 지연 시간이 길어져 ANR 및 쟁크(jank)를 유발하므로, 이런 작업은 수행하지 않는 것이 좋습니다.
562</li>
563
564<li>
565{@code Debug.startMethodTracing()} 계열에 속하는 메서드는,
566SD 카드의 최상위 레벨에 저장하는 것이 아니라, 이제 공유 저장소의
567패키지별 디렉터리에 출력을 기본적으로
568저장합니다.  즉, 앱은 이들 API를 사용하기 위해 {@code WRITE_EXTERNAL_STORAGE} 권한을 요청할 필요가 더 이상 없습니다.
569</li>
570
571<li>
572상당수 플랫폼 API는 이제 대용량
573페이로드가 {@link android.os.Binder} 트랜잭션을 통해 전송되는 것을 확인하기 시작했으며, 시스템에서는
574이제 {@code TransactionTooLargeExceptions}를
575자동으로 로깅하거나 억제하는 대신 {@code RuntimeExceptions}로 다시 발생시킵니다.  한 가지
576공통적인 예는
577{@link android.app.Activity#onSaveInstanceState Activity.onSaveInstanceState()}에
578너무 많은 데이터를 저장하는 바람에, 앱이 Android N을 대상으로 할 때 {@code ActivityThread.StopInfo}가
579{@code RuntimeException}을 발생시키는 경우입니다.
580</li>
581
582<li>
583앱이 {@link java.lang.Runnable} 작업을 {@link android.view.View}에 게시하고
584{@link android.view.View}가
585창에 연결되지 않은 경우, 시스템에서는
586{@link android.view.View}가 있는 {@link java.lang.Runnable} 작업을 큐에 넣으며,
587{@link java.lang.Runnable} 작업은
588{@link android.view.View}가 창에 연결될 때까지
589실행되지 않습니다. 이 동작은 다음과 같은 버그를 수정합니다.
590<ul>
591   <li>의도한 창의 UI 스레드가 아닌 다른 스레드에서 {@link android.view.View}에 앱이 게시된 경우,
592결과적으로 {@link java.lang.Runnable}이 잘못된 스레드에서 실행될 수 있습니다.
593   </li>
594   <li>{@link java.lang.Runnable} 작업이 루퍼 스레드가 아닌 다른 스레드에서
595게시되었다면 해당 앱이 {@link java.lang.Runnable} 작업을 노출시킬 수도 있습니다.</li>
596</ul>
597</li>
598
599<li>
600{@link android.Manifest.permission#DELETE_PACKAGES DELETE_PACKAGES}
601권한이
602있는 Android N 상의 앱이 패키지를 삭제하려고 하지만, 해당 패키지를 다른 앱이 설치한 경우에는
603사용자의 확인이 필요합니다. 이 시나리오에서는 앱이
604{@link android.content.pm.PackageInstaller#uninstall PackageInstaller.uninstall()}을 호출할 때
605{@link android.content.pm.PackageInstaller#STATUS_PENDING_USER_ACTION STATUS_PENDING_USER_ACTION}을
606반환 상태로 예상해야 합니다.
607</li>
608
609</ul>
610
611