1 page.title=Tratar alteraes no tempo de execuo 2 page.tags=atividade,ciclo de vida 3 @jd:body 4 5 <div id="qv-wrapper"> 6 <div id="qv"> 7 8 <h2>Neste documento</h2> 9 <ol> 10 <li><a href="#RetainingAnObject">Reteno de um objeto durante uma alterao de configurao</a></li> 11 <li><a href="#HandlingTheChange">Tratar voc mesmo da alterao de configurao</a> 12 </ol> 13 14 <h2>Veja tambm</h2> 15 <ol> 16 <li><a href="providing-resources.html">Fornecimento de recursos</a></li> 17 <li><a href="accessing-resources.html">Acesso aos recursos</a></li> 18 <li><a href="http://android-developers.blogspot.com/2009/02/faster-screen-orientation-change.html">Alterao 19 mais rpida da orientao da tela</a></li> 20 </ol> 21 </div> 22 </div> 23 24 <p>Algumas configuraes do dispositivo podem mudar durante o tempo de execuo 25 (como orientao de tela, disponibilidade do teclado e idioma). Quando ocorre uma alterao, 26 o Android precisa reiniciar a execuo 27 de {@link android.app.Activity} ({@link android.app.Activity#onDestroy()} chamado, seguido de {@link 28 android.app.Activity#onCreate(Bundle) onCreate()}). O comportamento de reincio foi projetado para ajudar 29 o aplicativo a se adaptar a novas configuraes recarregando automaticamente o aplicativo 30 com recursos alternativos que correspondam com a configurao do dispositivo.</p> 31 32 <p>Para tratar adequadamente um reincio, importante que a atividade se restaure 33 ao estado anterior por meio do <a href="{@docRoot}guide/components/activities.html#Lifecycle">ciclo de vida 34 da atividade</a>, no qual o Android chama 35 {@link android.app.Activity#onSaveInstanceState(Bundle) onSaveInstanceState()} antes de destruir 36 a atividade para que seja possvel salvar os dados acerca do estado do aplicativo. Em seguida, possvel restaurar o estado 37 durante {@link android.app.Activity#onCreate(Bundle) onCreate()} ou {@link 38 android.app.Activity#onRestoreInstanceState(Bundle) onRestoreInstanceState()}.</p> 39 40 <p>Para testar se o aplicativo se reinicia com o estado de aplicativo intacto, deve-se 41 invocar as alteraes de configurao (como alteraes na orientao da tela) enquanto executa diversas 42 tarefas no aplicativo. O aplicativo deve ser capaz de reiniciar a qualquer momento sem perda 43 de dados do usurio ou estado para tratar eventos como alteraes de configurao ou quando o usurio recebe 44 uma chamada telefnica e, em seguida, retorna ao aplicativo bem depois 45 de destrudo o processo do aplicativo. Para ver como restaurar o estado da atividade, leia sobre o <a href="{@docRoot}guide/components/activities.html#Lifecycle">Ciclo de vida da atividade</a>.</p> 46 47 <p>No entanto, pode-se encontrar uma situao em que o reincio do aplicativo 48 e a restaurao representem quantidades significativas de dados que podem ser custosos e prejudicar a experincia do usurio. Nessa situao, 49 temos duas opes:</p> 50 51 <ol type="a"> 52 <li><a href="#RetainingAnObject">Reter um objeto durante uma alterao de configurao</a> 53 <p>Permita que a atividade reinicie quando uma configurao muda, mas transporte um objeto 54 de estado para a nova instncia da atividade.</p> 55 56 </li> 57 <li><a href="#HandlingTheChange">Tratar voc mesmo da alterao de configurao</a> 58 <p>Evite que o sistema reinicie a atividade durante certas alteraes 59 de configurao, mas receba um retorno de chamada quando as configuraes se alteram, para que voc atualize manualmente 60 a atividade conforme necessrio.</p> 61 </li> 62 </ol> 63 64 65 <h2 id="RetainingAnObject">Reteno de um objeto durante uma alterao de configurao</h2> 66 67 <p>Se a reteno da atividade exigir a recuperao de grandes conjuntos de dados, restabelecer uma conexo 68 de rede ou executar outras operaes intensivas, um reincio completo devido a uma alterao 69 de configurao pode prejudicar a experincia do usurio. Alm disso, pode no ser possvel restaurar completamente 70 o estado da atividade com o {@link android.os.Bundle} que o sistema salva com o retorno de chamada {@link 71 android.app.Activity#onSaveInstanceState(Bundle) onSaveInstanceState()} — ele 72 no foi projetado para transportar objetos grandes (como bitmaps) e os dados contidos devem ser serializados 73 e, em seguida, desserializados, o que pode consumir muita memria e retardar a alterao de configurao. Nesse caso, 74 para aliviar o peso de reinicializar a atividade, pode-se reter um {@link 75 android.app.Fragment} quando a atividade for reiniciada devido a uma alterao de configurao. Esse fragmento 76 pode conter referncias a objetos com estado que seja preciso reter.</p> 77 78 <p>Quando o sistema Android encerra a atividade devido a uma alterao de configurao, os fragmentos 79 da atividade marcados para serem retidos no so destrudos. possvel adicionar esses fragmentos 80 atividade para preservar objetos de estado.</p> 81 82 <p>Para reter objetos de estado em um fragmento durante uma alterao de configurao em tempo de execuo:</p> 83 84 <ol> 85 <li>Estenda a classe {@link android.app.Fragment} e declare referncias aos objetos 86 de estado.</li> 87 <li>Chame {@link android.app.Fragment#setRetainInstance(boolean)} quando o fragmento for criado. 88 </li> 89 <li>Acrescente o fragmento atividade.</li> 90 <li>Use {@link android.app.FragmentManager} para recuperar o fragmento quando a atividade for 91 reiniciada.</li> 92 </ol> 93 94 <p>Por exemplo: defina o fragmento da seguinte forma:</p> 95 96 <pre> 97 public class RetainedFragment extends Fragment { 98 99 // data object we want to retain 100 private MyDataObject data; 101 102 // this method is only called once for this fragment 103 @Override 104 public void onCreate(Bundle savedInstanceState) { 105 super.onCreate(savedInstanceState); 106 // retain this fragment 107 setRetainInstance(true); 108 } 109 110 public void setData(MyDataObject data) { 111 this.data = data; 112 } 113 114 public MyDataObject getData() { 115 return data; 116 } 117 } 118 </pre> 119 120 <p class="caution"><strong>Ateno:</strong> ao restaurar qualquer objeto, 121 no se deve nunca passar um objeto vinculado a {@link android.app.Activity}, como um {@link 122 android.graphics.drawable.Drawable}, um {@link android.widget.Adapter}, um {@link android.view.View} 123 ou qualquer outro objeto associado a um {@link android.content.Context}. Se o fizer, 124 ele vazar todas as vistas e recursos da instncia da atividade original (vazar recursos 125 significa que o aplicativo mantm a reteno deles, que no podem ser recolhidos, o que 126 causa perda de memria).</p> 127 128 <p>Em seguida, use {@link android.app.FragmentManager} para adicionar o fragmento atividade. 129 possvel obter o objeto de dados do fragmento quando a atividade reiniciar durante as alteraes 130 de configurao em tempo de execuo. Por exemplo: defina a atividade da seguinte forma:</p> 131 132 <pre> 133 public class MyActivity extends Activity { 134 135 private RetainedFragment dataFragment; 136 137 @Override 138 public void onCreate(Bundle savedInstanceState) { 139 super.onCreate(savedInstanceState); 140 setContentView(R.layout.main); 141 142 // find the retained fragment on activity restarts 143 FragmentManager fm = getFragmentManager(); 144 dataFragment = (DataFragment) fm.findFragmentByTag(data); 145 146 // create the fragment and data the first time 147 if (dataFragment == null) { 148 // add the fragment 149 dataFragment = new DataFragment(); 150 fm.beginTransaction().add(dataFragment, data).commit(); 151 // load the data from the web 152 dataFragment.setData(loadMyData()); 153 } 154 155 // the data is available in dataFragment.getData() 156 ... 157 } 158 159 @Override 160 public void onDestroy() { 161 super.onDestroy(); 162 // store the data in the fragment 163 dataFragment.setData(collectMyLoadedData()); 164 } 165 } 166 </pre> 167 168 <p>Nesse exemplo, {@link android.app.Activity#onCreate(Bundle) onCreate()} adiciona um fragmento 169 ou restaura uma referncia a ele. {@link android.app.Activity#onCreate(Bundle) onCreate()} tambm 170 armazena o objeto de estado dentro da instncia de fragmento. 171 {@link android.app.Activity#onDestroy() onDestroy()} atualiza o objeto de estado dentro 172 da instncia de fragmento retida.</p> 173 174 175 176 177 178 <h2 id="HandlingTheChange">Tratar voc mesmo da alterao de configurao</h2> 179 180 <p>Se o aplicativo no tiver que atualizar recursos durante uma alterao de configurao especfica 181 <em>e</em> se houver alguma limitao de desempenho que 182 impea a atividade de reiniciar, pode-se declarar que a atividade trata ela mesma da alterao de configurao, 183 o que evita que o sistema reinicie a atividade.</p> 184 185 <p class="note"><strong>Observao:</strong> Tratar voc mesmo da alterao de configurao 186 pode dificultar muito o uso de recursos alternativos, pois o sistema no os aplicar 187 automaticamente. Esta tcnica deve ser considerada um ltimo recurso, quando preciso evitar reincios 188 devido a uma alterao de configurao e no recomendada para a maioria dos aplicativos.</p> 189 190 <p>Para declarar que a atividade manipula uma alterao de configurao, edite o elemento <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a> 191 apropriado no arquivo de manifesto para que inclua o atributo <a href="{@docRoot}guide/topics/manifest/activity-element.html#config">{@code 192 android:configChanges}</a> com um valor que represente a configurao 193 a tratar. Os valores possveis esto listados na documentao do atributo <a href="{@docRoot}guide/topics/manifest/activity-element.html#config">{@code 194 android:configChanges}</a> (os valores mais comumente usados so {@code "orientation"}, para 195 impedir reincios durante alteraes na orientao da tela, e {@code "keyboardHidden"} para impedir 196 reincios quando a disponibilidade do teclado muda). Para declarar vrios valores de configurao 197 no atributo, usa-se um separador na forma de caractere barra reta {@code |}.</p> 198 199 <p>Por exemplo: o cdigo de manifesto a seguir declara uma atividade que trata tanto 200 da alterao de orientao da tela quanto da disponibilidade do teclado:</p> 201 202 <pre> 203 <activity android:name=".MyActivity" 204 android:configChanges="orientation|keyboardHidden" 205 android:label="@string/app_name"> 206 </pre> 207 208 <p>Agora, quando uma dessas configuraes mudar, {@code MyActivity} no reiniciar. 209 Em vez disso, a {@code MyActivity} recebe uma chamada para {@link 210 android.app.Activity#onConfigurationChanged(Configuration) onConfigurationChanged()}. Um objeto 211 {@link android.content.res.Configuration} passado a esse mtodo e especifica 212 a nova configurao do dispositivo. Ao ler os campos em {@link android.content.res.Configuration}, 213 pode-se determinar a nova configurao e atualizar os recursos na interface para fazer 214 as alteraes adequadas. No momento 215 em que o mtodo chamado, o objeto {@link android.content.res.Resources} da atividade atualizado 216 para retornar recursos com base na nova configurao, o que facilita 217 a redefinio de elementos da IU sem que o sistema reinicie a atividade.</p> 218 219 <p class="caution"><strong>Ateno:</strong> a partir do Android 3.2 (nvel da API 13), <strong>o "tamanho 220 da tela" tambm muda</strong> quando o dispositivo alterna entre as orientaes retrato 221 e paisagem. Assim, se voc deseja evitar que o tempo de execuo reinicie devido a uma mudana da orientao 222 ao desenvolver uma API nvel 13 ou posterior (conforme declarado pelos atributos <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code minSdkVersion}</a> e <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code targetSdkVersion}</a>), 223 preciso incluir o valor {@code "screenSize"} alm do valor {@code 224 "orientation"}. Ou seja, preciso declarar {@code 225 android:configChanges="orientation|screenSize"}. No entanto, se o aplicativo tem como alvo uma API nvel 226 12 ou inferior, a atividade sempre trata ela mesma a alterao de configurao (essa mudana 227 de configurao no reinicia a atividade, mesmo em execuo em Android 3.2 ou dispositivo posterior).</p> 228 229 <p>Por exemplo: a implementao a seguir {@link 230 android.app.Activity#onConfigurationChanged(Configuration) onConfigurationChanged()} verifica 231 a orientao de dispositivo atual:</p> 232 233 <pre> 234 @Override 235 public void onConfigurationChanged(Configuration newConfig) { 236 super.onConfigurationChanged(newConfig); 237 238 // Checks the orientation of the screen 239 if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) { 240 Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show(); 241 } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){ 242 Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show(); 243 } 244 } 245 </pre> 246 247 <p>O objeto {@link android.content.res.Configuration} representa todas as configuraes 248 atuais, no somente as que foram alteradas. Na maior parte do tempo, no importa como 249 a configurao foi alterada; basta reatribuir todos os recursos que apresentam alternativas 250 configurao que esto sendo tratadas. Por exemplo: como o objeto {@link 251 android.content.res.Resources} est atualizado, pode-se redefinir 252 qualquer {@link android.widget.ImageView} com {@link android.widget.ImageView#setImageResource(int) 253 setImageResource()} 254 e ser usado o recurso adequado nova configurao (conforme descrito em <a href="providing-resources.html#AlternateResources">Como fornecer recursos</a>).</p> 255 256 <p>Observe que os valores dos campos de {@link 257 android.content.res.Configuration} so inteiros que correspondem a constantes especficas 258 da classe {@link android.content.res.Configuration}. Para ver a documentao sobre as constantes 259 a usar em cada campo, consulte o campo em questo na referncia sobre {@link 260 android.content.res.Configuration}.</p> 261 262 <p class="note"><strong>Lembre-se:</strong> ao declarar a atividade para tratar uma alterao 263 de configurao, voc responsvel por redefinir todos os elementos que fornecem alternativas. Se voc 264 declarar a atividade para tratar a alterao de orientao e tiver imagens que alterariam 265 entre paisagem e retrato, preciso reatribuir cada recurso a cada elemento durante {@link 266 android.app.Activity#onConfigurationChanged(Configuration) onConfigurationChanged()}.</p> 267 268 <p>Se no for necessrio atualizar o aplicativo com base nessas alteraes 269 de configurao, pode-se <em>no</em> implementar {@link 270 android.app.Activity#onConfigurationChanged(Configuration) onConfigurationChanged()}. Nesse 271 caso, todos os recursos usados antes da alterao de configurao ainda so usados 272 e somente o reincio da atividade evitado. No entanto, o aplicativo deve sempre ser capaz 273 de se encerrar e reiniciar com seu estado anterior intacto, portanto essa tcnica no deve 274 ser considerada uma fuga da reteno do estado durante o ciclo de vida normal da atividade, No somente porque 275 h outras alteraes de configurao impossveis de evitar que reiniciem o aplicativo, 276 mas tambm porque devem-se tratar eventos como o do usurio que sai do aplicativo e ele destrudo 277 antes de o usurio voltar a ele.</p> 278 279 <p>Para obter mais informaes sobre as alteraes de configurao que devem ser tratadas na atividade, consulte a documentao sobre <a href="{@docRoot}guide/topics/manifest/activity-element.html#config">{@code 280 android:configChanges}</a> e a classe 281 {@link android.content.res.Configuration}.</p> 282