为 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;
}
}
我有一个 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;
}
}