1page.title=Otimizações em segundo plano 2page.metaDescription=Novas restrições a transmissões implícitas. 3page.keywords="android N", "implicit broadcasts", "job scheduler" 4page.image=images/cards/card-nyc_2x.jpg 5 6@jd:body 7 8<div id="qv-wrapper"> 9 <div id="qv"> 10 <h2> 11 Neste documento 12 </h2> 13 14 <ol> 15 <li> 16 <a href="#connectivity-action">Restrições sobre CONNECTIVITY_ACTION</a> 17 </li> 18 19 <li> 20 <a href="#sched-jobs">Agendamento de trabalhos de rede em conexões 21 ilimitadas</a> 22 </li> 23 24 <li> 25 <a href="#monitor-conn">Monitoramento de conectividade de rede durante a execução 26 do aplicativo</a> 27 </li> 28 29 <li> 30 <a href="#media-broadcasts">Restrições sobre NEW_PICTURE e 31 NEW_VIDEO</a> 32 </li> 33 34 <li> 35 <a href="#new-jobinfo">Novos métodos JobInfo</a> 36 </li> 37 38 <li> 39 <a href="#new-jobparam">Novos métodos JobParameter</a> 40 </li> 41 42 <li> 43 <a href="#further-optimization">Otimização adicional do aplicativo</a> 44 </li> 45 </ol> 46 </div> 47</div> 48 49<p> 50 Os processos em segundo plano podem fazer uso intensivo de memória e bateria. Por exemplo, uma 51 transmissão implícita poderá iniciar diversos processos em segundo plano registrados 52 para escutá-la, mesmo se esses processos não forem muito usados. Isso pode afetar 53 substancialmente o desempenho do dispositivo e a experiência do usuário. 54</p> 55 56<p> 57 Para aliviar esse problema, o Android N aplica as seguintes 58restrições: 59</p> 60 61<ul> 62 <li>Os aplicativos direcionados ao Preview não receberão transmissões {@link 63 android.net.ConnectivityManager#CONNECTIVITY_ACTION} se estiverem 64 registrados para recebê-las no seu manifesto. Os aplicativos em execução ainda 65poderão escutar {@code CONNECTIVITY_CHANGE} no encadeamento principal registrando um 66{@link android.content.BroadcastReceiver} em {@link 67 android.content.Context#registerReceiver Context.registerReceiver()}. 68 </li> 69 70 <li>Os aplicativos não podem enviar nem receber transmissões {@link 71 android.hardware.Camera#ACTION_NEW_PICTURE} ou {@link 72 android.hardware.Camera#ACTION_NEW_VIDEO}. Essa otimização 73 afeta todos os aplicativos e não apenas os direcionados ao Preview. 74 </li> 75</ul> 76 77<p> 78 Se o seu aplicativo usar qualquer uma dessas intenções, remova as dependências delas 79 assim que possível para direcionar corretamente os dispositivos Android N. 80 A estrutura do Android oferece diversas soluções para reduzir a necessidade dessas 81 transmissões implícitas. Por exemplo, {@link android.app.job.JobScheduler} 82 e <a href="https://developers.google.com/android/reference/com/google/android/gms/gcm/GcmNetworkManager"> 83{@code GcmNetworkManager}</a> oferecem mecanismos robustos para agendar operações 84 de rede quando ocorrem condições especificadas, como conexão a uma 85 rede ilimitada. Agora, você também pode usar {@link android.app.job.JobScheduler} 86 para reagir a mudanças em provedores de conteúdo. Os objetos {@link android.app.job.JobInfo} 87 encapsulam os parâmetros usados por {@link android.app.job.JobScheduler} 88 para agendar o seu trabalho. Quando as condições do trabalho forem atendidas, o sistema 89 executará o trabalho no {@link android.app.job.JobService} do seu aplicativo. 90</p> 91 92<p> 93 Neste documento, veremos como usar métodos alternativos, como 94 {@link android.app.job.JobScheduler}, para adaptar seu aplicativo a essas novas 95 restrições. 96</p> 97 98<h2 id="connectivity-action"> 99 Restrições sobre CONNECTIVITY_ACTION 100</h2> 101 102<p> 103 Os aplicativos direcionados ao Android N não receberão transmissões {@link 104 android.net.ConnectivityManager#CONNECTIVITY_ACTION} se estiverem 105 registrados para recebê-las no seu manifesto e os processos que dependerem dessas 106 transmissões não serão iniciados. Isso pode ser um problema para aplicativos que quiserem 107 escutar mudanças de rede ou executar atividades de rede em massa quando o 108 dispositivo se conectar a uma rede ilimitada. Já existem várias soluções para contornar essa 109 restrição na estrutura do Android, mas a escolha da solução correta 110 depende do que o aplicativo pretende realizar. 111</p> 112 113<p class="note"> 114 <strong>Observação:</strong> Um {@link android.content.BroadcastReceiver} registrado em 115 {@link android.content.Context#registerReceiver Context.registerReceiver()} 116 continuará a receber essas transmissões enquanto o aplicativo estiver em execução. 117</p> 118 119<h3 id="sched-jobs"> 120 Agendamento de trabalhos de rede em conexões ilimitadas 121</h3> 122 123<p> 124 Ao usar a classe {@link android.app.job.JobInfo.Builder JobInfo.Builder} 125 para compilar o objeto {@link android.app.job.JobInfo}, aplique o método {@link 126 android.app.job.JobInfo.Builder#setRequiredNetworkType 127 setRequiredNetworkType()} e passe {@link android.app.job.JobInfo 128 JobInfo.NETWORK_TYPE_UNMETERED} como parâmetro do trabalho. O código a seguir 129 agendará a execução de um serviço quando o dispositivo se conectar a uma rede 130 ilimitada e estiver carregando: 131</p> 132 133<pre> 134public static final int MY_BACKGROUND_JOB = 0; 135... 136public static void scheduleJob(Context context) { 137 JobScheduler js = 138 (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE); 139 JobInfo job = new JobInfo.Builder( 140 MY_BACKGROUND_JOB, 141 new ComponentName(context, MyJobService.class)) 142 .setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED) 143 .setRequiresCharging(true) 144 .build(); 145 js.schedule(job); 146} 147</pre> 148 149<p> 150 Quando as condições para o trabalho forem atendidas, o aplicativo receberá um retorno de chamada para executar 151 o método {@link android.app.job.JobService#onStartJob onStartJob()} na 152 {@code JobService.class} especificada. Para ver mais exemplos da implementação de {@link 153 android.app.job.JobScheduler}, consulte o <a href="{@docRoot}samples/JobScheduler/index.html">aplicativo de exemplo do JobScheduler</a>. 154</p> 155 156<p> 157 Os aplicativos que usarem serviços do GMSCore e forem direcionados ao Android 5.0 (nível da API 21) 158 ou anterior poderão usar <a href="https://developers.google.com/android/reference/com/google/android/gms/gcm/GcmNetworkManager"> 159 {@code GcmNetworkManager}</a> e especificar {@code Task.NETWORK_STATE_UNMETERED}. 160</p> 161 162<h3 id="monitor-conn"> 163 Monitoramento de conectividade de rede durante a execução do aplicativo 164</h3> 165 166<p> 167 Os aplicativos em execução ainda poderão escutar {@code CONNECTIVITY_CHANGE} com um 168 {@link android.content.BroadcastReceiver} registrado. No entanto, a API {@link 169 android.net.ConnectivityManager} oferece um método mais robusto para solicitar 170 um retorno de chamada apenas quando condições de rede especificadas são atendidas. 171</p> 172 173<p> 174 Os objetos {@link android.net.NetworkRequest} definem os parâmetros do 175 retorno de chamada de rede em termos de {@link android.net.NetworkCapabilities}. Objetos 176 {@link android.net.NetworkRequest} são criados com a classe {@link 177 android.net.NetworkRequest.Builder NetworkRequest.Builder}. Em seguida, {@link 178 android.net.ConnectivityManager#registerNetworkCallback(android.net.NetworkRequest, 179 android.net.ConnectivityManager.NetworkCallback) registerNetworkCallback()} 180 passa o objeto {@link android.net.NetworkRequest} ao sistema. Quando 181 as condições de rede forem atendidas, o aplicativo receberá um retorno de chamada para executar o 182 método {@link android.net.ConnectivityManager.NetworkCallback#onAvailable 183 onAvailable()} definido em sua classe {@link 184 android.net.ConnectivityManager.NetworkCallback}. 185</p> 186 187<p> 188 O aplicativo continuará a receber retornos de chamada até que o aplicativo encerre ou chame 189 {@link android.net.ConnectivityManager#unregisterNetworkCallback 190 unregisterNetworkCallback()}. 191</p> 192 193<h2 id="media-broadcasts"> 194 Restrições sobre NEW_PICTURE e NEW_VIDEO 195</h2> 196 197<p> 198 No Android N, os aplicativos não conseguem enviar nem receber transmissões {@link 199 android.hardware.Camera#ACTION_NEW_PICTURE} ou {@link 200 android.hardware.Camera#ACTION_NEW_VIDEO}. Essa restrição ajuda a 201 aliviar os impactos no desempenho e na experiência de usuário quando vários aplicativos devem 202 despertar para processar uma nova imagem ou vídeo. O Android N 203 estende {@link android.app.job.JobInfo} e {@link 204 android.app.job.JobParameters} para oferecer uma solução alternativa. 205</p> 206 207<h3 id="new-jobinfo"> 208 Novos métodos JobInfo 209</h3> 210 211<p> 212 Para acionar trabalhos em mudanças de URI de conteúdo, o Android N estende 213 a API {@link android.app.job.JobInfo} com os seguintes métodos: 214</p> 215 216<dl> 217 <dt> 218 {@code JobInfo.TriggerContentUri()} 219 </dt> 220 221 <dd> 222 Encapsula os parâmetros necessários para acionar um trabalho quando ocorrem mudanças de URI de conteúdo. 223 </dd> 224 225 <dt> 226 {@code JobInfo.Builder.addTriggerContentUri()} 227 </dt> 228 229 <dd> 230 Passa um objeto {@code TriggerContentUri} para {@link 231 android.app.job.JobInfo}. Um {@link android.database.ContentObserver} 232 monitora o URI de conteúdo encapsulado. Se houver vários objetos {@code 233 TriggerContentUri} associados a um trabalho, o sistema fornecerá um 234 retorno de chamada, mesmo se indicar uma mudança em apenas um dos URIs de conteúdo. 235 </dd> 236 237 <dd> 238 Adicione o sinalizador {@code TriggerContentUri.FLAG_NOTIFY_FOR_DESCENDANTS} para 239 acionar o trabalho em caso de mudança em qualquer um dos descendentes do URI especificado. Esse indicador 240 corresponde ao parâmetro {@code notifyForDescendants} passado para {@link 241 android.content.ContentResolver#registerContentObserver 242 registerContentObserver()}. 243 </dd> 244</dl> 245 246<p class="note"> 247 <strong>Observação:</strong> não é possível usar {@code TriggerContentUri()} 248 juntamente com {@link android.app.job.JobInfo.Builder#setPeriodic 249 setPeriodic()} ou {@link android.app.job.JobInfo.Builder#setPersisted 250 setPersisted()}. Para monitorar continuamente mudanças de conteúdo, agende um novo 251 {@link android.app.job.JobInfo} antes que o {@link 252 android.app.job.JobService} do aplicativo encerre o processamento do retorno de chamada mais recente. 253</p> 254 255<p> 256 O exemplo de código a seguir agenda um trabalho que será acionado quando o sistema indicar 257 uma mudança no URI de conteúdo {@code MEDIA_URI}: 258</p> 259 260<pre> 261public static final int MY_BACKGROUND_JOB = 0; 262... 263public static void scheduleJob(Context context) { 264 JobScheduler js = 265 (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE); 266 JobInfo.Builder builder = new JobInfo.Builder( 267 MY_BACKGROUND_JOB, 268 new ComponentName(context, MediaContentJob.class)); 269 builder.addTriggerContentUri( 270 new JobInfo.TriggerContentUri(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, 271 JobInfo.TriggerContentUri.FLAG_NOTIFY_FOR_DESCENDANTS)); 272 js.schedule(builder.build()); 273} 274</pre> 275<p> 276 Quando o sistema indicar uma mudança nos URIs de conteúdo especificados, o aplicativo 277 receberá um retorno de chamada e um objeto {@link android.app.job.JobParameters} será 278 passado para o método {@link android.app.job.JobService#onStartJob onStartJob()} 279 na {@code MediaContentJob.class}. 280</p> 281 282<h3 id="new-jobparam"> 283 Novos métodos JobParameter 284</h3> 285 286<p> 287 O Android N também estende {@link android.app.job.JobParameters} para 288 permitir que o aplicativo receba informações úteis sobre quais autoridades de conteúdo 289 e URIs acionaram o trabalho: 290</p> 291 292<dl> 293 <dt> 294 {@code Uri[] getTriggeredContentUris()} 295 </dt> 296 297 <dd> 298 Retorna uma matriz de URIs que acionaram o trabalho. O retorno será {@code 299 null} se o trabalho não foi acionado por URIs (por exemplo, o trabalho foi 300 acionado devido a um prazo ou por outro motivo) ou o número de URIs modificados 301 for maior que 50. 302 </dd> 303 304 <dt> 305 {@code String[] getTriggeredContentAuthorities()} 306 </dt> 307 308 <dd> 309 Retorna uma matriz de strings de autoridades de conteúdo que acionaram o trabalho. 310 Se a matriz retornada não for {@code null}, use {@code getTriggeredContentUris()} 311 para recuperar os detalhes sobre quais URIs foram modificados. 312 </dd> 313</dl> 314 315<p> 316 O exemplo de código a seguir substitui o método {@link 317 android.app.job.JobService#onStartJob JobService.onStartJob()} e 318 registra as autoridades de conteúdo e URIs que acionaram o trabalho: 319</p> 320 321<pre> 322@Override 323public boolean onStartJob(JobParameters params) { 324 StringBuilder sb = new StringBuilder(); 325 sb.append("Media content has changed:\n"); 326 if (params.getTriggeredContentAuthorities() != null) { 327 sb.append("Authorities: "); 328 boolean first = true; 329 for (String auth : 330 params.getTriggeredContentAuthorities()) { 331 if (first) { 332 first = false; 333 } else { 334 sb.append(", "); 335 } 336 sb.append(auth); 337 } 338 if (params.getTriggeredContentUris() != null) { 339 for (Uri uri : params.getTriggeredContentUris()) { 340 sb.append("\n"); 341 sb.append(uri); 342 } 343 } 344 } else { 345 sb.append("(No content)"); 346 } 347 Log.i(TAG, sb.toString()); 348 return true; 349} 350</pre> 351 352<h2 id="further-optimization"> 353 Otimização adicional do aplicativo 354</h2> 355 356<p> 357 A otimização dos aplicativos para execução em dispositivos com pouca memória ou em 358 condições de pouca memória pode melhorar o desempenho e a experiência do usuário. A remoção de 359 dependências de serviços em segundo plano e receptores de transmissão 360 implícita registrados estatisticamente pode aprimorar a execução do aplicativo nesses dispositivos. Embora 361 o Android N avance na redução de alguns desses problemas, 362 recomendamos que você otimize os aplicativos para execução sem o uso desses 363 processos em segundo plano. 364</p> 365 366<p> 367 O Android N introduz alguns comandos adicionais do <a href="{@docRoot}tools/help/adb.html">Android Debug Bridge (ADB)</a> que 368 podem ser usados para testar o comportamento do aplicativo de teste com esses processos em segundo plano desativados: 369</p> 370 371<ul> 372 <li>Para simular condições em que transmissões implícitas e serviços em segundo plano 373 não estão disponíveis, insira o seguinte comando: 374 </li> 375 376 <li style="list-style: none; display: inline"> 377<pre class="no-pretty-print"> 378{@code $ adb shell cmd appops set <package> RUN_IN_BACKGROUND ignore} 379</pre> 380 </li> 381 382 <li>Para reativar transmissões implícitas e serviços em segundo plano, insira o 383 seguinte comando: 384 </li> 385 386 <li style="list-style: none; display: inline"> 387<pre class="no-pretty-print"> 388{@code $ adb shell cmd appops set <package> RUN_IN_BACKGROUND allow} 389</pre> 390 </li> 391</ul> 392