【问题标题】:ProgressDialog doesn't show the real progress of fetching information from a web serverProgressDialog 不显示从 Web 服务器获取信息的真实进度
【发布时间】:2012-07-24 21:00:06
【问题描述】:

我将获取某些信息的代码转移到 Async 类中,这是为了最大限度地减少缓冲并避免“不响应”或更糟糕的应用程序崩溃的可能性。

现在,我想显示一个 ProgressDialog,它应该设置为“不可取消”以避免用户中断连接。

但是如果我的 ProgressDialog 真的显示了我的应用程序中实际发生的事情的进度(从在线服务器获取信息期间),我会感到有些困惑。因为在我的模拟器上,我的应用程序暂停(大约 2 秒),然后显示 ProgressDialog,然后立即显示“获取”的结果。

任何帮助将不胜感激。

谢谢。这是我的代码。

public void onClick(View v) 
{
    new retrieveOnline().execute();
}

private class retrieveOnline extends AsyncTask <Void, Void, Void>
{
    protected void onPreExecute ()
    {
        pDialog = new ProgressDialog (FirstScreen.this);
        pDialog.setMessage("Please wait...");
        pDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        pDialog.setIndeterminate(true);
        pDialog.setCancelable(false);
        pDialog.show();
    }
    @Override
    protected Void doInBackground(Void... unused)
    {
        runOnUiThread (new Runnable()
        {
            public void run()
            {
                httpclient = new DefaultHttpClient();
                httppost = new HttpPost("http://mysite.com/database/login.php");
                stringEmail = etEmail.getText().toString();
                stringPassword = etPassword.getText().toString();

                try 
                {
                    nameValuePairs = new ArrayList<NameValuePair>();
                    nameValuePairs.add(new BasicNameValuePair("stringEmail", stringEmail));
                    nameValuePairs.add(new BasicNameValuePair("stringPassword", stringPassword));

                    httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
                    response = httpclient.execute(httppost);
                    if(response.getStatusLine().getStatusCode()== 200)
                    {
                        entity = response.getEntity();
                        if(entity != null)
                        {   
                            InputStream instream = entity.getContent();
                            JSONObject jsonResponse = new JSONObject(convertStreamToString(instream));

                            String errorEmail = jsonResponse.getString("errorEmail");
                            if (errorEmail != "")
                            {
                                tvEmailError.setText(errorEmail);
                            }else{}

                            String errorPassword = jsonResponse.getString("errorPassword");
                            if (errorPassword != "")
                            {
                                tvPasswordError.setText(errorPassword);
                            }else{}

                            String inactiveAccount = jsonResponse.getString("inactiveAccount");
                            if (inactiveAccount.length() != 0)
                            {                       
                                AlertDialog alert = new AlertDialog.Builder(FirstScreen.this).create();
                                alert.setCancelable(false);
                                alert.setMessage("Your account is currently inactive and unusable." + "\nDo you want to send an account activation message to your email now?");
                                alert.setButton("Yes", new DialogInterface.OnClickListener()
                                {   
                                    public void onClick(DialogInterface arg0, int arg1)
                                    {
                                        httpclient = new DefaultHttpClient();
                                        httppost = new HttpPost("http://mysite.com/database/activate2.php");
                                        stringEmail = etEmail.getText().toString();
                                        stringPassword = etPassword.getText().toString();

                                        try
                                        {
                                            nameValuePairs = new ArrayList<NameValuePair>();
                                            nameValuePairs.add(new BasicNameValuePair("stringEmail", stringEmail));
                                            nameValuePairs.add(new BasicNameValuePair("stringPassword", stringPassword));

                                            httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
                                            response = httpclient.execute(httppost);
                                            if(response.getStatusLine().getStatusCode()== 200)
                                            {
                                                entity = response.getEntity();
                                                if(entity != null)
                                                {
                                                    InputStream instream = entity.getContent();
                                                    JSONObject jsonResponse = new JSONObject(convertStreamToString(instream));

                                                    String successActivation = jsonResponse.getString("successActivation");
                                                    if (successActivation.length() != 0)
                                                    {
                                                        //Progress Dialog here.
                                                        Toast.makeText(getBaseContext(), "We successfully sent an activation message to your email account. Try to log in again after activating your account.", Toast.LENGTH_LONG).show();
                                                    }
                                                    else
                                                    {
                                                        Toast.makeText(getBaseContext(), "Sorry, we are unable to reach your email account.",Toast.LENGTH_SHORT).show();
                                                    }
                                                }
                                            }   
                                        }
                                        catch (Exception e)
                                        {
                                            e.printStackTrace();
                                            Toast.makeText(getBaseContext(), "Connection to the server is lost. Please check your internet connection.", Toast.LENGTH_SHORT).show();
                                        }
                                    }
                                });
                                alert.setButton2("Not now", new DialogInterface.OnClickListener()
                                {   
                                    public void onClick(DialogInterface arg0, int arg1)
                                    {
                                        AlertDialog alert2 = new AlertDialog.Builder(FirstScreen.this).create();
                                        alert2.setCancelable(false);
                                        alert2.setMessage("Exit FindDroid?");
                                        alert2.setButton("Yes", new DialogInterface.OnClickListener()
                                        {   
                                            public void onClick(DialogInterface arg0, int arg1)
                                            {
                                                finish();
                                            }
                                        });
                                        alert2.setButton2("No", new DialogInterface.OnClickListener()
                                        {   
                                            public void onClick(DialogInterface arg0, int arg1)
                                            {
                                                //Do nothing
                                            }
                                        });
                                        alert2.show();
                                    }
                                });
                                alert.show();
                            }else{}

                            if ((errorEmail.length()==0) && (errorPassword.length()==0)&& (inactiveAccount.length()==0))
                            {                       
                                String dbEmail = jsonResponse.getString("dbEmail");
                                String dbPassword = jsonResponse.getString("dbPassword");
                                //---Store dbEmail and dbPassword to SharedPreferences---//
                                //-------------------------------------------------------//
                                Intent i = new Intent(getApplicationContext(), Construction.class);
                                startActivity(i);
                                finish();
                            }

                        }//if (entity!=null)..      
                    }//if response()...
                }//try..
                catch(Exception e)
                {
                    e.printStackTrace();
                    Toast.makeText(getBaseContext(), "Connection to the server is lost. Please check your internet connection.", Toast.LENGTH_SHORT).show();
                }   

            }
        });

        return (null);
    }

