web-dev-qa-db-fra.com

Comment mettre à jour l'interface utilisateur à partir d'un asyncte

J'ai vu de nombreux exemples sur la façon de procéder, mais je ne vois pas comment l'implémenter dans mon code.

Je utilise ce code .
J'ai mis à jour l'URL, donc il recevra un json avec des données dynamiques . Ce que j'essaie de faire est de mettre à jour automatiquement la liste toutes les 30 secondes avec ce code.

Handler handler = new Handler();
    Runnable refresh = new Runnable() {
        public void run() {
            new GetContacts().execute();
            handler.postDelayed(refresh, 30000); 
        }
    };

Il a actualisé et appelle l'URL et obtient les données, mais l'interface utilisateur n'est pas mise à jour.

Merci pour toutes les astuces qui m'aident dans la bonne direction.

http://www.androidhive.info/2012/01/Android-json-parsing-tutorial/

12
Bjorn

Vous avez trois méthodes protégées dans une AsyncTask pouvant interagir avec l'interface utilisateur.

  • onPreExecute()
    • exécute beforedoInBackground()
  • onPostExecute()
    • exécute après quedoInBackground() soit terminé
  • onProgressUpdate()
    • cela ne fonctionne que lorsque doInBackground() l'appelle avec publishProgress()

Si dans votre cas, la tâche doit durer beaucoup plus longtemps que les 30 secondes que vous souhaitez actualiser, vous voudrez utiliser onProgressUpdate() et publishProgress(). Sinon, onPostExecute() devrait faire l'affaire.

Voir le documentation officielle pour savoir comment l'implémenter.

18
indivisible

Vous pouvez utiliser AsycTask et mettre à jour list ui lorsque la tâche est terminée dans onPostExecute.

    new AsyncTask<String, String, String>() {
        /**
         * Before starting background do some work.
         * */
        @Override
        protected void onPreExecute() {
        }

        @Override
        protected String doInBackground(String... params) {
            // TODO fetch url data do bg process.
            return null;
        }

        /**
         * Update list ui after process finished.
         */
        protected void onPostExecute(String result) {
               // NO NEED to use activity.runOnUiThread(), code execute here under UI thread. 

                 // Updating parsed JSON data into ListView
                 final List data = new Gson().fromJson(result);
                // updating listview
                ((ListActivity) activity).updateUI(data);
        }

    };
}

Mise à jour Inutile d’utiliser runOnUiThread dans onPostExecute, car il est déjà appelé et son corps est exécuté sous UIThread.

7
Khaled Lela

La première chose à utiliser postdelayed () n'exécutera pas votre code de manière répétitive. Si vous souhaitez exécuter du code dans un motif répétitif, utilisez ce code. Cela fonctionnera toutes les 5 secondes

  ScheduledExecutorService scheduleTaskExecutor = Executors.newScheduledThreadPool(5);

    /*This schedules a runnable task every second*/
    scheduleTaskExecutor.scheduleAtFixedRate(new Runnable() {
      public void run() 
      {
        runOnUiThread(new Runnable(){

            @Override
            public void run() {
                // TODO Auto-generated method stub
                new GetContacts().execute();
            }

        });
      }
    }, 0, 5, TimeUnit.SECONDS);

Le code que vous suivez crée chaque fois une nouvelle instance de SimpleAdapter dans postExecute () afin que vous puissiez voir les mêmes données encore et encore. Donc, si vous souhaitez mettre à jour votre adaptateur, créez l’instance SimpleAdapter en tant que membre de la classe et remplacez postExecute () par

@Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);
            // Dismiss the progress dialog
            if (pDialog.isShowing())
                pDialog.dismiss();
            /**
             * Updating parsed JSON data into ListView
             * */
            if(adapter == null)
            {
                adapter = new SimpleAdapter(
                    MainActivity.this, contactList,
                    R.layout.list_item, new String[] { TAG_NAME, TAG_EMAIL,
                            TAG_PHONE_MOBILE }, new int[] { R.id.name,
                            R.id.email, R.id.mobile });

                            setListAdapter(adapter);
            }
            else
            {
                adapter.notifyDataSetChanged();
            }


        }

Maintenant, cela mettra à jour l'adaptateur mais ajoutera le même contact 

1
umerk44