Java 异步任务错误

Java 异步任务错误,java,android,android-fragments,Java,Android,Android Fragments,我有一个包含异步任务的片段: class GetPharmacieDetails extends AsyncTask<String, String, String> { /** * Before starting background thread Show Progress Dialog * */ @Override protected void onPreExecute() {

我有一个包含异步任务的片段:

class GetPharmacieDetails extends AsyncTask<String, String, String> {
        /**
         * Before starting background thread Show Progress Dialog
         * */
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            pDialog = new ProgressDialog(getActivity());
            pDialog.setMessage("Chargement. Patienter ...");
            pDialog.setIndeterminate(false);
            pDialog.setCancelable(true);
            pDialog.show();
        }
        /**
         * Getting product details in background thread
         * */
        @Override
        protected String doInBackground(String... args) {
            // TODO Auto-generated method stub
            int success;
            try {
                // Building Parameters
                List<NameValuePair> params = new ArrayList<NameValuePair>();
                params.add(new BasicNameValuePair("latitude", pid));
                // getting product details by making HTTP request
                // Note that product details url will use GET request
                JSONObject json = jsonParser.makeHttpRequest(
                        url_product_detials, "GET", params);

                // check your log for json response
                Log.d("Single Product Details", json.toString());

                // json success tag
                success = json.getInt(TAG_SUCCESS);
                if (success == 1) {
                    // successfully received product details
                    JSONArray productObj = json
                            .getJSONArray(TAG_PRODUCT); // JSON Array

                    // get first product object from JSON Array
                    JSONObject product = productObj.getJSONObject(0);



                    txtName.setText(product.getString(TAG_NAME));
                    txtRegion.setText(product.getString(TAG_REGION));

                    txtAddress.setText(product.getString(TAG_ADDRESS));
                    lati = product.getString(TAG_LATITUDE);
                    longi = product.getString(TAG_LANGITUDE);
                }else{
                    // product with pid not found
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
        return null;

        }

        /**
         * After completing background task Dismiss the progress dialog
         * **/
        protected void onPostExecute(String file_url) {
            // dismiss the dialog once got all details
            if(pDialog != null){
                pDialog.dismiss();
            }

        }
    }
我认为问题就在这里:

txtName.setText(product.getString(TAG_NAME));
txtRegion.setText(product.getString(TAG_REGION));
txtAddress.setText(product.getString(TAG_ADDRESS));
lati = product.getString(TAG_LATITUDE);
longi = product.getString(TAG_LANGITUDE);

您正在更新doInBackground()中的UI。该方法在与GUI线程不同步的后台线程上运行,因此会产生CalledFromErrorThreadException

一个选项是使用runOnUiThread()方法在GUI线程上计划UI更新。请注意,此方法属于活动,因此您需要通过引用片段的父级来使用它:

getActivity().runOnUiThread(new Runnable() {
    @Override
    public void run() {
        txtName.setText(product.getString(TAG_NAME));
        txtRegion.setText(product.getString(TAG_REGION));
        txtAddress.setText(product.getString(TAG_ADDRESS));
    }
});
但是,使用AsyncTask的正确方法是在onPostExecute()中执行任何UI更新,该更新与GUI线程同步。要这样做,请将AsyncTask定义中的第3个参数更改为JSONObject(这是您将从doInBackground返回的类型,然后传递到onPostExecute):

…并且不再更新doInBackground中的UI。相反,返回对“产品”的引用:

...
if (success == 1) {
    JSONArray productObj = json.getJSONArray(TAG_PRODUCT);
    JSONObject product = productObj.getJSONObject(0);

    //txtName.setText(product.getString(TAG_NAME));
    //txtRegion.setText(product.getString(TAG_REGION));
    //txtAddress.setText(product.getString(TAG_ADDRESS));

    lati = product.getString(TAG_LATITUDE);
    longi = product.getString(TAG_LANGITUDE);
    return product;
}else{
...
更改onPostExecute以接收JSONObject并在此处更新UI,前提是doInBackground提供的引用不为null:

protected void onPostExecute(JSONObject product) {
    if (product != null) {
        txtName.setText(product.getString(TAG_NAME));
        txtRegion.setText(product.getString(TAG_REGION));
        txtAddress.setText(product.getString(TAG_ADDRESS));
    }

    // dismiss the dialog once got all details
    if(pDialog != null){
        pDialog.dismiss();
    }
}

您无法从另一个线程更新UI线程(主线程),这会在内部导致许多错误,请尝试将
产品
变量设置为本地变量,然后在
onPostExecute
中将文本设置为
文本视图

class GetPharmacieDetails extends AsyncTask<String, String, String> {
    /**
     * Before starting background thread Show Progress Dialog
     * */
    private JSONObject product;

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        pDialog = new ProgressDialog(getActivity());
        pDialog.setMessage("Chargement. Patienter ...");
        pDialog.setIndeterminate(false);
        pDialog.setCancelable(true);
        pDialog.show();
    }
    /**
     * Getting product details in background thread
     * */
    @Override
    protected String doInBackground(String... args) {
        // TODO Auto-generated method stub
        int success;
        try {
            // Building Parameters
            List<NameValuePair> params = new ArrayList<NameValuePair>();
            params.add(new BasicNameValuePair("latitude", pid));
            // getting product details by making HTTP request
            // Note that product details url will use GET request
            JSONObject json = jsonParser.makeHttpRequest(
                    url_product_detials, "GET", params);

            // check your log for json response
            Log.d("Single Product Details", json.toString());

            // json success tag
            success = json.getInt(TAG_SUCCESS);
            if (success == 1) {
                // successfully received product details
                JSONArray productObj = json
                        .getJSONArray(TAG_PRODUCT); // JSON Array

                // get first product object from JSON Array
                product = productObj.getJSONObject(0);
            }else{
                // product with pid not found
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
    return null;

    }

    /**
     * After completing background task Dismiss the progress dialog
     * **/
    protected void onPostExecute(String file_url) {
        // dismiss the dialog once got all details
        if(null!=product){
            txtName.setText(product.getString(TAG_NAME));
                txtRegion.setText(product.getString(TAG_REGION));
                txtAddress.setText(product.getString(TAG_ADDRESS));
                lati = product.getString(TAG_LATITUDE);
                longi = product.getString(TAG_LANGITUDE);
        }
        if(pDialog != null){
            pDialog.dismiss();
        }

    }
}
类getPharmaceAdetails扩展异步任务{
/**
*在启动后台线程显示进度对话框之前
* */
私有JSONObject产品;
@凌驾
受保护的void onPreExecute(){
super.onPreExecute();
pDialog=newprogressdialog(getActivity());
pDialog.setMessage(“Chargement.Patienter…”);
pDialog.setUndeterminate(假);
pDialog.setCancelable(真);
pDialog.show();
}
/**
*在后台线程中获取产品详细信息
* */
@凌驾
受保护的字符串doInBackground(字符串…args){
//TODO自动生成的方法存根
成功;
试一试{
//建筑参数
List params=new ArrayList();
参数添加(新的BasicNameValuePair(“纬度”,pid));
//通过发出HTTP请求获取产品详细信息
//请注意,产品详细信息url将使用GET请求
JSONObject json=jsonParser.makeHttpRequest(
url(产品详细信息,“获取”,参数);
//检查日志中的json响应
Log.d(“单一产品详细信息”,json.toString());
//json成功标记
success=json.getInt(TAG_success);
如果(成功==1){
//已成功接收产品详细信息
JSONArray productObj=json
.getJSONArray(TAG_PRODUCT);//JSON数组
//从JSON数组中获取第一个产品对象
product=productObj.getJSONObject(0);
}否则{
//找不到具有pid的产品
}
}捕获(JSONException e){
e、 printStackTrace();
}
返回null;
}
/**
*完成后台任务后,关闭“进度”对话框
* **/
受保护的void onPostExecute(字符串文件\u url){
//获得所有详细信息后关闭对话框
if(null!=产品){
setText(product.getString(TAG_NAME));
setText(product.getString(TAG_REGION));
setText(product.getString(TAG_地址));
lati=product.getString(标记纬度);
longi=product.getString(标签);
}
如果(pDialog!=null){
pDialog.disclose();
}
}
}
...
if (success == 1) {
    JSONArray productObj = json.getJSONArray(TAG_PRODUCT);
    JSONObject product = productObj.getJSONObject(0);

    //txtName.setText(product.getString(TAG_NAME));
    //txtRegion.setText(product.getString(TAG_REGION));
    //txtAddress.setText(product.getString(TAG_ADDRESS));

    lati = product.getString(TAG_LATITUDE);
    longi = product.getString(TAG_LANGITUDE);
    return product;
}else{
...
protected void onPostExecute(JSONObject product) {
    if (product != null) {
        txtName.setText(product.getString(TAG_NAME));
        txtRegion.setText(product.getString(TAG_REGION));
        txtAddress.setText(product.getString(TAG_ADDRESS));
    }

    // dismiss the dialog once got all details
    if(pDialog != null){
        pDialog.dismiss();
    }
}
class GetPharmacieDetails extends AsyncTask<String, String, String> {
    /**
     * Before starting background thread Show Progress Dialog
     * */
    private JSONObject product;

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        pDialog = new ProgressDialog(getActivity());
        pDialog.setMessage("Chargement. Patienter ...");
        pDialog.setIndeterminate(false);
        pDialog.setCancelable(true);
        pDialog.show();
    }
    /**
     * Getting product details in background thread
     * */
    @Override
    protected String doInBackground(String... args) {
        // TODO Auto-generated method stub
        int success;
        try {
            // Building Parameters
            List<NameValuePair> params = new ArrayList<NameValuePair>();
            params.add(new BasicNameValuePair("latitude", pid));
            // getting product details by making HTTP request
            // Note that product details url will use GET request
            JSONObject json = jsonParser.makeHttpRequest(
                    url_product_detials, "GET", params);

            // check your log for json response
            Log.d("Single Product Details", json.toString());

            // json success tag
            success = json.getInt(TAG_SUCCESS);
            if (success == 1) {
                // successfully received product details
                JSONArray productObj = json
                        .getJSONArray(TAG_PRODUCT); // JSON Array

                // get first product object from JSON Array
                product = productObj.getJSONObject(0);
            }else{
                // product with pid not found
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
    return null;

    }

    /**
     * After completing background task Dismiss the progress dialog
     * **/
    protected void onPostExecute(String file_url) {
        // dismiss the dialog once got all details
        if(null!=product){
            txtName.setText(product.getString(TAG_NAME));
                txtRegion.setText(product.getString(TAG_REGION));
                txtAddress.setText(product.getString(TAG_ADDRESS));
                lati = product.getString(TAG_LATITUDE);
                longi = product.getString(TAG_LANGITUDE);
        }
        if(pDialog != null){
            pDialog.dismiss();
        }

    }
}