Использование ProgressDialog с Thread на Android создает исключение ViewRoot $ CalledWrongFromThreadException - PullRequest
0 голосов
/ 16 декабря 2010

Я пытаюсь показать диалог прогресса при заполнении макета:

РЕДАКТИРОВАТЬ (вот код):

public class CalendarMonth extends Activity {

    private ProgressDialog mDialog;

        private int mMonth = 0;
    private int mYear = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.calendar_m);

        filterData();
    }

    private void filterData() {

        mDialog = ProgressDialog.show(this, "Loading calendar", 
                "Please wait...", true, true);
        mDialog.setCancelable(false);
        mDialog.show();

        new GenerateMonth().execute();
    }

class GenerateMonth extends AsyncTask {
        protected Object doInBackground(Object... arg0) {
            generateMonth();
            return true;
        }
        protected void onPostExecute(Object result) {
            mDialog.dismiss();
        }

    private void generateMonth() {

        mCalendar = new CalendarInstance(mMonth, mYear);

        mMonth = this.mCalendar.getSelectedMonth();
        mYear = this.mCalendar.getSelectedYear();

        TextView monthName = (TextView) findViewById(R.id.monthName);
        monthName.setText(mCalendar.getMonthAndYearAsString());

        Button monthPrevious = (Button) findViewById(R.id.monthPrevious);
        monthPrevious.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                int month = mMonth - 1;
                int year = mYear;
                if (mMonth == 1) {
                    month = 12;
                    year = mYear - 1;
                }
                mMonth = month;
                mYear = year;
                filterData();
            }
        });

        Button monthNext = (Button) findViewById(R.id.monthNext);
        monthNext.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                int month = mMonth + 1;
                int year = mYear;
                if (mMonth == 12) {
                    month = 1;
                    year = mYear + 1;
                }
                mMonth = month;
                mYear = year;
                filterData();
            }
        });

        GridView gridview = (GridView) findViewById(R.id.gridview);
        gridview.setNumColumns(7);
        gridview.setStretchMode(GridView.STRETCH_COLUMN_WIDTH);
        gridview.setBackgroundColor(Color.BLACK);
        gridview.setAdapter(new CalendarMonthAdapter(this, mMonth, mYear));     
    }

    @Override
    protected void onResume() {

        super.onResume();
        filterData();
    }
    }

Ответы [ 3 ]

1 голос
/ 16 декабря 2010

может быть проще использовать AsyncTask http://developer.android.com/reference/android/os/AsyncTask.html

, чтобы у вас было что-то вроде этого

public class Temp extends Activity {
    private Context mContext;
    private ProgressDialog mDialog

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.temp);


        mDialog = ProgressDialog.show(this, "Filter", "blah", true, true);
        mDialog.show();
        new FillDataTask.execute();

    }


    class FillDataTask extends AsyncTask {
        @Override
        protected Object doInBackground(Object... params) {

             try {
                    filterData();
                } catch (ParseException e) {
                    Log.e("FILTER", e.toString());
                    e.printStackTrace();
                }
            return true;  // you can return whatever you want here
        }

        protected void onPostExecute(Object result) {
            //update progressDialog here
            mDialog.dismiss();
        }
    }

}

РЕДАКТИРОВАТЬ НИЖЕ

сделайте это так

public class CalendarMonth extends Activity {

    private ProgressDialog mDialog;

        private int mMonth = 0;
    private int mYear = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.calendar_m);

        filterData();
    }

    private void filterData() {

        mDialog = ProgressDialog.show(this, "Loading calendar", 
                "Please wait...", true, true);
        mDialog.setCancelable(false);
        mDialog.show();

        new GenerateMonth().execute();
    }

    private void genMonth()
    {

        mCalendar = new CalendarInstance(mMonth, mYear);

        mMonth = this.mCalendar.getSelectedMonth();
        mYear = this.mCalendar.getSelectedYear();

    }

    private void layoutUI()
    {
          TextView monthName = (TextView) findViewById(R.id.monthName);
        monthName.setText(mCalendar.getMonthAndYearAsString());

        Button monthPrevious = (Button) findViewById(R.id.monthPrevious);
        monthPrevious.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                int month = mMonth - 1;
                int year = mYear;
                if (mMonth == 1) {
                    month = 12;
                    year = mYear - 1;
                }
                mMonth = month;
                mYear = year;
                filterData();
            }
        });

        Button monthNext = (Button) findViewById(R.id.monthNext);
        monthNext.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                int month = mMonth + 1;
                int year = mYear;
                if (mMonth == 12) {
                    month = 1;
                    year = mYear + 1;
                }
                mMonth = month;
                mYear = year;
                filterData();
            }
        });

        GridView gridview = (GridView) findViewById(R.id.gridview);
        gridview.setNumColumns(7);
        gridview.setStretchMode(GridView.STRETCH_COLUMN_WIDTH);
        gridview.setBackgroundColor(Color.BLACK);
        gridview.setAdapter(new CalendarMonthAdapter(this, mMonth, mYear)); 
    }
}
}

class GenerateMonth extends AsyncTask {
        protected Object doInBackground(Object... arg0) {
            genMonth();
            return true;
        }
        protected void onPostExecute(Object result) {
            layoutUI();
            mDialog.dismiss();

        }

    }
0 голосов
/ 17 декабря 2010

Похоже, ваша проблема в функции generateMonth, которая вызывается из функции doInBackground.Вы не должны получать доступ к пользовательскому интерфейсу из функции doInBackground или из любой функции, вызываемой из doInBackground.Эта функция предназначена для выполнения задач, которые требуют много времени, таких как вычисления или сложные запросы к БД, но НЕ ДОЛЖНЫ обращаться к пользовательскому интерфейсу.Ваши обновления пользовательского интерфейса должны быть сделаны в функции onPostExecute.Таким образом, такие вещи, как:

gridview.setNumColumns (7)

не разрешены в doInBackground (или generateMonth, который вызывается оттуда).

0 голосов
/ 16 декабря 2010

Ошибка должна быть в filterData, если вы обновляете пользовательский интерфейс из данных фильтра, он выдаст это исключение. Я бы рекомендовал использовать асинхронную задачу, использовать doInBackground для построения данных и onPostExecute для обновления пользовательского интерфейса.

...