0

这应该很简单,但我仍然看不到什么/如何可能是 Null。我试图从谷歌地方 api获得一个AutoCompleteTextView的结果。我可以看到我的 URL 创建是正确的,我从 google 获得了结果,但是当结果被传播到 textView 时,一切都崩溃了。

XML 布局 - places_search.xml:

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="#dddddd">

<AutoCompleteTextView android:id="@+id/autoCompleteTextView1"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="10dp" >
    <requestFocus></requestFocus>
    </AutoCompleteTextView>
</RelativeLayout>

TextView 的 XML 布局:

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:padding="10dp"
    android:textSize="16sp"
    android:textColor="#000">
</TextView>

以下是从 google places api 搜索自动完成结果的完整代码。

public class PlacesListSearchActivity extends Activity {

    private static final String TAG = "PlacesListActivity";

    private ResultReceiver mReceiver;

    private OnSharedPreferenceChangeListener sharedPreferencesListener;
    private SharedPreferences sharedPreferences;

    /** Called when the activity is first created. */
    public ArrayAdapter<String> adapter;
    public AutoCompleteTextView textView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.places_search);
        final ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,R.layout.item_list);
        final AutoCompleteTextView textView = (AutoCompleteTextView)findViewById(R.id.autoCompleteTextView1);
        adapter.setNotifyOnChange(true);
        textView.setHint("type store name");
        textView.setAdapter(adapter);
        textView.addTextChangedListener(new TextWatcher() {

        public void onTextChanged(CharSequence s, int start, int before, int count) {
            if (count%3 == 1) {
                adapter.clear();
                    GetPlaces task = new GetPlaces();
                    //now pass the argument in the textview to the task
                    task.execute(textView.getText().toString());
            }
        }

        public void beforeTextChanged(CharSequence s, int start, int count,
        int after) {
        // TODO Auto-generated method stub

        }

        public void afterTextChanged(Editable s) {

        }

        });
    }

    class GetPlaces extends AsyncTask<String, Void, ArrayList<String>> {
        @Override
        // three dots is java for an array of strings
        protected ArrayList<String> doInBackground(String... args)
        {
            Log.d("gottaGo", "doInBackground");
            ArrayList<String> predictionsArr = new ArrayList<String>();
            try
            {
                URL googlePlaces = new URL(
                        "https://maps.googleapis.com/maps/api/place/autocomplete/json?input=" +
                        URLEncoder.encode(args[0], "UTF-8") +
                        "&types=geocode&language=en&sensor=true&key=" +
                        getResources().getString(R.string.googleAPIKey));

                Log.d("URL", googlePlaces.toString());

                URLConnection tc = googlePlaces.openConnection();
                BufferedReader in = new BufferedReader(new InputStreamReader(
                        tc.getInputStream()));

                String line;
                StringBuffer sb = new StringBuffer();
                //take Google's legible JSON and turn it into one big string.
                while ((line = in.readLine()) != null) {
                    sb.append(line);
                }
                //turn that string into a JSON object
                JSONObject predictions = new JSONObject(sb.toString()); 
                //now get the JSON array that's inside that object            
                JSONArray ja = new JSONArray(predictions.getString("predictions"));

                for (int i = 0; i < ja.length(); i++) {
                    JSONObject jo = (JSONObject) ja.get(i);
                    //add each entry to our array
                    predictionsArr.add(jo.getString("description"));
                }
            } catch (IOException e)
            {
            Log.e("YourApp", "GetPlaces : doInBackground", e);
            } catch (JSONException e)
            {


    Log.e("YourApp", "GetPlaces : doInBackground", e);
        }

        return predictionsArr;
    }

    //then our post
    @Override
    protected void onPostExecute(ArrayList<String> result){
        Log.d("YourApp", "onPostExecute : " + result.size());
        //update the adapter
        adapter = new ArrayAdapter<String>(getBaseContext(), R.layout.item_list);
        adapter.setNotifyOnChange(true);
        //attach the adapter to textview
        textView.setAdapter(adapter);

        for (String string : result) {
            Log.d("YourApp", "onPostExecute : result = " + string);
            adapter.add(string);
            adapter.notifyDataSetChanged();
        }

        Log.d("YourApp", "onPostExecute : autoCompleteAdapter" + adapter.getCount());
    }

}

}

下面是LOGCAT:

06-24 09:34:41.225: E/AndroidRuntime(10588): FATAL EXCEPTION: main
06-24 09:34:41.225: E/AndroidRuntime(10588): java.lang.NullPointerException
06-24 09:34:41.225: E/AndroidRuntime(10588):    at com.rathinavelu.rea.PlacesListSearchActivity$GetPlaces.onPostExecute(PlacesListSearchActivity.java:156)
06-24 09:34:41.225: E/AndroidRuntime(10588):    at com.rathinavelu.rea.PlacesListSearchActivity$GetPlaces.onPostExecute(PlacesListSearchActivity.java:1)
06-24 09:34:41.225: E/AndroidRuntime(10588):    at android.os.AsyncTask.finish(AsyncTask.java:602)
06-24 09:34:41.225: E/AndroidRuntime(10588):    at android.os.AsyncTask.access$600(AsyncTask.java:156)
06-24 09:34:41.225: E/AndroidRuntime(10588):    at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:615)
06-24 09:34:41.225: E/AndroidRuntime(10588):    at android.os.Handler.dispatchMessage(Handler.java:99)
06-24 09:34:41.225: E/AndroidRuntime(10588):    at android.os.Looper.loop(Looper.java:137)
06-24 09:34:41.225: E/AndroidRuntime(10588):    at android.app.ActivityThread.main(ActivityThread.java:4507)
06-24 09:34:41.225: E/AndroidRuntime(10588):    at java.lang.reflect.Method.invokeNative(Native Method)
06-24 09:34:41.225: E/AndroidRuntime(10588):    at java.lang.reflect.Method.invoke(Method.java:511)
06-24 09:34:41.225: E/AndroidRuntime(10588):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790)
06-24 09:34:41.225: E/AndroidRuntime(10588):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557)
06-24 09:34:41.225: E/AndroidRuntime(10588):    at dalvik.system.NativeStart.main(Native Method)

第 156 行将我带到代码中的这一行:

textView.setAdapter(adapter);
4

2 回答 2

3

改变

final ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,R.layout.item_list);
final AutoCompleteTextView textView = (AutoCompleteTextView)findViewById(R.id.autoCompleteTextView1)

 adapter = new ArrayAdapter<String>(this,R.layout.item_list);
 textView = (AutoCompleteTextView)findViewById(R.id.autoCompleteTextView1)
于 2012-06-24T08:03:17.193 回答
1

很明显你会得到NPE

您已经定义了 textView 两次。

1 在 Oncreate Block (这是本地的)

final AutoCompleteTextView textView = (AutoCompleteTextView)findViewById(R.id.autoCompleteTextView1);

2 在类成员变量中。

public AutoCompleteTextView textView;

当您尝试 setAdapter 时,它会寻找未初始化的成员变量 textView。

解决方案是删除final AutoCompleteTextView

textView = (AutoCompleteTextView)findViewById(R.id.autoCompleteTextView1);

事实上,您需要将两者都修改为以下

adapter = new ArrayAdapter<String>(this,R.layout.item_list);
textView = (AutoCompleteTextView)findViewById(R.id.autoCompleteTextView1);

如果您在成员变量中定义了它们,那么为什么要在 onCreate 中本地重新定义它们。如果您尝试从 AsyncTask 访问它们,它将查找未初始化的成员变量。

于 2012-06-24T07:54:57.680 回答