【问题标题】:How to show ProgressDialog across launching a new Activity?如何在启动新活动时显示 ProgressDialog?
【发布时间】:2012-10-22 18:07:38
【问题描述】:

目标:拥有一个显示“正在加载...”的 ProgressDialog,直到下一个 Activity 完全加载并显示在屏幕上。

尝试将 ProgressDialog 上下文和活动设置为原始活动。还尝试使用 getApplicationContext() 和 getParentContext()。最后两种方法的例外情况。需要这样做,因为由于非简单的布局文件,目标 Activity 的渲染速度很慢。 (由于组织问题,现在无法解决这个问题。)结果目标 Activity 需要 1-2 秒才能 OnCreate,然后屏幕变黑长达 5 秒以上,然后它会绘制。渲染很慢。使用 Hierarchy Viewer 进行了审核,发现很多红球,但现在无法修复。

阅读一些相关但尚未找到解决方法。例如。 What's the difference between the various methods to get a Context?

例如这两个崩溃。使用源 Activity 的“this”也不起作用。

// Context parentContext = this.getParent().getBaseContext();    
Context parentContext = this.getApplicationContext();
ProgressDialogMenuable theProgressDialog = new ProgressDialogMenuable(parentContext,this);
theProgressDialog.setTitle("yeeha");
theProgressDialog.setMessage("weewah");
theProgressDialog.setIndeterminate(true);
theProgressDialog.setCancelable(true);
theProgressDialog.show();

另外,奇怪的是,当我这样做时没有任何反应: theProgressDialog.show(); ActivityHelper.changeActivity(this, v, InsMyHoldingsActivity.class, extraMap, -1, -1); 用户单击按钮以显示下一个活动,但 ProgressDialog 与 Activity 启动冲突,除了按钮在触摸时变为黄色之外实际上没有任何反应。下面的按钮有效。删除 ProgressDialog 创建,它可以工作。没有记录控制台消息。对开发者来说肯定有点反感。

【问题讨论】:

  • 在您的新活动中创建一个异步任务,在那里进行所有处理,在执行后设置布局元素。在创建时显示进度条,并在执行后关闭。
  • 让我试试。我只能子类化(而不是更改)目标活动的情况。所以,这可能行得通。
  • 如果您作为解决方案发布,那么我会接受。我不认为 ProgressDialog 可以跨越活动的生命周期(多个活动);但是可以通过这种方法对用户产生影响,一个 PDlg 在 Activity A 中,然后在 ActivityB 中,就像你说的那样。我实际上使用了与 AsynTask 不同的语法,但我相信它在语义上是相同的。最终 Runnable r = new Runnable() { public void run() { setupActivityDisplay(); // 需要一段时间的事情 theProgressDialog.dismiss(); } }; (new Handler()).postDelayed(r, 1000);
  • 更多研究表明,在完成 Activity 布局之前,无法显示 ProgressDialog。简单地说,对于复杂的布局,用户会在一段时间内看到一个黑色(空白)屏幕。仍在研究中。
  • 有一种方法可以显示 ProgressDialog。在创建之后。只需删除布局 setContentView( 从 onCreate 调用。稍后再做。

标签: android progressdialog


【解决方案1】:

你可以像这样显示一个进度对话框 -

定义这个

private ProgressDialog pd = null;

在你的活动课上

把这个放在你的 onCreate 中(不要直接在这里 setContentView)

@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.pd = ProgressDialog.show(this, "Fancy App",
                    "Loading...Please wait...", true, false);
        // Start a new thread that will download all the data
        new IAmABackgroundTask().execute();

    }

//后台重载

class IAmABackgroundTask extends
        AsyncTask<String, Integer, Boolean> {
    @Override
    protected void onPreExecute() {
        // showDialog(AUTHORIZING_DIALOG);
    }

    @Override
    protected void onPostExecute(Boolean result) {

        // Pass the result data back to the main activity
        ActivityName.this.data = result;

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

        setContentView(R.layout.main);


    }

    @Override
    protected Boolean doInBackground(String... params) {

        //Do all your slow tasks here but dont set anything on UI
                    //ALL ui activities on the main thread 

        return true;

    }

}

也可以通过这个:http://developer.android.com/training/improving-layouts/index.html 来优化布局性能。 也可以使用 Traceview 寻找瓶颈

【讨论】:

  • 这是正确的做法。将慢速渲染延迟到以后。不得不与 AsyncTask 作为“发布”处理程序不起作用(如果没有别的,怀疑 AsyncTask 仅从 MessageQueue 运行?还没有发现。)我实际上需要两个 AsycTasks。一个设置布局,然后第二个填充数据。感谢您发布 Slartibarfast。
  • 没问题。如果它解决了您的问题,请接受作为答案,欢迎来到 SO :)
【解决方案2】:

有两种方法

第一种使用异步任务的方法

如果您正在执行繁重的任务,例如从服务器加载数据或在这种情况下解析 xml,请使用 AsynTask 如果您想从 ActivityA 调用 ActivityB,那么

*step-1*创建一个 AsyncTask 类。在 doBackground() 方法中编写所有后台任务,并在任务完成后调用代码在 onPostExecute() 后执行方法中编写的活动

import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.view.View;



public class LoadingDataFromServer extends AsyncTask {
    Context currentContext = null;

    boolean isCancelled = false;


    public LoadingDataFromServer(Context context) {
        currentContext = context;

    }

    @Override
    protected void onPreExecute() {
        if (DashboardActivity.progressBarLayout != null) {
            DashboardActivity.progressBarLayout.setVisibility(View.VISIBLE);
            // Log.i(TAG,".....Now make progress bar visible.....");
        }

        super.onPreExecute();
    }

    @Override
    protected Object doInBackground(Object... params) {
        // do background processing

        try {
// do background tasks eg sever communication
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onPostExecute(Object result) {
        // TODO Auto-generated method stub
        // progressDialog.dismiss();

        // call second Activity
        Intent i = new Intent(currentContext, com.ActvityB.class);
        super.onPostExecute(result);
    }

    @Override
    protected void onCancelled() {
        // TODO Auto-generated method stub
        isCancelled = true;
        super.onCancelled();
    }

}

step-2 在要跳转到新活动的活动中(例如在 ActivityA 中)调用 AsynTask 的 execute()

new LoadingDataFromServer(context).execute(null);

第二种方法

首先显示进度对话框。 创建一个线程来执行所有后台任务。当线程完成任务然后取消进度对话框并调用下一个活动

当线程完成任务然后调用下一个活动传递此对象(进度对话框)并在该新活动内关闭此对话框。

【讨论】:

【解决方案3】:

这是我的代码,可以提供帮助。

在此,我只发布AsyncTask 的第一种方法,即onPreExecute

User_AsyncTask 扩展 AsyncTask:

public class User_AsyncTask extends AsyncTask<String, String, String>
    {
        String response = "";

        @Override
        protected void onPreExecute()
        {
            try
            {
                if (progressDialog != null)
                    progressDialog.cancel();
            }
            catch (Exception e)
            {

            }
            progressDialog = ProgressDialog.show(DisplayDetails.this, "", "Please wait...", true, true);
            progressDialog.setCancelable(false);
            progressDialog.show();
        }

【讨论】:

  • 如果有帮助请评价这个答案
猜你喜欢
  • 1970-01-01
  • 2015-12-14
  • 1970-01-01
  • 2013-06-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多