1

In my effort to get a simple address auto complete on android using geocoder, I tried to my patience and finally decided to ask out for help.

original code reference : Geocoder autocomplete in android

So in the below code, all that is happening is trying to auto complete the address as the user types in the autoCompleteTextView. I am calling the function doing the actual work in runOnUiThread,hoping that the UI would not freeze, as the user types in. However the UI freezes after the Threshold (3 characters) and the drop down of the possible addresses appear at it its own pace and not always.

If you guys can tell me where I am going wrong.... thanks in advance

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.location.Address;
import android.location.Geocoder;
import android.os.Bundle;
import android.os.Handler;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;

public class AlarmActivity extends Activity implements TextWatcher {
private static final int THRESHOLD = 3;
private String latitude, longitude;
private List<Address> autoCompleteSuggestionAddresses;
private ArrayAdapter<String> autoCompleteAdapter;



/** Called when the activity is first created. */
@Override
public void onCreate(Bundle icicle) {
    super.onCreate(icicle);
    setContentView(R.layout.hw);
    setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL);
    autoCompleteAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line, new ArrayList<String>());
    autoCompleteAdapter.setNotifyOnChange(false);
    AutoCompleteTextView locationinput = (AutoCompleteTextView) findViewById(R.id.locationInput);
    locationinput.addTextChangedListener(this);
    locationinput.setOnItemSelectedListener(this);
    locationinput.setThreshold(THRESHOLD);
    locationinput.setAdapter(autoCompleteAdapter);

}

@Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {

}

@Override
public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
final String value = arg0.toString();

if (!"".equals(value) && value.length() >= THRESHOLD) {

    Thread t = new Thread() {
        public void run() {
            try {

                runOnUiThread(new Runnable() {
                    public void run() {
                        notifyResult(value);
                    }
                });
            } catch (Exception e) {}
        }
    };
    t.start();


} else {
    autoCompleteAdapter.clear();
}
}

@Override
public void afterTextChanged(Editable arg0) {
}


private void notifyResult(String value) {
     try {
            autoCompleteSuggestionAddresses = new Geocoder(getBaseContext()).getFromLocationName(value, 10);

            //notifyResult(autoCompleteSuggestionAddresses);

            latitude = longitude = null;
            autoCompleteAdapter.clear();
            for (Address a : autoCompleteSuggestionAddresses) {
                Log.v("Nohsib", a.toString());
                String temp = ""+ a.getFeatureName()+" "+a.getCountryName()+" "+a.getPostalCode();  

                autoCompleteAdapter.add(temp);
            }
            autoCompleteAdapter.notifyDataSetChanged();



        } catch (IOException ex) {
          //  Log.e(GeoCoderAsyncTask.class.getName(), "Failed to get autocomplete suggestions", ex);
        }

}

}

4

1 回答 1

0

我相信 UI 冻结的原因是因为即使您从单独的线程调用 notifyResult,它仍然在 UI 线程上运行。解决此问题的方法是改用AsyncTask

就像是:

private class GetSuggestions extends AsyncTask<String, Void, Void> {
     protected Long doInBackground(String... search) {
         value = search[0];
         try {
        autoCompleteSuggestionAddresses = new Geocoder(getBaseContext()).getFromLocationName(value, 10);

        //notifyResult(autoCompleteSuggestionAddresses);

        latitude = longitude = null;
        autoCompleteAdapter.clear();
        for (Address a : autoCompleteSuggestionAddresses) {
            Log.v("Nohsib", a.toString());
            String temp = ""+ a.getFeatureName()+" "+a.getCountryName()+" "+a.getPostalCode();  

            autoCompleteAdapter.add(temp);
        }

    } catch (IOException ex) {
      //  Log.e(GeoCoderAsyncTask.class.getName(), "Failed to get autocomplete suggestions", ex);
    }
     }

     protected void onPostExecute(Long result) {
         autoCompleteAdapter.notifyDataSetChanged();
     }
 }

然后你可以通过调用 new GetSuggestions().execute(value); 来启动任务。

于 2012-05-15T02:18:17.813 回答