简体   繁体   中英

ProgressDialog doesn't show the real progress of fetching information from a web server

I transferred my code of fetching some information into an Async class, it is to minimize the buffering and avoid the possibility of 'not responding', or worse crashing of my application.

Now, I want to show a ProgressDialog, and it should be set to 'not cancelable' to avoid users of interrupting the connection.

But I am a little confused if my ProgressDialog really show the progress of what actually happens in my application (during the fetching of information from an online server). Because on my emulator, my application pauses (for about 2 seconds), and then shows the ProgressDialog, and then immediately shows the result of the 'fetching'.

Any help will be much appreciated.

Thanks. Here's my code.

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();
    }
}

I am making a log in activity, and it's getting the registered users information from an online server..

Ok, so what you have here is an AsyncTask that immediately creates a runnable that runs on the UI thread, completely defeating the purpose of the AsyncTask. Get rid of the runOnUIThread, do all the processing in the background call and use the OnProgressUpdate and OnPostExecute to update the UI. Also ready the API documentation here:

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

The ProgressDialog doesn't automatically update, you need to update it in the OnProgressUpdate call from your AsyncTask.

Yes, call publishProgress from doInBackground with an integer to pass to pDialog.setProgress(int) Alter the AsyncTask signature to pass the integer <Void, Integer, Void> You'll want to normalize that progress integer between 0-10000 before passing to onProgressUpdate This can be done when loading an image or a large amount of data from the web by loop through bytes or lines, reading in chunks, and passing progress update as you go.

Another thing you need to modify, is you CANNOT access/modify/touch-in-any-way objects in the UI during doInBackground You'll need to move things like alert.show() Toast and I beleive the Activity methods also (ie. finish() ) to the postExecute method.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM