11

我有个问题。我需要从一项活动转到另一项活动。我的第二个活动有一个很大的 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();
            }
        }
   } 
}

你可以看到我setContentViewonCreate方法。

这行不通。它给了我一个例外,像这样:

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

4 回答 4

1

这是一个糟糕的设计。如果您有如此大量的数据要呈现给可能会滚动浏览的用户,则应该使用AdapterView子类,例如 aListViewGridView。包含近 400 个元素的 XML 布局非常大。

我了解您正在尝试做什么(您正在尝试使用View单独执行大规模层次结构的冗长构建,但您发现它被炸毁了,因为您试图在 a 上触摸层次结构非用户界面)。ThreadAsyncTaskViewThread

即使您在构建层次结构时确实设法在前台实现了某种进度条,我不确定系统是否会在它膨胀View层次结构时提供回调进度信息的方法(但我可能错了)。

AdapterView创建 s 正是为了解决这类问题。使用,通常在任何时候内存中AdapterView只存在一个屏幕的价值。Views例如,您可能有一个有一千行的表,但一次只有七行适合屏幕,因此View内存中可能一次只存在八行。此外,适配器还应该回收Views,进一步优化性能。

于 2013-04-02T18:00:40.660 回答
0

这可能不是最好的解决方案,但您可以做的是扩展 android 中使用的基本主题并将窗口背景设置为指示活动正在加载的图像。然后将该主题设置为 Activity B。现在,当 Activity B 加载时,它将显示您的可绘制对象而不是黑色窗口。您甚至可以通过动画列表获得创意并获得某种不确定的加载效果。

于 2010-12-09T20:40:21.740 回答
0

您的格式有点偏离,但如果我理解正确,您正在调用initCalendar()AsyncTaskdoInBackground(). 不允许您使用AsyncTasks 执行此操作。

用于doInBackground()长时间运行的操作,例如 HTTP 调用、数据库访问等。一旦你有了你需要的东西,initCalendar()onPostExecute().

于 2010-12-10T09:43:47.610 回答
0

您是否尝试new MakeYearTask().execute();过 onResume() 代替?

虽然不优雅,但您可以在创建时触发延迟线程帖子以等待几毫秒。

编辑:

我只是这个错误:

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

您是否正在从 AsyncTask 修改 UI?

您应该只在 中构建数据doInBackground(),但在 中更新 ui onPostExecute()

于 2010-12-09T21:03:34.300 回答