Aure77 Posté(e) 23 décembre 2010 Share Posté(e) 23 décembre 2010 Bonjour, J'ai un gros soucis avec la gestion de l'orientation et l'affichage d'une ProgressDialog pendant un long traitement. En effet si je pivote l'orientation pendant que la progress dialog est active, ça me faut planter mon programme... Voici mon implementation: // android:configChanges="keyboardHidden|orientation" dans le manifest public class ProgTv extends Activity { private LoadProgTvData progData; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); //loadProgTvData(); } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); setContentView(R.layout.main); } @Override public Object onRetainNonConfigurationInstance() { progData.setActivity(null); return progData; } @Override protected void onResume() { super.onResume(); loadProgTvData(); } private void loadProgTvData() { final Object retained = getLastNonConfigurationInstance(); if(retained instanceof LoadProgTvData) { progData = (LoadProgTvData) retained; progData.setActivity(this); } else { progData = new LoadProgTvData(this, null); } } } LoadProgTvData : public class LoadProgTvData { private Activity activity; private static List<ProgTvObj> lst_prog = new ArrayList<ProgTvObj>(); private static ProgTvAdapter progTvAdapter = null; private Hours progHours; public static enum Hours { BEGINING_EVENING, END_EVENING }; public LoadProgTvData(Activity activity, Hours h) { this.activity = activity; this.progHours = h; if(lst_prog.isEmpty()) new ListRefresher().execute(); else refreshListView(); } public void setActivity(Activity activity) { this.activity = activity; if(!lst_prog.isEmpty()) refreshListView(); } /** * Set List of ProgTvObj from an XML stream */ private void setListFromXml() { // SAX Parser try { ProgSaxXml px = new ProgSaxXml(activity.getAssets().open("soir.xml")); // SAX Parser lst_prog = px.getProgList(); } catch (MalformedURLException e) { Log.d("MalformedURLException", "XML Url is malformed", e); throw new RuntimeException(e); } catch (IOException e) { Log.d("IOException", e.toString()); } } /** * Set Adapter of ListView to fill it with ProgTvObj */ public void refreshListView() { //Hours progHours = (Hours) getIntent().getSerializableExtra("tabHours"); // Get Hours value or null if not defined if(null != activity) { if(null == progTvAdapter) progTvAdapter = new ProgTvAdapter(activity); if(null != progHours) progTvAdapter.setListProg(myUtils.filter(lst_prog, progHours)); else progTvAdapter.setListProg(lst_prog); ListView lstview_prog = (ListView)activity.findViewById(R.id.lstview_prog); lstview_prog.setAdapter(progTvAdapter); lstview_prog.setOnItemClickListener(progTvAdapter); } } class ListRefresher extends AsyncTask<Uri, Void, Void> { private ProgressDialog progressDialog; @Override protected void onPreExecute() { if(!lst_prog.isEmpty()) { this.cancel(true); refreshListView(); } else progressDialog = ProgressDialog.show(activity, null, "Chargement en cours..."); } @Override protected Void doInBackground(Uri... params) { setListFromXml(); return null; } @Override protected void onPostExecute(Void result) { progressDialog.dismiss(); refreshListView(); } } } Sachant que si je met loadProgTvData(); dans le OnResume c'est parce que mon Activity est un onglet de mon tableau et le faut de changer d'onglet ne rapelle pas OnCreate. Or j'ai besoin que ma liste soit rafraichit à chaque passage. Je pense que le problème viens du fait que la ProgressDialog est crée dans un context et le changement d'orientation change le context et donc au moment du dismiss il doit pas savoir quoi faire. Si vous pouviez m'aider ça serai vraiment sympa. Car le problème sur le lequel je bloque est quand même une chose que tout le monde doit réaliser dans une appli mobile (telechargement avec message d'attente...). Lien vers le commentaire Partager sur d’autres sites More sharing options...
Pierre87 Posté(e) 27 décembre 2010 Share Posté(e) 27 décembre 2010 facile: http://developer.android.com/reference/android/R.attr.html#configChanges il te suffit de mettre "rotation" dans configChange ça empêche l'Activity d'être détruite lors d'un rotation Lien vers le commentaire Partager sur d’autres sites More sharing options...
Aure77 Posté(e) 28 décembre 2010 Auteur Share Posté(e) 28 décembre 2010 Je crois que tu n'as pas lu la première ligne en commentaire dans mon code, j'ai mis dans le manifest : android:configChanges="keyboardHidden|orientation" (et pas rotation) Mais malheuresement ce n'est pas le problème... le problème est que "progressDialog.dismiss();" leve une exception (NullPointer...) quand il est appellé (notamment après une rotation). Je pense que c'est du au fait que le context ne soit plus le même qui lui pose problème. Lien vers le commentaire Partager sur d’autres sites More sharing options...
Pierre87 Posté(e) 30 décembre 2010 Share Posté(e) 30 décembre 2010 ha oui désolé :P Alors déjà un truc, il me semble qu'on ne peut pas faire appel plusieurs fois à setContentView() dans la vie d'une Activity (mais je ne suis pas sûr) Le mieux, ça serait quand même que tu nous dises quelle ligne pose problème... (trace....) Lien vers le commentaire Partager sur d’autres sites More sharing options...
Nivek Posté(e) 30 décembre 2010 Share Posté(e) 30 décembre 2010 La bonne méthode pour gérer les changements d'orientation avec les ProgressDialog est expliquée ici: http://stackoverflow.com/questions/3821423/background-task-progress-dialog-orientation-change-is-there-any-100-working/3821998#3821998 Lien vers le commentaire Partager sur d’autres sites More sharing options...
Aure77 Posté(e) 31 décembre 2010 Auteur Share Posté(e) 31 décembre 2010 J'ai fait l'implementation comme via le lien de Nivek (j'ai gardé ma ProgressDialog au lieu de ProgressBar) Mais j'ai toujours le même problème.... voici la trace : ERROR/AndroidRuntime(648): java.lang.IllegalArgumentException: no dialog with id 0 was ever shown via Activity#showDialog Cette erreur intervient bien sur après une rotation de l'écran... La classe static, inner classe de LoadProgTvData (qui extends de Activity maintenant) : static class ListRefresher extends AsyncTask<Void, Void, Void> { private boolean loadXML = true; private LoadProgTvData activity = null; public ListRefresher(LoadProgTvData prgActivity) { attach(prgActivity); } @Override protected void onPreExecute() { if(!lst_prog.isEmpty()) loadXML = false; else activity.showDialog(0); } @Override protected Void doInBackground(Void... params) { if(loadXML) activity.setListFromXml(); return null; } @Override protected void onPostExecute(Void result) { if(null != activity) { if(loadXML) activity.dismissDialog(0); // Il plante à cette ligne avec la trace ci-dessus activity.refreshListView(); } } public void detach() { activity=null; } public void attach(LoadProgTvData activity) { this.activity=activity; } } dans ProgTvActivity extends Activity j'ai rajouté : private ProgressDialog loadingDialog = null; @Override protected Dialog onCreateDialog(int id) { if(id == 0){ loadingDialog = new ProgressDialog(this); loadingDialog.setMessage("Chargement en cours..."); loadingDialog.setIndeterminate(true); loadingDialog.setCancelable(true); return loadingDialog; } return super.onCreateDialog(id); } Lien vers le commentaire Partager sur d’autres sites More sharing options...
chpil Posté(e) 3 janvier 2011 Share Posté(e) 3 janvier 2011 Ce qui te manque, c'est qu'il te faut recréer ta boite de dialogue dans ton onResume si tu détectes que tu es dans le cas d'une rotation d'écran (getLastNonConfigurationInstance() qui retourne non-null). Car si Android recrée une Activity en cas de rotation, ce ne doit pas être le cas d'une boite de dialogue... Lien vers le commentaire Partager sur d’autres sites More sharing options...
chpil Posté(e) 4 janvier 2011 Share Posté(e) 4 janvier 2011 Y'a un truc qui me chiffonne, c'est que si tu as mis un android:configChanges dans ton manifest.xml, alors tu ne devrais pas avoir ce problème, et Android ne devrait pas détruire ton Activity et la Dialog qui va avec lors d'un changement d'orientation Par contre, sur quelle activity as-tu mis cet attribut android:configChanges ? si je comprends bien à la relecture de ton premier post, tu as une TabActivity qui contient des onglets, dont ton Activity détaillée ici... Il faut que le android:configChanges soit sur la TabActivity, s'il est sur l'autre cela ne sert à rien, car sinon c'est la TabActivity qui est détruire/recréée, et par conséquence ses Activity filles aussi, lors d'un changement de configuration. Si c'est le cas, fais le changement et tu pourras te passer des onConfigurationChanged/onRetainNonConfigurationIntance/... Lien vers le commentaire Partager sur d’autres sites More sharing options...
Recommended Posts
Archivé
Ce sujet est désormais archivé et ne peut plus recevoir de nouvelles réponses.