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();
}
}
}