我使用AsycTask从URL获取JSON,解析它并将数据显示在listView上。我还单击刷新按钮再次从URL获取JSON以进行一些更新。当我点击刷新按钮时,会发生以下情况; 1)adapter.clear():清除listView的适配器以填充新数据。 2)从url获取JSON,解析并将新获取的数据显示到listView上。 3)同时在获取数据时,我会显示一个进度对话框。
但是当我点击刷新按钮时,主UI线程在执行AsynTask期间冻结。我的意思是刷新按钮看起来按下,直到AsynTask完成作业,如下所示。
这是我的代码:
public class AndroidJSONParsingActivity extends SherlockActivity {
// JSON Node names
ArrayList<HashMap<String, String>> placeList = new ArrayList<HashMap<String, String>>();
private static final String TAG_PLACES = "places";
private static final String TAG_PLACE_NAME = "name";
private static final String TAG_PLACE_CATEGORY = "category";
private static final String TAG_PLACE_DISTANCE = "distance";
private static final String TAG_TRAVEL_TIME = "travel_time";
ListAdapter adapter;
public static Context con;
JSONArray places = null;
ListView list;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
con = this;
list = (ListView) findViewById(R.id.listView1);
parseJSON();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getSupportMenuInflater();
inflater.inflate(R.menu.activity_main, menu);
MenuItem menu_item1 = menu.findItem(R.id.menu_item1);
menu_item1.setOnMenuItemClickListener(new OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
Toast.makeText(getApplicationContext(), "refresh",
Toast.LENGTH_LONG).show();
placeList.clear();
parseJSON();
return false;
}
});
return true;
}
public void parseJSON() {
try {
placeList = new JSONParsingTask().execute().get();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
adapter = new SimpleAdapter(this, placeList, R.layout.list_item,
new String[] { TAG_PLACE_NAME, TAG_PLACE_CATEGORY,
TAG_PLACE_DISTANCE, TAG_TRAVEL_TIME }, new int[] {
R.id.name, R.id.category, R.id.distance,
R.id.travel_time });
list.setAdapter(adapter);
list.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
String name = ((TextView) view.findViewById(R.id.name))
.getText().toString();
String category = ((TextView) view.findViewById(R.id.category))
.getText().toString();
String distance = ((TextView) view.findViewById(R.id.distance))
.getText().toString();
String travel_time = ((TextView) view
.findViewById(R.id.travel_time)).getText().toString();
Intent in = new Intent(getApplicationContext(),
SingleMenuItemActivity.class);
in.putExtra(TAG_PLACE_NAME, name);
in.putExtra(TAG_PLACE_CATEGORY, category);
in.putExtra(TAG_PLACE_DISTANCE, distance);
in.putExtra(TAG_TRAVEL_TIME, travel_time);
startActivity(in);
}
});
}
}
class JSONParsingTask extends
AsyncTask<Void, Void, ArrayList<HashMap<String, String>>> {
public Boolean flag = false;
private static String url = "http://some - url";
// JSON Node names
private static final String TAG_PLACES = "places";
private static final String TAG_PLACE_NAME = "name";
private static final String TAG_PLACE_CATEGORY = "category";
private static final String TAG_PLACE_DISTANCE = "distance";
private static final String TAG_TRAVEL_TIME = "travel_time";
ListAdapter adapter;
JSONParser jParser;
ListView list;
static ArrayList<HashMap<String, String>> placeList = new ArrayList<HashMap<String, String>>();
JSONArray places = null;
ProgressDialog JSONParsingDialog = new ProgressDialog(
AndroidJSONParsingActivity.con);
@Override
protected void onPreExecute() {
JSONParsingDialog.setMessage("Preparing data...");
JSONParsingDialog.setCanceledOnTouchOutside(false);
JSONParsingDialog.setCancelable(false);
JSONParsingDialog.show();
}
@Override
protected ArrayList<HashMap<String, String>> doInBackground(Void... params) {
JSONParser jParser = new JSONParser();
final JSONObject json = jParser.getJSONFromUrl(url);
try {
places = json.getJSONArray(TAG_PLACES);
for (int i = 0; i < places.length(); i++) {
JSONObject c = places.getJSONObject(i);
String name = c.getString(TAG_PLACE_NAME);
String category = c.getString(TAG_PLACE_CATEGORY);
String distance = c.getString(TAG_PLACE_DISTANCE);
String travel_time = c.getString(TAG_TRAVEL_TIME);
HashMap<String, String> map = new HashMap<String, String>();
map.put(TAG_PLACE_NAME, name);
map.put(TAG_PLACE_CATEGORY, category);
map.put(TAG_PLACE_DISTANCE, distance);
map.put(TAG_TRAVEL_TIME, travel_time);
placeList.add(map);
}
} catch (JSONException e) {
e.printStackTrace();
}
return placeList;
}
@Override
protected void onPostExecute(ArrayList<HashMap<String, String>> result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
JSONParsingDialog.dismiss();
}
}
我需要的是,当我点击刷新按钮时,它应该是平滑的,并且在AsynTask完成之前不应该冻结。知道我该怎么办?
答案 0 :(得分:4)
使用
new JSONParsingTask().execute();
.get()会阻止调用者线程。
更多信息:Looking for good example of using get() with an AsyncTask in android
答案 1 :(得分:2)
试试这样:
public class AndroidJSONParsingActivity extends SherlockActivity {
// JSON Node names
ArrayList<HashMap<String, String>> placeList = new ArrayList<HashMap<String, String>>();
private static final String TAG_PLACES = "places";
private static final String TAG_PLACE_NAME = "name";
private static final String TAG_PLACE_CATEGORY = "category";
private static final String TAG_PLACE_DISTANCE = "distance";
private static final String TAG_TRAVEL_TIME = "travel_time";
ListAdapter adapter;
public static Context con;
JSONArray places = null;
ListView list;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
con = this;
list = (ListView) findViewById(R.id.listView1);
fetchJSON();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getSupportMenuInflater();
inflater.inflate(R.menu.activity_main, menu);
MenuItem menu_item1 = menu.findItem(R.id.menu_item1);
menu_item1.setOnMenuItemClickListener(new OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
Toast.makeText(getApplicationContext(), "refresh",
Toast.LENGTH_LONG).show();
placeList.clear();
parseJSON();
return false;
}
});
return true;
}
public void fecthJson(){
new JSONParsingTask().execute();
}
public void parseJSON(ArrayList<Hashmap<String, String>> dataList) {
adapter = new SimpleAdapter(this, dataList, R.layout.list_item,
new String[] { TAG_PLACE_NAME, TAG_PLACE_CATEGORY,
TAG_PLACE_DISTANCE, TAG_TRAVEL_TIME }, new int[] {
R.id.name, R.id.category, R.id.distance,
R.id.travel_time });
list.setAdapter(adapter);
list.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
String name = ((TextView) view.findViewById(R.id.name))
.getText().toString();
String category = ((TextView) view.findViewById(R.id.category))
.getText().toString();
String distance = ((TextView) view.findViewById(R.id.distance))
.getText().toString();
String travel_time = ((TextView) view
.findViewById(R.id.travel_time)).getText().toString();
Intent in = new Intent(getApplicationContext(),
SingleMenuItemActivity.class);
in.putExtra(TAG_PLACE_NAME, name);
in.putExtra(TAG_PLACE_CATEGORY, category);
in.putExtra(TAG_PLACE_DISTANCE, distance);
in.putExtra(TAG_TRAVEL_TIME, travel_time);
startActivity(in);
}
});
}
}
class JSONParsingTask extends
AsyncTask<Void, Void, ArrayList<HashMap<String, String>>> {
public Boolean flag = false;
private static String url = "http://some - url";
// JSON Node names
private static final String TAG_PLACES = "places";
private static final String TAG_PLACE_NAME = "name";
private static final String TAG_PLACE_CATEGORY = "category";
private static final String TAG_PLACE_DISTANCE = "distance";
private static final String TAG_TRAVEL_TIME = "travel_time";
ListAdapter adapter;
JSONParser jParser;
ListView list;
static ArrayList<HashMap<String, String>> placeList = new ArrayList<HashMap<String, String>>();
JSONArray places = null;
ProgressDialog JSONParsingDialog = new ProgressDialog(
AndroidJSONParsingActivity.con);
@Override
protected void onPreExecute() {
JSONParsingDialog.setMessage("Preparing data...");
JSONParsingDialog.setCanceledOnTouchOutside(false);
JSONParsingDialog.setCancelable(false);
JSONParsingDialog.show();
}
@Override
protected ArrayList<HashMap<String, String>> doInBackground(Void... params) {
JSONParser jParser = new JSONParser();
final JSONObject json = jParser.getJSONFromUrl(url);
try {
places = json.getJSONArray(TAG_PLACES);
for (int i = 0; i < places.length(); i++) {
JSONObject c = places.getJSONObject(i);
String name = c.getString(TAG_PLACE_NAME);
String category = c.getString(TAG_PLACE_CATEGORY);
String distance = c.getString(TAG_PLACE_DISTANCE);
String travel_time = c.getString(TAG_TRAVEL_TIME);
HashMap<String, String> map = new HashMap<String, String>();
map.put(TAG_PLACE_NAME, name);
map.put(TAG_PLACE_CATEGORY, category);
map.put(TAG_PLACE_DISTANCE, distance);
map.put(TAG_TRAVEL_TIME, travel_time);
placeList.add(map);
}
} catch (JSONException e) {
e.printStackTrace();
}
return placeList;
}
@Override
protected void onPostExecute(ArrayList<HashMap<String, String>> result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
JSONParsingDialog.dismiss();
placeList = result;
parseJson(result);
}
}