【问题标题】:How can I show a Progress dialog between two activities?如何在两个活动之间显示进度对话框?
【发布时间】:2010-12-09 20:29:19
【问题描述】:

我有问题。我需要从一项活动转到另一项活动。我的第二个活动有一个很大的 xml 布局,有很多元素(我说的是大约四百左右),然后显示第二个活动需要几秒钟(太多)。

如何在两个活动之间显示进度对话框?

我正在尝试使用后台任务来执行此操作。

我的 Activity 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

【问题讨论】:

  • 回答如何在两个activity之间创建进度条link

标签: android android-activity progressdialog


【解决方案1】:

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

我了解您要做什么(您正尝试使用 AsyncTask 在单独的 Thread 上执行庞大的 View 层次结构的冗长构建,但您发现它是对你试图在非 UI Thread 上触摸 View 层次结构感到愤怒)。

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

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

【讨论】:

  • 如果你需要设计一个屏幕来容纳一个可以水平和垂直滚动的表格,你将如何使用适配器解决这个问题?
  • 好点。我简单地搜索并发现了几个 SO 问题,这些问题表明通过一点工作就可以实现水平和垂直可滚动的基于适配器的布局(例如stackoverflow.com/questions/7681581/…)。我认为如果 OP 在.setContentView() 的膨胀过程中遇到过度延迟,那么整体性能可能会很慢(可能在较慢的设备上),因此使用基于适配器的布局是值得的,即使这意味着有点痛苦它可以工作,或者重新考虑一下 UI。
  • 其实我同意,我这里只有这个问题:stackoverflow.com/questions/15559851/… 并且仍在寻找解决方案。但是谢谢:)
  • 啊啊!这很有趣 - 碰巧的是,我实际上在前几天为你提出的这个问题加注了星标并投了赞成票。我自己的一个应用程序也有一个非常相似的 UI 结构(带有Fragments 的寻呼机包含TableLayouts,在使用适配器很棘手的情况下)并且它有时非常缓慢,所以我很想看看什么已向您提出建议。我一定会反馈我能提供的任何帮助。
【解决方案2】:

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

【讨论】:

  • 嗯。我和你一样想,但如果它有效,对我来说没问题:) 我要试试,然后告诉你发生了什么。谢谢。
  • 我还没有尝试这个,但我把它放在了我的“待办事项”列表中。当我尝试这个时,我会告诉你结果。谢谢!
  • 期待听到/看到结果
【解决方案3】:

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

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

编辑:

我只是这个错误:

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

您是否正在从 AsyncTask 修改 UI?

您应该只在doInBackground() 中构建数据,但在onPostExecute() 中更新用户界面。

【讨论】:

  • 是的,现在,结果相同。 :( 无论如何谢谢。
  • 用附加信息编辑了我的答案。也许就是这样。
【解决方案4】:

您的格式有点不对,但如果我理解正确,您在AsyncTask 的doInBackground() 中调用initCalendar()。 AsyncTasks 不允许你这样做。

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

【讨论】:

  • 对不起格式。我修复它:D 我会尝试理解你的答案。我是西班牙人,我的英语不太好。
  • 基本上,我的意思是将这个YearActivity.this.initCalendar(); 移动到onPostExecute() 方法,我试图解释原因。 :)
  • 嗨,扎拉!很难向我解释。如果我把 YearActivity.this.initCalendar();在 onPostExecute() 上,我没有任何错误,但 ProgressDialog 没有显示...活动之间的转换需要几秒钟,这就是我想要阻止的事情。我想显示进度对话框以使等待更舒适。你懂我的意思吗?正是出于这个原因,我使用了 AsyncTask。也许存在另一种方法,但我不知道。 :(
  • 在onPreExecute() 中显示您的进度条并在onPostExecute() 上关闭它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-07-09
  • 1970-01-01
  • 1970-01-01
  • 2020-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多