16

I've seen many examples of how to do this, but I can't figure how to implement it in my code.

I am using this code.
I have updated the url, so it will receive a json with dynamic data. What I'm trying to do is to automatically update the list every 30 secs with this code.

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

It refreshes, and calls the url and gets the data, but the UI does not get updated.

Thanks for any hints to point me in the right direction.

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

Derryl Thomas
  • 793
  • 7
  • 15
Bjorn
  • 663
  • 2
  • 11
  • 29
  • the postExecute() of GetContacts is updating the UI, if so it's already run on UI thread and should work. try to supply more code – Nativ Jun 01 '14 at 09:34
  • I meant to ask, the first sentence is a question.. ',' -> '?' – Nativ Jun 01 '14 at 09:44
  • It sounds like you are trying to update a ListView. If this is correct, you should be updating your data structure and passing it to your adapter with a method like this: `public synchronized void refreshAdapter(List itemList) { this.itemList = itemList; notifyDataSetChanged(); }` – Jeremy W Jun 01 '14 at 09:50
  • R you updating url after every 30 sec or hitting the same url everytime? – umerk44 Jun 01 '14 at 09:51

3 Answers3

21

You have three protected methods in an AsyncTask that can interact with the UI.

  • onPreExecute()
    • runs before doInBackground()
  • onPostExecute()
    • runs after doInBackground() completes
  • onProgressUpdate()
    • this only runs when doInBackground() calls it with publishProgress()

If in your case the Task runs for a lot longer than the 30 seconds you want to refresh you would want to make use of onProgressUpdate() and publishProgress(). Otherwise onPostExecute() should do the trick.

See the official documentation for how to implement it.

indivisible
  • 4,557
  • 3
  • 26
  • 48
8

You can use AsycTask and update list ui on task finished within 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);
        }

    };
}

Update No need to use runOnUiThread inside onPostExecute, Because it's already called on and it's body executed under UIThread.

Khaled Lela
  • 5,495
  • 5
  • 39
  • 63
1

The first thing is using postdelayed() will not run your code in repetition If you want to run code in repetitive pattern use this code. This will run after every 5 sec

  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);

The code you are following is creating new instance of SimpleAdapter in postExecute() each time so you will see the same data again and again. So if you want to update your adapter create SimpleAdapter instance as class member and replace the postExecute() by this

@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();
            }


        }

Now this will update adapter but will add same contact

umerk44
  • 2,691
  • 4
  • 20
  • 42