    protected void onPostExecute (Void unused)
    {
        pDialog.dismiss();
    }
}

我正在进行登录活动,它正在从在线服务器获取注册用户信息..

【问题讨论】:

    标签: android progressdialog


    【解决方案1】:

    好的,所以你这里有一个 AsyncTask,它立即创建一个在 UI 线程上运行的可运行对象,完全违背了 AsyncTask 的目的。摆脱 runOnUIThread,在后台调用中进行所有处理并使用 OnProgressUpdate 和 OnPostExecute 更新 UI。在这里也准备好 API 文档:

    http://developer.android.com/reference/android/os/AsyncTask.html

    ProgressDialog 不会自动更新,您需要在 AsyncTask 的 OnProgressUpdate 调用中更新它。

    【讨论】:

    • 如何更新progressDialog?我需要传入一个整数值吗?请帮帮我。
    • 准备好了->阅读。所以除非我更改至少 6 个字符,否则不会让我改正错字...
    • 如果您查看我链接的文档中名为“使用”的部分,它会告诉您该怎么做。您在 doBackground 中调用 publishProgress,它将在 UI 线程中调用 OnProgressUpdate,以便您可以更新 ProgressDialog 或您想要的任何其他 UI 元素。然后在您退出 doInBackground 后,它会在 UI 线程上调用 onPostExecute,这样您就可以关闭进度对话框并使用任何剩余数据更新 UI。
    • 我认为您给我的链接中的代码与我现在所拥有的非常不同。我没有精确的整数值来增加。请指导我。
    • 只需要在doInBackground中调用publishProgress吗?还是我仍然需要传入一个整数值,例如您给我的示例中的 count 变量。对不起,但我是android编程的新手。谢谢。
    【解决方案2】:

    是的,从doInBackground 调用publishProgress 并使用整数传递给pDialog.setProgress(int) 更改AsyncTask 签名以传递整数&lt;Void, Integer, Void&gt; 在传递给@ 之前,您需要规范化0-10000 之间的进度整数987654325@ 这可以在通过字节或行循环从网络加载图像或大量数据时完成,读取块,并随时传递进度更新。

    您需要修改的另一件事是,您在doInBackground 期间无法访问/修改/以任何方式触摸 UI 中的对象,您需要移动 alert.show() Toast 之类的东西,我相信 Activity 方法也(即finish())到postExecute 方法。

    【讨论】:

    • 哦,我明白了。但是我该怎么做呢?你能指导我吗?我只需要增加一些增量吗?而不是传入一些整数值?
    • 0 到 10,000 (100%)。您必须确定您在任务中取得的进度百分比(完全取决于您在做什么),将该百分比转换为 0-10000 范围并将其传递给 progressUpdate()。例如,如果我正在下载图像的字节,我可能会执行以下操作:progressUpdate((int)((float)bytesDownloaded/(float)totalBytes)*10000f)));
    • 先生,您能多解释一下或者给我一些例子吗?我真的不知道我要做什么。
    • 但我的应用程序与下载的东西不同。如果我的 doInBackground 中的进程不包含整数值,我将如何传递整数值?
    • 我只是做一个登录和注册活动。我没有一些整数可以传入。我该怎么做?
    猜你喜欢
    • 1970-01-01
    • 2017-01-16
    • 2016-12-09
    • 1970-01-01
    • 1970-01-01
    • 2016-09-29
    • 1970-01-01
    • 2021-12-11
    相关资源
    最近更新 更多