0

My goal is to do drop down list while user input text using Google Places API, it works fine, but if user wont to remove the input text by holding backspace button, it will throw different exceptions.

Somethimes it:

 java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.ViewGroup$LayoutParams android.view.View.getLayoutParams()' on a null object reference
        at android.widget.PopupWindow.update(PopupWindow.java:1615)
        at android.widget.PopupWindow.update(PopupWindow.java:1593)
        at android.widget.ListPopupWindow.show(ListPopupWindow.java:609)
        at android.widget.AutoCompleteTextView.showDropDown(AutoCompleteTextView.java:1105)
        at android.widget.AutoCompleteTextView.updateDropDownForFilter(AutoCompleteTextView.java:974)
        at android.widget.AutoCompleteTextView.access$900(AutoCompleteTextView.java:90)
        at android.widget.AutoCompleteTextView$PopupDataSetObserver$1.run(AutoCompleteTextView.java:1299)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:135)
        at android.app.ActivityThread.main(ActivityThread.java:5254)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)

Somethimes it, this excpetion I catch, it does not affect on app :

java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
        at android.view.ViewGroup.addViewInner(ViewGroup.java:3936)
        at android.view.ViewGroup.addView(ViewGroup.java:3786)
        at android.view.ViewGroup.addView(ViewGroup.java:3758)
        at android.widget.PopupWindow.preparePopup(PopupWindow.java:1076)
        at android.widget.PopupWindow.showAsDropDown(PopupWindow.java:999)
        at android.widget.ListPopupWindow.show(ListPopupWindow.java:639)
        at android.widget.ListPopupWindow$PopupDataSetObserver.onChanged(ListPopupWindow.java:1757)
        at android.database.DataSetObservable.notifyChanged(DataSetObservable.java:37)
        at android.widget.BaseAdapter.notifyDataSetChanged(BaseAdapter.java:50)
        at android.widget.ArrayAdapter.notifyDataSetChanged(ArrayAdapter.java:286)
        at android.widget.ArrayAdapter.clear(ArrayAdapter.java:261)
        at com.driveyello.yello.adapters.AutoPredictionAdapter$1.performFiltering(AutoPredictionAdapter.java:66)
        at android.widget.Filter$RequestHandler.handleMessage(Filter.java:234)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:135)
        at android.os.HandlerThread.run(HandlerThread.java:61)

This exceptions makes crash:

 Process: com.driveyello.yello, PID: 25191
java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.ViewGroup$LayoutParams android.view.View.getLayoutParams()' on a null object reference
        at android.widget.PopupWindow.update(PopupWindow.java:1615)
        at android.widget.PopupWindow.update(PopupWindow.java:1593)
        at android.widget.ListPopupWindow.show(ListPopupWindow.java:609)
        at android.widget.AutoCompleteTextView.showDropDown(AutoCompleteTextView.java:1105)
        at android.widget.AutoCompleteTextView.setFrame(AutoCompleteTextView.java:1051)
        at android.view.View.layout(View.java:15667)
        at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1703)
        at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1557)
        at android.widget.LinearLayout.onLayout(LinearLayout.java:1466)
        at android.view.View.layout(View.java:15671)
        at android.view.ViewGroup.layout(ViewGroup.java:5038)
        at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1703)
        at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1557)
        at android.widget.LinearLayout.onLayout(LinearLayout.java:1466)
        at android.view.View.layout(View.java:15671)
        at android.view.ViewGroup.layout(ViewGroup.java:5038)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:514)
        at android.widget.ScrollView.onLayout(ScrollView.java:1502)
        at android.view.View.layout(View.java:15671)
        at android.view.ViewGroup.layout(ViewGroup.java:5038)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:514)
        at android.view.View.layout(View.java:15671)
        at android.view.ViewGroup.layout(ViewGroup.java:5038)
        at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1703)
        at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1557)
        at android.widget.LinearLayout.onLayout(LinearLayout.java:1466)
        at android.view.View.layout(View.java:15671)
        at android.view.ViewGroup.layout(ViewGroup.java:5038)
        at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1076)
        at android.view.View.layout(View.java:15671)
        at android.view.ViewGroup.layout(ViewGroup.java:5038)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:514)
        at android.view.View.layout(View.java:15671)
        at android.view.ViewGroup.layout(ViewGroup.java:5038)
        at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1703)
        at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1557)
        at android.widget.LinearLayout.onLayout(LinearLayout.java:1466)
        at android.view.View.layout(View.java:15671)
        at android.view.ViewGroup.layout(ViewGroup.java:5038)
        at android.support.v4.widget.DrawerLayout.onLayout(DrawerLayout.java:1043)
        at android.view.View.layout(View.java:15671)
        at android.view.ViewGroup.layout(ViewGroup.java:5038)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:514)
        at android.view.View.layout(View.java:15671)
        at android.view.ViewGroup.layout(ViewGroup.java:5038)
        at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1703)
        at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1557)
        at android.widget.LinearLayout.onLayout(LinearLayout.java:1466)
        at android.view.View.layout(View.java:15671)
        at android.view.ViewGroup.layout(ViewGroup.java:5038)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:514)
        at android.view.View.layout(View.java:15671)
        at android.view.ViewGroup.layout(ViewGroup.java:5038)
        at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1703)
        at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1557)
        at android.widget.LinearLayout.onLayout(LinearLayout.java:1466)
        at android.view.View.layout(View.java:15671)
        at android.view.ViewGroup.layout(ViewGroup.java:5038)
        at android.widget.Frame

