Android 如何在执行异步任务时不影响UI?

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

我有一个问题,这不是那么大,但对用户来说是坏的。 该应用程序基本上获取用户对某个位置的输入,当用户单击按钮时,一个指向Google API的URL及其参数上的位置被发送到一个AsyncTask,在那里它通过HttpGet发送该URL,并返回一个JSONArray,其中包含所需的所有内容。问题是,当我点击按钮时,互联网不太好,按钮似乎冻结如下:

我的活动代码如下:

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