将progressDialog添加到JSON Parser类并返回MainActivity的方法

我有一个JSONparser类来获取和发送数据到服务器工作正常,但在没有wifi连接测试这个过程需要更长的时间。 是否可以将进程Dialog放入我的类中,因为我将这个类称为每个需要发送或接收数据的活动。

我尝试了一些不同的事情,例如在任务之前和之后应用设置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 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; } } 

说实话,我没有写完所有课程,我按照教程修改了课程,以满足我的需求。

可以在任何活动中调用该类,这就是类的想法:

 List params = new ArrayList(); 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类中的返回。

例如:New PostAcync.execute(param,param)将调用基本的PostAcync类; 但我已对此进行了修改,以便它具有普遍性,可以用于任何活动; 所以没有,我会调用这个类并通过以下方式执行任务:

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

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

有没有办法我可以添加一个回调到这样的东西

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

我实际上最近写了一篇博客文章,其中包含此JSONParser类的更新版本,以及如何将其与显示ProgressDialog的AsyncTask一起使用的示例。

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

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

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

按如下方式定义AsyncTask,其中包括ProgressDialog:

 class PostAsync extends AsyncTask { 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 params = new ArrayList(); 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 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; } } 

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

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

在Android开发人员网站和本教程中查看本教程以及这些幻灯片

您可以在AsyncTask中解析JSON并在开始解析之前显示Dialog,并在作业完成时使其消失。

 public class JSONParseAsyncTask extends AsyncTask { 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; } }