我正在创建一个Android应用程序,它取决于应用程序从数据库获取的数据。为了获得这些数据,我有以下类(这个类从json中的数据库获取数据,翻译并返回它):
public class Json {
public String jsonResult;
private Activity activity;
private String url = "http://json.example.org/json.php";
private String db, query;
public Json(Activity activity) {
this.activity = activity;
}
public String accessWebService(String db, String query) {
JsonReadTask task = new JsonReadTask();
this.db = db;
this.query = query;
task.execute(new String[] { url });
try {
task.get();
} catch (InterruptedException e) {
Toast.makeText(activity.getApplicationContext(),
"FATAL ERROR: The thread got interrupted", Toast.LENGTH_LONG).show();
} catch (ExecutionException e) {
Toast.makeText(activity.getApplicationContext(),
"FATAL ERROR: The thread wasn't able to execute", Toast.LENGTH_LONG).show();
}
return jsonResult;
}
// Async Task to access the web
private class JsonReadTask extends AsyncTask<String, Void, String> {
private final ProgressDialog dialog = new ProgressDialog(activity);
protected String doInBackground(String... params) {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(params[0]);
try {
// add post data
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("db", db));
nameValuePairs.add(new BasicNameValuePair("query", query));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
jsonResult = inputStreamToString(response.getEntity().getContent()).toString();
if (jsonResult.isEmpty()) {
Toast.makeText(activity.getApplicationContext(),
"Error, connection is up but didn't receive data. That's strange...",
Toast.LENGTH_LONG).show();
this.cancel(true);
}
} catch (ClientProtocolException e) {
//Toast.makeText(activity.getApplicationContext(),
// "Error, Client Protocol Exception in JSON task",
// Toast.LENGTH_LONG).show();
Log.i("Json", "Error, Client Protocol Exception in JSON task");
this.cancel(true);
} catch (IOException e) {
//Toast.makeText(activity.getApplicationContext(),
// "Error, Please check your internet connection",
// Toast.LENGTH_LONG).show();
Log.i("Json", "Error, Please check your internet connection");
this.cancel(true);
}
return null;
}
private StringBuilder inputStreamToString(InputStream is) {
String rLine = "";
StringBuilder answer = new StringBuilder();
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
try {
while ((rLine = rd.readLine()) != null) {
answer.append(rLine);
}
} catch (IOException e) {
Toast.makeText(activity.getApplicationContext(), "Error..." + e.toString(),
Toast.LENGTH_LONG).show();
}
return answer;
}
}
}// end async task
}
我注意到我的应用在访问数据库时冻结了。经过一些谷歌搜索后,我发现它是由accessWebService()方法中的.get()方法引起的。我试图像这样实现progressDialog(我也删除了.get()方法):
private final ProgressDialog dialog = new ProgressDialog(activity);
protected void onPreExecute() {
super.onPreExecute();
this.dialog.setMessage("Loading...");
this.dialog.setCancelable(false);
this.dialog.show();
}
protected void onPostExecute(String result) {
if (this.dialog.isShowing()) {
this.dialog.dismiss();
}
}
但对话框没有显示,我得到了NullPointerExceptions,因为应用程序仅在有数据时才有效:
result = json.accessWebService(db, query);
(也许一件重要的事情要提到:我也可以在forloops中使用这个方法)
所以现在我的问题是:我如何更改我的应用程序,以便在访问数据库时获得ProgressDialog并且无需获取NullPointerExceptions?我担心我必须重新构建我的整个应用程序,如果我必须这样做,我该怎么做?我希望你们理解我的问题并解决这个问题,因为我真的需要帮助。提前谢谢。
P.S。对不起,如果我的英语不是那么好,我不是母语人士。
答案 0 :(得分:3)
...我发现它是accessWebService()方法中的.get()方法引起的。我试图实现progressDialog ...
这是对的。 get()
是阻止通话,只是添加ProgressDialog
无法解决问题。您需要删除.get()
,这可能会解决您的ProgressDialog
未显示的问题。
必须在主AsyncTask
上执行Thread
,因此请确保您这样做。
您遇到的另一个问题是Toast.LENGTH_LONG).show();
UI
会在doInBackground()
上运行,而result
则无法实现。您需要将onPostExecute()
发送到Toast
,如果需要,您可以在那里显示onProgressUpdate()
。这也可以在{{1}}中完成。
答案 1 :(得分:0)
由于result
值为null,因此发生此空指针异常。把条件放在
if(result != null ) {
// CODE FOR PARSING
} else {
return;
}
答案 2 :(得分:0)
您可以在启动asyncTask之前开始显示进度条,并在asyncTask完成时完成显示。
将处理程序传递给asyncTask和sendMessage onPostExecute方法。然后处理UI线程上的消息并隐藏进度条
例如,UI(mainActivity)中有处理程序字段。你应该处理隐藏进度条:
public Handler refreshChannelsHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case EPGManager.ERROR_MESSAGE:
//do some stuff
break;
case EPGManager.SUCCESS_MESSAGE:
//do some stuff
break;
}
super.handleMessage(msg);
}
};
然后你可以用你的处理程序调用asyncTask
epgManager.loadChannels(refreshChannelsHandler);
AsyncTask在方法内部,所以看起来像这样:
public void loadChannels(Handler handler) {
AsyncTask task = new AsyncTask() {
@Override
protected Object doInBackground(Object[] params) {
try {
//do AsyncTask Job
} catch (Exception e) {
return new LoadingResult((Handler) params[0], false);
}
return new LoadingResult((Handler) params[0], false);
}
@Override
protected void onPostExecute(Object o) {
super.onPostExecute(o);
LoadingResult loadingResult = ((LoadingResult)o);
sendMessageToHandler(loadingResult.handler, loadingResult.isSuccess);
}
};
task.execute(handler);
}
这是方法:
private void sendMessageToHandler(Handler handler, boolean isSuccess) {
handler.sendEmptyMessage(isSuccess ? SUCCESS_MESSAGE : ERROR_MESSAGE);
}
最后是内部课
private class LoadingResult {
private Handler handler;
private boolean isSuccess;
public LoadingResult(Handler handler, boolean isSuccess) {
this.handler = handler;
this.isSuccess = isSuccess;
}
public Handler getHandler() {
return handler;
}
public void setHandler(Handler handler) {
this.handler = handler;
}
public boolean isSuccess() {
return isSuccess;
}
public void setSuccess(boolean isSuccess) {
this.isSuccess = isSuccess;
}
}
Ow,不要忘记常数
public static final int SUCCESS_MESSAGE = 1;
public static final int ERROR_MESSAGE = -1;
希望有所帮助:)