为 MainActivity 添加一个 progressDialog 到 JSON 解析器 class 和 return 方法

Add a progressDialog to JSON Parser class and return method for MainActivity

我有一个 JSONparser Class 来获取数据并将数据发送到服务器,它工作正常,但是在没有 wifi 连接的情况下测试它时,过程需要更长的时间。是否可以将进程对话框放入我的 class,因为我将此 class 形式称为每个需要发送或接收数据的 activity。

我尝试了一些不同的事情,例如在任务之前和之后应用设置 LinearLayout 的可见性,例如:

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

但是屏幕只是冻结并加载数据。

我尝试在 HTTP 请求的开头添加一个 processDialog 并在任务完成后再次删除它,但我收到空引用错误。

我觉得错误可能出在class本身,因为我是新手Java我现在只知道基础知识所以只是学习。

这是我的 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;
    }

}

说实话,我并没有写下所有这些 class,我遵循了 tutorial 并根据需要修改了 class。

class可以在任何activity中调用,这就是class的想法是这样的:

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

如果问题出在 class,我敢肯定,您能否解释一下如何修改它以合并 progressDialog。

更新 在下面答案的帮助下,我设法使用 PostAsync class 添加了一个进程对话框。 屁股我已经修改了这个 class 以使其更加动态是否可以在我当前的 activity 上处理 return 或者我可以只处理 PostAcync [=53 中的 return =].

例如: 基本的 PostAcync Class 将由 New PostAcync.execute(param,param) 调用; 但是我已经修改了这个,所以它是通用的并且可以在任何 activity 上工作; 所以不,我会调用这个 class 并通过以下方式执行任务:

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

所以现在我添加对话框生成器的上下文来运行 我可以根据任务添加不同的消息 第一个参数始终是网页。

有什么方法可以在上面添加回调,比如

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

您似乎在主 (UI) 线程中 运行 处理此 HTTP 请求。因此,在您的 HTTP 请求完成之前,UI 线程将被冻结。这就是冻结的原因。 您可以将此委托给 AsyncTask 并执行所需的操作。 AsyncTask 将其拆分为 3 个部分 1. 术前 2.运行中(后台线程) 3.Post操作

第 1 步和第 3 步是 运行 在 UI 线程中。所以你可以在那里开始和结束进度对话框。 您可以在步骤 2 中进行 HTTP 调用。

检查 this tutorial in Android developer site and this tutorial which I did and these 个幻灯片

可以在AsyncTask中解析JSON,在解析开始前显示Dialog,解析完成后消失

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

我实际上 wrote a blog post 最近使用了此 JSONParser class 的更新版本,并提供了如何将其与显示 ProgressDialog 的 AsyncTask 一起使用的示例。

对于您的情况,您可以使用这样的 AsyncTask:

调用 AsyncTask,传入电子邮件和密码:

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

按如下方式定义您的 AsyncTask,其中包括 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();
            }
        }
    }

}

这是 JSONParser class 的更新版本,它使用 HttpURLConnection 而不是已弃用的 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;
    }
}