web-dev-qa-db-ja.com

asynctaskからUIを更新する方法

これを行う方法の多くの例を見てきましたが、自分のコードにそれを実装する方法がわかりません。

私はこれを使用します code
URLを更新したため、動的データを含むjsonを受け取ります。私がやろうとしていることは、このコードで30秒ごとにリストを自動的に更新することです。

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

更新し、URLを呼び出してデータを取得しますが、UIは更新されません。

正しい方向に私を助けるヒントをありがとう。

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

13
Bjorn

AsyncTaskには、UIと対話できる3つの保護されたメソッドがあります。

  • onPreExecute()
    • 実行beforedoInBackground()
  • onPostExecute()
    • 実行afterdoInBackground() completes
  • onProgressUpdate()
    • これは、doInBackground()publishProgress()で呼び出したときにのみ実行されます

あなたの場合、タスクがリフレッシュしたい30秒よりもずっと長く実行されるなら、onProgressUpdate()publishProgress()を利用したいでしょう。それ以外の場合は、onPostExecute()がトリックを行う必要があります。

実装方法については 公式ドキュメント をご覧ください。

19
indivisible

AsycTask内で終了したタスクでonPostExecuteを使用し、list uiを更新できます。

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

    };
}

更新runOnUiThread内でonPostExecuteを使用する必要はありません。既に呼び出されており、UIThreadの下で本体が実行されるためです。

7
Khaled Lela

最初に、postdelayed()を使用すると、コードが繰り返し実行されません。コードを繰り返しパターンで実行する場合は、このコードを使用します。これは5秒ごとに実行されます

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

以下のコードは、毎回postExecute()でSimpleAdapterの新しいインスタンスを作成しているため、同じデータが繰り返し表示されます。アダプターを更新する場合は、SimpleAdapterインスタンスをクラスメンバーとして作成し、postExecute()をこれで置き換えます

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


        }

これでアダプターが更新されますが、同じ連絡先が追加されます

1
umerk44