ProgressDialog不会出现在AsyncTask中

时间:2013-11-06 13:26:08

标签: android android-asynctask progressdialog

我正在创建一个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。对不起,如果我的英语不是那么好,我不是母语人士。

3 个答案:

答案 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;

希望有所帮助:)