Here is my adapter, AutoCompletePlace it's a simple model that contains two string fields, getters/setters

public class AutoPredictionAdapter extends ArrayAdapter<AutoCompletePlace> {

private GoogleApiClient mGoogleApiClient;

public AutoPredictionAdapter(Context context) {
    super(context, 0);
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder holder;

    if( convertView == null ) {
        holder = new ViewHolder();
        convertView = LayoutInflater.from(getContext()).inflate( android.R.layout.simple_list_item_1, parent, false  );
        holder.text = (TextView) convertView.findViewById( android.R.id.text1 );
        convertView.setTag( holder );
    } else {
        holder = (ViewHolder) convertView.getTag();
    }

    holder.text.setText(getItem(position).getDescription());

    return convertView;
}
public void setGoogleApiClient(GoogleApiClient mGoogleApiClient) {
    this.mGoogleApiClient = mGoogleApiClient;
}
@Override
public Filter getFilter() {
    return new Filter() {
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            if( mGoogleApiClient == null || !mGoogleApiClient.isConnected() ) {
                Toast.makeText(getContext(), "Not connected", Toast.LENGTH_SHORT).show();
                return null;
            }
            clear(); // here exceptions are thrown 
            displayPredictiveResults(constraint.toString());
            return null;
        }

        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            try {
                notifyDataSetChanged(); // here exceptions are thrown 
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    };
}

private void displayPredictiveResults(String query) {
    //Southwest corner to Northeast corner.
    final LatLngBounds bounds = new LatLngBounds( new LatLng( 39.906374, -105.122337 ), new LatLng( 39.949552, -105.068779 ) );

    //Filter: https://developers.google.com/places/supported_types#table3
    /*List<Integer> filterTypes = new ArrayList<>();
    filterTypes.add( Place.TYPE_ESTABLISHMENT );*/

    Places.GeoDataApi.getAutocompletePredictions( mGoogleApiClient, query, bounds, null )
            .setResultCallback(
                    new ResultCallback<AutocompletePredictionBuffer>() {
                        @Override
                        public void onResult(AutocompletePredictionBuffer buffer) {
                            if (buffer == null)
                                return;


                            if (buffer.getStatus().isSuccess()) {
                                for (AutocompletePrediction prediction : buffer) {
                                    try {
                                        //Add as a new item to avoid IllegalArgumentsException when buffer is released
                                        add(new AutoCompletePlace(prediction.getPlaceId(), prediction.getDescription()));
                                    }catch (Exception e){
                                        e.printStackTrace();
                                    }
                                }
                            }

                            //Prevent memory leak by releasing buffer
                            buffer.release();
                        }
                    }, 60, TimeUnit.SECONDS);
}
private static class ViewHolder {
    TextView text;
}

Here is how I configure auto prediction, I have two AutoCompleteTextView.

 private void configureAutoPrediction(){
    mPredictionAdapter = new AutoPredictionAdapter(getActivity());
    mFirstAddressAutoCompleteTextView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            AutoCompletePlace place = (AutoCompletePlace) parent.getItemAtPosition(position);
            findPlaceById(place.getId(),FIRST_ADDRESS);
        }
    });
    mSecondAddressAutoCompleteTextView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            AutoCompletePlace place = (AutoCompletePlace) parent.getItemAtPosition(position);
            findPlaceById(place.getId(),SECOND_ADDRESS);
        }
    });
    mFirstAddressAutoCompleteTextView.setAdapter(mPredictionAdapter);
    mSecondAddressAutoCompleteTextView.setAdapter(mPredictionAdapter);
}
private void findPlaceById( final String id, final int addressID ) {
    if( TextUtils.isEmpty(id) || mGoogleApiClient == null || !mGoogleApiClient.isConnected())
        return;

    Places.GeoDataApi.getPlaceById(mGoogleApiClient, id).setResultCallback(new ResultCallback<PlaceBuffer>() {
        @Override
        public void onResult(PlaceBuffer places) {
            if (places.getStatus().isSuccess()) {
                Place place = places.get(0);
                switch (addressID){
                    case FIRST_ADDRESS:
                        mFirstAddressAutoCompleteTextView.setText(place.getAddress());
                        break;
                    case SECOND_ADDRESS:
                        mSecondAddressAutoCompleteTextView.setText(place.getAddress());
                        break;
                    default: throw new IllegalArgumentException("Unknown address id");
                }
                mPredictionAdapter.clear();
            }
            //Release the PlaceBuffer to prevent a memory leak
            places.release();
        }
    });


}
Dennis Zinkovski
  • 1,821
  • 3
  • 25
  • 42

0 Answers0