Как я могу показать диалог между двумя действиями? - PullRequest
11 голосов
/ 09 декабря 2010

У меня проблема. Мне нужно перейти от одного занятия к другому. У моего второго занятия большой макет xml, с большим количеством элементов (я говорю о четырехстах приблизительно), затем для показа этого второго занятия требуется несколько секунд (слишком много).

Как отобразить диалоговое окно хода выполнения между двумя действиями?

Я пытаюсь использовать фоновое задание для этого.

У меня есть этот метод в моей Деятельности A:

  private void goToYear() {
   Intent intent = new Intent();
   intent.setClass (getBaseContext(), YearActivity.class);
   startActivity( intent);
  }

А в моей Деятельности B:

public class YearActivity extends Activity {

 private String  TAG = "YearActivity ::";

 private ProgressDialog pd = null;


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

        // Show the ProgressDialog on this thread
        this.pd = ProgressDialog.show(this, "Working...", "Calculating the screen...", true, false);

        // Start a new thread that will download all the data
        new MakeYearTask().execute();

    }

    private void initCalendar () {
      this.setContentView( R.layout.calendar_year);   

   ...
   ...
   initialize values
   ...
   ...

    }


    private class MakeYearTask extends AsyncTask<String, Void, Object> {
        protected Void doInBackground(String... args) {
            Log.i("YearActivity::MakeYearTask", "MakeYearTask Background thread starting");

   YearActivity.this.initCalendar();


        }

        protected void onPostExecute(Object result) {

            if (YearActivity.this.pd != null) {
             YearActivity.this.pd.dismiss();
            }
        }
   } 
}

Вы можете видеть, что я делаю setContentView из onCreate метода.

Это не работает. Это дает мне одно исключение, например:

12-09 19:49:17.729: ERROR/AndroidRuntime(218): java.lang.RuntimeException: An error occured while executing doInBackground()
12-09 19:49:17.729: ERROR/AndroidRuntime(218):     at android.os.AsyncTask$3.done(AsyncTask.java:200)
12-09 19:49:17.729: ERROR/AndroidRuntime(218):     at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:234)
12-09 19:49:17.729: ERROR/AndroidRuntime(218):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:258)
12-09 19:49:17.729: ERROR/AndroidRuntime(218):     at java.util.concurrent.FutureTask.run(FutureTask.java:122)
12-09 19:49:17.729: ERROR/AndroidRuntime(218):     at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:648)
12-09 19:49:17.729: ERROR/AndroidRuntime(218):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:673)
12-09 19:49:17.729: ERROR/AndroidRuntime(218):     at java.lang.Thread.run(Thread.java:1060)
12-09 19:49:17.729: ERROR/AndroidRuntime(218): Caused by: android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
12-09 19:49:17.729: ERROR/AndroidRuntime(218):     at android.view.ViewRoot.checkThread(ViewRoot.java:2629)
12-09 19:49:17.729: ERROR/AndroidRuntime(218):     at android.view.ViewRoot.requestLayout(ViewRoot.java:545)
12-09 19:49:17.729: ERROR/AndroidRuntime(218):     at android.view.View.requestLayout(View.java:7657)
12-09 19:49:17.729: ERROR/AndroidRuntime(218):     at android.view.ViewGroup.addView(ViewGroup.java:1749)
12-09 19:49:17.729: ERROR/AndroidRuntime(218):     at android.view.ViewGroup.addView(ViewGroup.java:1731)
12-09 19:49:17.729: ERROR/AndroidRuntime(218):     at com.android.internal.policy.impl.PhoneWindow.generateLayout(PhoneWindow.java:2186)
12-09 19:49:17.729: ERROR/AndroidRuntime(218):     at com.android.internal.policy.impl.PhoneWindow.installDecor(PhoneWindow.java:2239)
12-09 19:49:17.729: ERROR/AndroidRuntime(218):     at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:309)
12-09 19:49:17.729: ERROR/AndroidRuntime(218):     at android.app.Activity.setContentView(Activity.java:1620)
12-09 19:49:17.729: ERROR/AndroidRuntime(218):     at es.jota.app.YearActivity.initCalendar(YearActivity.java:42)
12-09 19:49:17.729: ERROR/AndroidRuntime(218):     at es.jota.app.YearActivity.access$0(YearActivity.java:41)
12-09 19:49:17.729: ERROR/AndroidRuntime(218):     at es.jota.app.YearActivity.initCalendar$MakeYearTask.doInBackground(YearActivity.java:120)
12-09 19:49:17.729: ERROR/AndroidRuntime(218):     at es.jota.app.YearActivity.initCalendar$MakeYearTask.doInBackground(YearActivity.java:1)
12-09 19:49:17.729: ERROR/AndroidRuntime(218):     at android.os.AsyncTask$2.call(AsyncTask.java:185)
12-09 19:49:17.729: ERROR/AndroidRuntime(218):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:256)
12-09 19:49:17.729: ERROR/AndroidRuntime(218):     ... 4 more

Ответы [ 4 ]

1 голос
/ 02 апреля 2013

Это плохой дизайн для начала.Если у вас есть такой большой объем данных для представления пользователю, который, вероятно, будет прокручиваться, вы должны вместо этого использовать подкласс AdapterView, такой как ListView или GridView.XML-макет с почти 400 элементами невероятно велик.

Я понимаю, что вы пытаетесь сделать (вы пытаетесь выполнить длительное построение массивной иерархии View на отдельной Thread, используя AsyncTask, но вы нашлиэто то, что вас взорвали за попытку прикоснуться к иерархии View в не-пользовательском интерфейсе Thread).

Даже если вам удалось реализовать какой-то индикатор выполнения на переднем плане во время построения иерархии, я не уверен, что система предоставит средства для вызова информации о ходе выполнения, пока она надувает View иерархия (но я могу ошибаться).

AdapterView были созданы, чтобы решить именно эту проблему.При AdapterView обычно в памяти в любое время существует только значение экрана Views.Например, у вас может быть таблица с тысячей строк, но только на экран помещаются только семь строк, только восемь строк View могут одновременно существовать в памяти.Кроме того, адаптер также должен перерабатывать View с, дополнительно оптимизируя производительность.

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

Попытались ли вы вместо этого использовать new MakeYearTask().execute(); в onResume ()?

Хотя это и не элегантно, вы можете запустить сообщение с задержкой в ​​потоке при создании, чтобы подождать пару миллис.

Редактировать:

Я только эту ошибку:

(Caused by: android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views)

вы изменяете пользовательский интерфейс из AsyncTask?

Вы должны просто построить данные в doInBackground(), но обновитьпользовательский интерфейс в onPostExecute().

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

Ваше форматирование немного отклонено, но если я правильно понимаю, вы звоните initCalendar() в ваших AsyncTask doInBackground().Вам не разрешено делать это с AsyncTask s.

Использовать doInBackground() для длительных операций, таких как HTTP-вызовы, доступ к БД и т. Д. После того, как у вас есть все необходимое, позвоните initCalendar()от onPostExecute().

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

Возможно, это не лучшее решение, но вы можете расширить базовую тему, используемую в Android, и установить фон окна для изображения, которое указывает, что активность загружается. Затем установите эту тему на Activity B. Теперь, когда загружается Activity B, она будет отображать ваш рисунок вместо черного окна. Возможно, вам даже удастся проявить креативность с помощью списка анимаций и получить какой-то неопределенный эффект загрузки.

...