Android 如何在执行异步任务时不影响UI?
我有一个问题,这不是那么大,但对用户来说是坏的。 该应用程序基本上获取用户对某个位置的输入,当用户单击按钮时,一个指向Google API的URL及其参数上的位置被发送到一个AsyncTask,在那里它通过HttpGet发送该URL,并返回一个JSONArray,其中包含所需的所有内容。问题是,当我点击按钮时,互联网不太好,按钮似乎冻结如下: 我的活动代码如下:Android 如何在执行异步任务时不影响UI?,android,url,user-interface,android-asynctask,google-api,Android,Url,User Interface,Android Asynctask,Google Api,我有一个问题,这不是那么大,但对用户来说是坏的。 该应用程序基本上获取用户对某个位置的输入,当用户单击按钮时,一个指向Google API的URL及其参数上的位置被发送到一个AsyncTask,在那里它通过HttpGet发送该URL,并返回一个JSONArray,其中包含所需的所有内容。问题是,当我点击按钮时,互联网不太好,按钮似乎冻结如下: 我的活动代码如下: public class MainActivity extends Activity{ ... p
public class MainActivity extends Activity{
...
protected void onCreate(Bundle savedInstanceState){...}
public void onResume()}
btnSearch.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
String search = txtSearch.getText().toString();
try{
List<Location> locations = new SearchTask(MainActivity.this).execute(strSearch).get();
if(locations != null){
ArrayAdapter<Location> adapter = new ArrayAdapter<Location>(MainActivity.this, android.R.layout.simple_list_item_1, locations);
listView.setAdapter(adapter);
...
}
}
}
}
}
}
public class SearchTask extends AsyncTask<String, Void, List<Location>>{
...
protected List<Location> doInBackground(String... params){
if(isNetworkAvailable()){
HttpGet httpGet = null;
HttpClient client = null;
HttpResponse response = null;
StringBuilder builder = null;
try{
String param = URLDecoder.decode(params[0], "UTF-8").replace(" ", "%20");
httpGet = new HttpGet("http://maps.googleapis.com/maps/api/geocode/json?address=" + param + "&sensor=false");
client = new DefaultHttpClient();
builder = new StringBuilder();
}
catch(UnsupportedEncodingException e){
Log.i("Error", e.getMessage());
}
try{
response = client.execute(httpGet);
HttpEntity entity = response.getEntity();
InputStream stream = entity.getContent();
BufferedReader br = new BufferedReader(new InputStreamReader(stream, "UTF-8"));
int val;
while((val = br.read()) != -1){
builder.append((char) val);
}
}
catch(IOException e){
Log.i("Error", e.getMessage());
}
JSONObject jsonObject = new JSONObject();
List<Location> listLocation = new ArrayList<Location>();
int countJson = 0;
try{
jsonObject = new JSONObject(builder.toString());
JSONArray jArray = jsonObject.getJSONArray("results");
countJson = jArray.length();
for(int i = 0; i < countJson; i++){
Location location = new Location();
String formattedAddress = ((JSONArray) jsonObject.get("results")).getJSONObject(i).getString("formatted_address");
double lat = ((JSONArray) jsonObject.get("results")).getJSONObject(i).getJSONObject("geometry").getJSONObject("location").getDouble("lat");
double lng = ((JSONArray) jsonObject.get("results")).getJSONObject(i).getJSONObject("geometry").getJSONObject("location").getDouble("lng");
location.setFormattedAddress(formattedAddress);
location.setLat(lat);
location.setLng(lng);
listLocation.add(location);
}
}
catch(JSONException e){
Log.i("Error", e.getMessage());
}
return listLocation;
}
else{
return null;
}
}
@Override
protected void onPreExecute(){
super.onPreExecute();
progress = new ProgressDialog(context);
progress.setMessage("Loading...");
progress.show();
}
@Override
protected void onPostExecute(List<Location> result){
super.onPostExecute();
progress.dismiss();
}
private boolean isNetworkAvailable(){
ConnectivityManager connManager = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info = connManager.getActiveNetworkInfo();
return info != null && info.isConnected();
}
}
我的AsyncTask类代码如下:
public class MainActivity extends Activity{
...
protected void onCreate(Bundle savedInstanceState){...}
public void onResume()}
btnSearch.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
String search = txtSearch.getText().toString();
try{
List<Location> locations = new SearchTask(MainActivity.this).execute(strSearch).get();
if(locations != null){
ArrayAdapter<Location> adapter = new ArrayAdapter<Location>(MainActivity.this, android.R.layout.simple_list_item_1, locations);
listView.setAdapter(adapter);
...
}
}
}
}
}
}
public class SearchTask extends AsyncTask<String, Void, List<Location>>{
...
protected List<Location> doInBackground(String... params){
if(isNetworkAvailable()){
HttpGet httpGet = null;
HttpClient client = null;
HttpResponse response = null;
StringBuilder builder = null;
try{
String param = URLDecoder.decode(params[0], "UTF-8").replace(" ", "%20");
httpGet = new HttpGet("http://maps.googleapis.com/maps/api/geocode/json?address=" + param + "&sensor=false");
client = new DefaultHttpClient();
builder = new StringBuilder();
}
catch(UnsupportedEncodingException e){
Log.i("Error", e.getMessage());
}
try{
response = client.execute(httpGet);
HttpEntity entity = response.getEntity();
InputStream stream = entity.getContent();
BufferedReader br = new BufferedReader(new InputStreamReader(stream, "UTF-8"));
int val;
while((val = br.read()) != -1){
builder.append((char) val);
}
}
catch(IOException e){
Log.i("Error", e.getMessage());
}
JSONObject jsonObject = new JSONObject();
List<Location> listLocation = new ArrayList<Location>();
int countJson = 0;
try{
jsonObject = new JSONObject(builder.toString());
JSONArray jArray = jsonObject.getJSONArray("results");
countJson = jArray.length();
for(int i = 0; i < countJson; i++){
Location location = new Location();
String formattedAddress = ((JSONArray) jsonObject.get("results")).getJSONObject(i).getString("formatted_address");
double lat = ((JSONArray) jsonObject.get("results")).getJSONObject(i).getJSONObject("geometry").getJSONObject("location").getDouble("lat");
double lng = ((JSONArray) jsonObject.get("results")).getJSONObject(i).getJSONObject("geometry").getJSONObject("location").getDouble("lng");
location.setFormattedAddress(formattedAddress);
location.setLat(lat);
location.setLng(lng);
listLocation.add(location);
}
}
catch(JSONException e){
Log.i("Error", e.getMessage());
}
return listLocation;
}
else{
return null;
}
}
@Override
protected void onPreExecute(){
super.onPreExecute();
progress = new ProgressDialog(context);
progress.setMessage("Loading...");
progress.show();
}
@Override
protected void onPostExecute(List<Location> result){
super.onPostExecute();
progress.dismiss();
}
private boolean isNetworkAvailable(){
ConnectivityManager connManager = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info = connManager.getActiveNetworkInfo();
return info != null && info.isConnected();
}
}
ListView位于EditView和按钮的同一xml上
有没有一种方法可以改进它,使UI不会像这样运行
谢谢 试试这个:
btnSearch.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
String search = txtSearch.getText().toString();
new SearchTask(MainActivity.this).execute(strSearch);
}
}
@Override
protected void onPostExecute(List<Location> locations){
if(locations != null){
ArrayAdapter<Location> adapter = new ArrayAdapter<Location>(MainActivity.this, android.R.layout.simple_list_item_1, locations);
listView.setAdapter(adapter);
}
progress.dismiss();
}