Add a progressDialog to JSON Parser class and retu

2019-05-30 05:27发布

I have a JSONparser Class to get and send data to a server which works fine but when testing this without a wifi connection the process takes a little longer. Is it possible to put a process Dialog into my class, as I would call this class form each activity that requires data to be sent or received.

I have tried a few different things like applying setting the visisability of a LinearLayout before and after the task like:

loading.setVisibility(View.VISIBLE);
/// DO TASK
loading.setVisibility(View.GONE);

But the screen just freezes and loads the data in anyway.

I have tried adding a processDialog at the start of the HTTP request and removing it again when the task is complete but I get a null reference error.

I have feeling that the error may lies in the class itself, as I am new to Java I only really know the basics at the moment so just learning.

This is my JSONParser Class

public class JSONParser {

    static InputStream is = null;
    static JSONObject jObj = null;
    static String json = "";
    static String root = "**MY SERVER**";
    private View loading = null;

    public JSONParser() {

    }
    public JSONObject makeHttpRequest(String url, String method, List<NameValuePair> params) {
        params.add(new BasicNameValuePair("APP_ID", "**APPTOKEN**"));
        // Making HTTP request
        try {
            // check for request method
            if(method.equalsIgnoreCase("POST")){
                DefaultHttpClient httpClient = new DefaultHttpClient();
                HttpPost httpPost = new HttpPost(this.root + url);
                httpPost.setEntity(new UrlEncodedFormEntity(params));

                HttpResponse httpResponse = httpClient.execute(httpPost);
                HttpEntity httpEntity = httpResponse.getEntity();
                is = httpEntity.getContent();

            }else if(method.equalsIgnoreCase("GET")){
                // request method is GET
                DefaultHttpClient httpClient = new DefaultHttpClient();
                String paramString = URLEncodedUtils.format(params, "utf-8");
                url += "?" + paramString;
                HttpGet httpGet = new HttpGet(url);

                HttpResponse httpResponse = httpClient.execute(httpGet);
                HttpEntity httpEntity = httpResponse.getEntity();
                is = httpEntity.getContent();
            }

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader( is, "utf-8"), 8);
            StringBuilder sb = new StringBuilder();
            String line = null;
            while ((line = reader.readLine()) != null) {
                sb.append(line + "\n");
            }
            is.close();
            json = sb.toString();
        } catch (Exception e) {
            Log.e("Buffer Error", "Error converting result " + e.toString());
        }

        // try parse the string to a JSON object
        try {
            jObj = new JSONObject(json);
        } catch (JSONException e) {
            Log.e("JSON Parser", "Error parsing data " + e.toString());
        }
        // return JSON String
        return jObj;
    }

}

Truth be told I did not write all of that class, I followed a tutorial and amended the class to my needs.

The class can be called in any activity, which was the idea of the class like this:

List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("email", email));
params.add(new BasicNameValuePair("password", password));
JSONParser jsonParser = new JSONParser();
loading.setVisibility(View.VISIBLE);
JSONObject json = jsonParser.makeHttpRequest("login.php", "POST", params);
try {
      Boolean success = json.getBoolean("ok");
      loading.setVisibility(View.GONE);
      if (success) {
         Log.d("LOGIN","LOGIN SUCCESSFUL");
         finish();
     } else {
         String err_msg = json.getString("error");
         Toast toast = Toast.makeText(getApplicationContext(), err_msg, Toast.LENGTH_LONG);
         toast.show();

     }
} catch (JSONException e) {
     e.printStackTrace();
}

If the problem is the class, which I'm sure it is could you offer an explanation of how to amend this to incorporate a progressDialog.

UPDATE With help in the answer below I have managed to add a process dialog using a PostAsync class. Ass I have modified this class to be more dynamic is it possible to process the return on my current activity or can I only process the return inside the PostAcync Class.

For example: The basic PostAcync Class would be called by New PostAcync.execute(param,param); But i have modified this so that it is universal and can work on any activity; So no instead I would call this class and execute the task by:

PostAsync post = new  PostAsync();
post.context = ThisActivity.this;
post.message = "Attempting to login";
post.execute("login.php", email, password);

So now I add in the Context for the Dialog Builder to function I can add a different message depending on the task And the first param is always the webpage.

is there a way I can add a callback onto this something like

JSONObject response = post.repsonse;
//then process the data here as I could using the ajax success callback in jQuery

3条回答
ゆ 、 Hurt°
2楼-- · 2019-05-30 05:59

It seems you're running this HTTP request in the main (UI) thread. So until your HTTP request is done, the UI thread is frozen. This is the reason for the freeze. You can delegate this to an AsyncTask and do the required operation. The AsyncTask splits this to 3 parts 1. Pre operation 2. In operation (background thread) 3. Post operation

steps 1 and 3 are run in the UI thread. So you can start and end the progress dialog there. You can do the HTTP call in step 2.

Check this tutorial in Android developer site and this tutorial which I did and these slides

查看更多
啃猪蹄的小仙女
3楼-- · 2019-05-30 06:02

You can parse JSON in AsyncTask and display the Dialog before starting the parsing and make it disappear when the job is completed.

