【问题标题】:Add a progressDialog to JSON Parser class and return method for MainActivity将 progressDialog 添加到 JSON Parser 类并返回 MainActivity 方法
【发布时间】:2015-07-06 18:57:31
【问题描述】:

我有一个 JSONparser 类来获取数据并将其发送到运行良好的服务器,但是在没有 wifi 连接的情况下进行测试时,该过程需要更长的时间。是否可以将一个流程对话框放入我的类中,因为我会将这个类称为每个需要发送或接收数据的活动。

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

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

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

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

我感觉错误可能在于课程本身,因为我是 Java 新手,目前我只真正了解基础知识,所以只是学习。

这是我的 JSONParser 类

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

}

说实话,我并没有写完所有的课程,我遵循tutorial 并根据我的需要修改了课程。

类可以在任何活动中调用,类的思路是这样的:

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

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

更新 在以下答案的帮助下,我设法使用 PostAsync 类添加了一个进程对话框。 我已将此类修改为更具动态性,是否可以处理当前活动的返回,或者我只能在 PostAcync 类中处理返回。

例如: 基本 PostAcync 类将由 New PostAcync.execute(param,param); 调用。 但是我已经对此进行了修改,使其具有通用性并且可以用于任何活动; 所以不,我会调用这个类并通过以下方式执行任务:

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

所以现在我添加 Context 以使 Dialog Builder 运行 我可以根据任务添加不同的消息 第一个参数始终是网页。

有没有办法可以在上面添加回调

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

【问题讨论】:

    标签: java android json android-asynctask dialog


    【解决方案1】:

    我实际上wrote a blog post 最近使用了这个 JSONParser 类的更新版本,并提供了如何将它与显示 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 类的更新版本,它使用 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;
        }
    }
    

    【讨论】:

    • 我尝试了合并 PostAsync 类,但我又一次无意地复制并粘贴了我已经修改它以满足我的需要的代码。如果您查看问题的更新。但是我如何在我的主要活动中调用 JSON 响应?
    • @PaulLedger 如果您将 AsyncTask 设为单独的类而不是 Activity 的内部类,则常见的实现是使用接口与 Activity 进行通信。看看这个答案:stackoverflow.com/questions/9963691/…
    • 谢谢丹尼尔,这非常有帮助并且解释得很好。
    【解决方案2】:

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

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

    查看Android开发者网站中的this教程和我做过的this教程和these幻灯片

    【讨论】:

    • Android 开发者网站上提供的信息非常多,起初令人困惑,但确实让事情变得更加清晰。
    【解决方案3】:

    您可以在 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;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2012-07-27
      • 1970-01-01
      • 2016-04-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-27
      • 1970-01-01
      相关资源
      最近更新 更多