如何使用ProgressDialog显示JSON解析进度?
How to use ProgressDialog to show JSON parsing progress?
我想用进度条显示一些 JSON 解析的进度。我从来没有使用过它并在互联网上找到了一些例子。因此,我尝试实现它,但在解析开始时应用程序崩溃了。这是代码:
public class Parser extends Activity {
public static String w_type1 = "news";
public static String w_type2 = "events_put";
public ListView lv;
ArrayList<Widget> data = new ArrayList<Widget>();
WidgetAdapter wid_adptr = new WidgetAdapter(this, data);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_parser);
lv = (ListView) this.findViewById(R.id.list);
lv.setAdapter(wid_adptr);
new ParseTask().execute();
}
private class ParseTask extends AsyncTask<Void, Void, String> {
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
String resultJson = "";
public ProgressDialog dialog;
Context ctx;
protected void onPreExecute() {
dialog = new ProgressDialog(ctx);
dialog.setMessage("Pasring...");
dialog.setIndeterminate(true);
dialog.setCancelable(true);
dialog.show();
}
@Override
protected String doInBackground(Void... params) {
try {
URL url = new URL("http://api.pandem.pro/healthcheck/w/");
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
InputStream inputStream = urlConnection.getInputStream();
StringBuffer buffer = new StringBuffer();
reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
buffer.append(line);
}
resultJson = buffer.toString();
} catch (Exception e) {
e.printStackTrace();
}
return resultJson;
}
@Override
protected void onPostExecute(String strJson) {
super.onPostExecute(strJson);
JSONObject dataJsonObj = null;
try {
dataJsonObj = new JSONObject(strJson);
JSONArray widgets = dataJsonObj.getJSONArray("widgets");
for (int i = 0; i < widgets.length(); i++) {
JSONObject widget = widgets.getJSONObject(i);
String wType = widget.getString("type");
if (wType.equals(w_type1) || wType.equals(w_type2)) {
String title = widget.getString("title");
String desc = widget.getString("desc");
String img_url = "";
if (widget.has("img")) {
JSONObject img = widget.getJSONObject("img");
img_url = img.getString("url");
}
data.add(new Widget(wType, title, desc, img_url));
//wid_adptr.notifyDataSetChanged();
}
}
} catch (JSONException e) {
e.printStackTrace();
}
dialog.dismiss();
}
}
}
如果我不使用 ProgressDialog(只是注释或删除对话框代码)应用程序可以正常工作。我该如何解决?
没有任何 logcat 很难提供帮助,但您的 ctx
似乎是空的,所以
dialog = new ProgressDialog(ctx);
无法创建对话框。
尝试将构造函数添加到 AsyncTask
并在此处传递上下文,例如:
private class ParseTask extends AsyncTask<Void, Void, String> {
...
public ParseTask(Context ctx) {
this.ctx = ctx;
}
...
}
开始任务:
new ParseTask(this).execute();
嗯,我想这可以用更简单和现代的方式完成。
- 使用 GSON 解析你的 JSON
- 考虑使用 Retrofit for REST
现在一步步来:
将依赖项添加到您的 gradle 文件:
compile "com.squareup.retrofit2:retrofit:$retrofitVersion"
compile "com.squareup.retrofit2:converter-gson:$retrofitVersion"
这会让你使用改造库
2.创建改造serverAPI接口
public interface InternalServerAPI {
@GET("users/statistics")
Call<Example> healthcheckEndPoint(Params... params);
}
创建一个对应于你的JSON对象(POJO)。你可以在线使用这个 http://www.jsonschema2pojo.org。例如你有这样的JSON:
{
"date":"1234343555",
"widgets": [
{
"title":"title1",
"desc":"desc1"
},
{
"title":"title2",
"desc":"desc2"
},
...
]
}
您将获得两个模型 类,如下所示:
public class Example {
@SerializedName("date")
@Expose
private String date;
@SerializedName("widgets")
@Expose
private List<Widget> widgets = new ArrayList<Widget>();
/**
*
* @return
* The date
*/
public String getDate() {
return date;
}
/**
*
* @param date
* The date
*/
public void setDate(String date) {
this.date = date;
}
/**
*
* @return
* The widgets
*/
public List<Widget> getWidgets() {
return widgets;
}
/**
*
* @param widgets
* The widgets
*/
public void setWidgets(List<Widget> widgets) {
this.widgets = widgets;
}
}
-----------------------------------com.example.Widget.java-----------------------------------
package com.example;
import javax.annotation.Generated;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
@Generated("org.jsonschema2pojo")
public class Widget {
@SerializedName("title")
@Expose
private String title;
@SerializedName("desc")
@Expose
private String desc;
/**
*
* @return
* The title
*/
public String getTitle() {
return title;
}
/**
*
* @param title
* The title
*/
public void setTitle(String title) {
this.title = title;
}
/**
*
* @return
* The desc
*/
public String getDesc() {
return desc;
}
/**
*
* @param desc
* The desc
*/
public void setDesc(String desc) {
this.desc = desc;
}
}
现在构建改造对象:
Retrofit mRetrofit = new Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(Constants.BASE_INTERNAL_SERVER_ADDRESS)
.build();
并参考相应的端点,但首先调用您的进度对话框:
dialog = new ProgressDialog(Parser.this);
dialog.setMessage("Pasring...");
dialog.setIndeterminate(true);
dialog.setCancelable(true);
dialog.show();
Call<Example> fetchWidgets = mRetrofit.create(InternalServerAPI.class).healthcheckEndPoint(Params);
fetchWidgets.enqueue(new Callback<Example>() {
@Override
public void onResponse(Call<Example> call, Response<Example> response) {
//here response is your model object and U can refer to its fields
ArrayList<Widget> data = response.getWidgets();
...
//update adapter
...
//and now U can dismiss your dialog
dialog.dismiss();
}
@Override
public void onFailure(Call<Example> call, Throwable t) {
//here U can handle connection errors
//and also dismiss dialog
dialog.dismiss();
}
});
当然,所有这些都应该以某种 MVP 方式完成,但现在不是主题。
我想用进度条显示一些 JSON 解析的进度。我从来没有使用过它并在互联网上找到了一些例子。因此,我尝试实现它,但在解析开始时应用程序崩溃了。这是代码:
public class Parser extends Activity {
public static String w_type1 = "news";
public static String w_type2 = "events_put";
public ListView lv;
ArrayList<Widget> data = new ArrayList<Widget>();
WidgetAdapter wid_adptr = new WidgetAdapter(this, data);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_parser);
lv = (ListView) this.findViewById(R.id.list);
lv.setAdapter(wid_adptr);
new ParseTask().execute();
}
private class ParseTask extends AsyncTask<Void, Void, String> {
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
String resultJson = "";
public ProgressDialog dialog;
Context ctx;
protected void onPreExecute() {
dialog = new ProgressDialog(ctx);
dialog.setMessage("Pasring...");
dialog.setIndeterminate(true);
dialog.setCancelable(true);
dialog.show();
}
@Override
protected String doInBackground(Void... params) {
try {
URL url = new URL("http://api.pandem.pro/healthcheck/w/");
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
InputStream inputStream = urlConnection.getInputStream();
StringBuffer buffer = new StringBuffer();
reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
buffer.append(line);
}
resultJson = buffer.toString();
} catch (Exception e) {
e.printStackTrace();
}
return resultJson;
}
@Override
protected void onPostExecute(String strJson) {
super.onPostExecute(strJson);
JSONObject dataJsonObj = null;
try {
dataJsonObj = new JSONObject(strJson);
JSONArray widgets = dataJsonObj.getJSONArray("widgets");
for (int i = 0; i < widgets.length(); i++) {
JSONObject widget = widgets.getJSONObject(i);
String wType = widget.getString("type");
if (wType.equals(w_type1) || wType.equals(w_type2)) {
String title = widget.getString("title");
String desc = widget.getString("desc");
String img_url = "";
if (widget.has("img")) {
JSONObject img = widget.getJSONObject("img");
img_url = img.getString("url");
}
data.add(new Widget(wType, title, desc, img_url));
//wid_adptr.notifyDataSetChanged();
}
}
} catch (JSONException e) {
e.printStackTrace();
}
dialog.dismiss();
}
}
}
如果我不使用 ProgressDialog(只是注释或删除对话框代码)应用程序可以正常工作。我该如何解决?
没有任何 logcat 很难提供帮助,但您的 ctx
似乎是空的,所以
dialog = new ProgressDialog(ctx);
无法创建对话框。
尝试将构造函数添加到 AsyncTask
并在此处传递上下文,例如:
private class ParseTask extends AsyncTask<Void, Void, String> {
...
public ParseTask(Context ctx) {
this.ctx = ctx;
}
...
}
开始任务:
new ParseTask(this).execute();
嗯,我想这可以用更简单和现代的方式完成。
- 使用 GSON 解析你的 JSON
- 考虑使用 Retrofit for REST
现在一步步来:
将依赖项添加到您的 gradle 文件:
compile "com.squareup.retrofit2:retrofit:$retrofitVersion" compile "com.squareup.retrofit2:converter-gson:$retrofitVersion"
这会让你使用改造库 2.创建改造serverAPI接口
public interface InternalServerAPI {
@GET("users/statistics")
Call<Example> healthcheckEndPoint(Params... params);
}
创建一个对应于你的JSON对象(POJO)。你可以在线使用这个 http://www.jsonschema2pojo.org。例如你有这样的JSON:
{ "date":"1234343555", "widgets": [ { "title":"title1", "desc":"desc1" }, { "title":"title2", "desc":"desc2" }, ... ]
}
您将获得两个模型 类,如下所示:
public class Example {
@SerializedName("date")
@Expose
private String date;
@SerializedName("widgets")
@Expose
private List<Widget> widgets = new ArrayList<Widget>();
/**
*
* @return
* The date
*/
public String getDate() {
return date;
}
/**
*
* @param date
* The date
*/
public void setDate(String date) {
this.date = date;
}
/**
*
* @return
* The widgets
*/
public List<Widget> getWidgets() {
return widgets;
}
/**
*
* @param widgets
* The widgets
*/
public void setWidgets(List<Widget> widgets) {
this.widgets = widgets;
}
}
-----------------------------------com.example.Widget.java-----------------------------------
package com.example;
import javax.annotation.Generated;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
@Generated("org.jsonschema2pojo")
public class Widget {
@SerializedName("title")
@Expose
private String title;
@SerializedName("desc")
@Expose
private String desc;
/**
*
* @return
* The title
*/
public String getTitle() {
return title;
}
/**
*
* @param title
* The title
*/
public void setTitle(String title) {
this.title = title;
}
/**
*
* @return
* The desc
*/
public String getDesc() {
return desc;
}
/**
*
* @param desc
* The desc
*/
public void setDesc(String desc) {
this.desc = desc;
}
}
现在构建改造对象:
Retrofit mRetrofit = new Retrofit.Builder() .addConverterFactory(GsonConverterFactory.create()) .baseUrl(Constants.BASE_INTERNAL_SERVER_ADDRESS) .build();
并参考相应的端点,但首先调用您的进度对话框:
dialog = new ProgressDialog(Parser.this); dialog.setMessage("Pasring..."); dialog.setIndeterminate(true); dialog.setCancelable(true); dialog.show(); Call<Example> fetchWidgets = mRetrofit.create(InternalServerAPI.class).healthcheckEndPoint(Params); fetchWidgets.enqueue(new Callback<Example>() { @Override public void onResponse(Call<Example> call, Response<Example> response) { //here response is your model object and U can refer to its fields ArrayList<Widget> data = response.getWidgets(); ... //update adapter ... //and now U can dismiss your dialog dialog.dismiss(); } @Override public void onFailure(Call<Example> call, Throwable t) { //here U can handle connection errors //and also dismiss dialog dialog.dismiss(); } });
当然,所有这些都应该以某种 MVP 方式完成,但现在不是主题。