public class JSONParseAsyncTask extends AsyncTask<Void, Void, Void> {

    private ProgressDialog progressDialog;

    public JSONParseAsyncTask(Context ctx) {
        progressDialog = new ProgressDialog(ctx);

    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        progressDialog.show();
    }

    @Override
    protected void onPostExecute(Void aVoid) {
        super.onPostExecute(aVoid);
        progressDialog.dismiss();
    }

    @Override
    protected Void doInBackground(Void... params) {
        //JSON PARSE

        return null;
    }
}
查看更多
看我几分像从前
4楼-- · 2019-05-30 06:08

I actually wrote a blog post recently with an updated version of this JSONParser class, with examples of how to use it with an AsyncTask that shows a ProgressDialog.

For your case, you could use an AsyncTask like this:

Call the AsyncTask, passing in the email and password:

new PostAsync().execute(email, password);

Define your AsyncTask as follows, which includes a ProgressDialog:

class PostAsync extends AsyncTask<String, String, JSONObject> {

    JSONParser jsonParser = new JSONParser();

    private ProgressDialog pDialog;

    private static final String LOGIN_URL = "http://www.example.com/login.php.php";

    @Override
    protected void onPreExecute() {
        pDialog = new ProgressDialog(MainActivity.this);
        pDialog.setMessage("Attempting login...");
        pDialog.setIndeterminate(false);
        pDialog.setCancelable(true);
        pDialog.show();
    }

    @Override
    protected JSONObject doInBackground(String... args) {

        try {

            List<NameValuePair> params = new ArrayList<NameValuePair>();
            params.add(new BasicNameValuePair("email", args[0]));
            params.add(new BasicNameValuePair("password", args[1]));

            Log.d("request", "starting");

            JSONObject json = jsonParser.makeHttpRequest(
                    LOGIN_URL, "POST", params);

            if (json != null) {
                Log.d("JSON result", json.toString());

                return json;
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    protected void onPostExecute(JSONObject json) {

        if (pDialog != null && pDialog.isShowing()) {
            pDialog.dismiss();
        }

        if (json != null) {
            try {
                Boolean success = json.getBoolean("ok");
                if (success) {
                    Log.d("LOGIN","LOGIN SUCCESSFUL");
                    finish();
                } else {
                    String err_msg = json.getString("error");
                    Toast toast = Toast.makeText(MainActivity.this.getApplicationContext(), err_msg, Toast.LENGTH_LONG);
                    toast.show();

                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    }

}

Here is the updated version of the JSONParser class, which uses HttpURLConnection instead of the deprecated DefaultHttpClient:

import android.util.Log;
import org.apache.http.NameValuePair;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.List;

public class JSONParser {

    String charset = "UTF-8";
    HttpURLConnection conn;
    DataOutputStream wr;
    StringBuilder result = new StringBuilder();
    URL urlObj;
    JSONObject jObj = null;
    StringBuilder sbParams;
    String paramsString;

    public JSONParser() {

    }

    public JSONObject makeHttpRequest(String url, String method,
                                      List<NameValuePair> params) {

        sbParams = new StringBuilder();
        for (int i = 0; i < params.size(); i++) {

            NameValuePair nvp = params.get(i);
            try {
                sbParams.append("&").append(nvp.getName()).append("=")
                   .append(URLEncoder.encode(nvp.getValue(), charset));
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }

        if (method.equals("POST")) {
            // request method is POST
            try {
                urlObj = new URL(url);

                conn = (HttpURLConnection) urlObj.openConnection();

                conn.setDoOutput(true);

                conn.setRequestMethod("POST");

                conn.setRequestProperty("Accept-Charset", charset);

                conn.setReadTimeout(10000);
                conn.setConnectTimeout(15000);

                conn.connect();

                paramsString = sbParams.toString();

                wr = new DataOutputStream(conn.getOutputStream());
                wr.writeBytes(paramsString);
                wr.flush();
                wr.close();

            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        else if(method.equals("GET")){
            // request method is GET

            if (sbParams.length() != 0) {
                url += "?" + sbParams.toString();
            }

            try {
                urlObj = new URL(url);

                conn = (HttpURLConnection) urlObj.openConnection();

                conn.setDoOutput(false);

                conn.setRequestMethod("GET");

                conn.setRequestProperty("Accept-Charset", charset);

                conn.setConnectTimeout(15000);

                conn.connect();

            } catch (IOException e) {
                e.printStackTrace();
            }

        }

        try {
            //Receive the response from the server
            InputStream in = new BufferedInputStream(conn.getInputStream());
            BufferedReader reader = new BufferedReader(new InputStreamReader(in));

            String line;
            while ((line = reader.readLine()) != null) {
                result.append(line);
            }

            Log.d("JSON Parser", "result: " + result.toString());

        } catch (IOException e) {
            e.printStackTrace();
        }

        conn.disconnect();

        // try parse the string to a JSON object
        try {
            jObj = new JSONObject(result.toString());
        } catch (JSONException e) {
            Log.e("JSON Parser", "Error parsing data " + e.toString());
        }

        // return JSON Object
        return jObj;
    }
}
查看更多
登录 后发表回答