简体   繁体   English

应用程序在滚动列表时崩溃

[英]App is crashing on scrolling of list

In my app I am displaying map and list of items. 在我的应用中,我正在显示地图和项目列表。 I am using google place api to fetch nearest places and showing on map as markers having name and vicinity and as well as list. 我正在使用Google Place API获取最近的位置,并在地图上显示为具有名称和附近以及列表的标记。 Here is my code 这是我的代码

GooglePlacesActivity.java GooglePlacesActivity.java

import android.app.ActionBar;
import android.location.Location;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;

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


public class GooglePlacesActivity extends FragmentActivity implements LocationListener, GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener{

    GoogleMap mMap;
    private GoogleApiClient mGoogleApiClient;
    private LocationRequest mLocationRequest;
    private double latitude;
    private double longitude;

    List<Place> placeList;

    ListView listView;

    PlaceAdapter mPlaceAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_google_places);

        ActionBar actionBar = getActionBar();
        actionBar.show();

        mGoogleApiClient = new GoogleApiClient.Builder(this).
                addApi(LocationServices.API).
                addConnectionCallbacks(this).
                addOnConnectionFailedListener(this).
                build();

        actionBar.setCustomView(R.layout.search_actionbar);
        final EditText search = (EditText) actionBar.getCustomView().findViewById(R.id.searchField);

        listView = (ListView) findViewById(R.id.list_item);

        search.setOnEditorActionListener(new TextView.OnEditorActionListener() {
            @Override
            public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
                String value = search.getText().toString();
                StringBuilder googlePlacesUrl = new StringBuilder("https://maps.googleapis.com/maps/api/place/search/json?");
                googlePlacesUrl.append("location=" + latitude + "," + longitude);
                googlePlacesUrl.append("&radius=" + 1000);
                googlePlacesUrl.append("&types=" + value);
                googlePlacesUrl.append("&key=" + API_KEY);

                GooglePlacesTask googlePlacesTask = new GooglePlacesTask();
                googlePlacesTask.execute(googlePlacesUrl.toString());

                return false;
            }
        });

        actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM | ActionBar.DISPLAY_SHOW_HOME);

        if (mMap == null){
            mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.googleMap)).getMap();
            mMap.setMyLocationEnabled(true);
        }
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_google_places, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }


    @Override
    protected void onStart() {
        super.onStart();
        mGoogleApiClient.connect();
    }

    @Override
    protected void onStop() {
        mGoogleApiClient.disconnect();
        super.onStop();
    }

    @Override
    public void onConnected(Bundle bundle) {
        mLocationRequest = LocationRequest.create();
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        mLocationRequest.setInterval(1000*60);

        LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);

    }

    @Override
    public void onConnectionSuspended(int i) {

    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {

    }

    @Override
    public void onLocationChanged(Location location) {
        latitude = location.getLatitude();
        longitude = location.getLongitude();
        LatLng latLng = new LatLng(latitude, longitude);
        mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
        mMap.animateCamera(CameraUpdateFactory.zoomTo(12));
    }

    private class GooglePlacesTask extends AsyncTask<String, Void, String>{
        String data;

        @Override
        protected String doInBackground(String... params) {
            try{
                data = Http.read(params[0]);
                Log.d("DATA", data);
            }catch (IOException e){
                e.printStackTrace();
            }

            return data;
        }

        @Override
        protected void onPostExecute(String result) {

            placeList = ParseJson.parsedata(result);

            for (Place place : placeList){
                Log.d("Latitude", String.valueOf(place.getLatitude()));
                Log.d("Longitude", String.valueOf(place.getLongitude()));
                Log.d("Name", place.getName());
                Log.d("Vicinity", place.getVicinity());

            }

            for (int i = 0; i < placeList.size(); i++) {
                mMap.addMarker(new MarkerOptions()
                        .title(placeList.get(i).getName())
                        .position(
                                new LatLng(placeList.get(i).getLatitude(), placeList
                                        .get(i).getLongitude()))
                        .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN))
                        .snippet(placeList.get(i).getVicinity()));
            }
            CameraPosition cameraPosition = new CameraPosition.Builder()
                    .target(new LatLng(placeList.get(0).getLatitude(), placeList
                            .get(0).getLongitude())) // Sets the center of the map to
                            // Mountain View
                    .zoom(14) // Sets the zoom
                    .tilt(30) // Sets the tilt of the camera to 30 degrees
                    .build(); // Creates a CameraPosition from the builder
            mMap.animateCamera(CameraUpdateFactory
                    .newCameraPosition(cameraPosition));

            mPlaceAdapter = new PlaceAdapter(GooglePlacesActivity.this, placeList);
            mPlaceAdapter.notifyDataSetChanged();
            listView.setAdapter(mPlaceAdapter);
        }
    }
}

PlaceAdapter.java PlaceAdapter.java

package com.aquib.android.placefinder;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;

import java.util.List;


/**
 * Created by dell on 2/19/2015.
 */
public class PlaceAdapter extends ArrayAdapter<Place>{

    private final List<Place> list;
    private final Context context;

    public PlaceAdapter(Context context, List<Place> list){
        super(context, R.layout.place_list, list);
        this.context = context;
        this.list = list;
    }

    static class ViewHolder{
        protected TextView text;
    }

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

        View view = null;
        ViewHolder viewHolder;

        if (convertView == null){
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            view = inflater.inflate(R.layout.place_list, parent, false);
            viewHolder = new ViewHolder();
            viewHolder.text = (TextView) view.findViewById(R.id.placeName);
            view.setTag(viewHolder);
        }

        else {
            viewHolder = (ViewHolder) view.getTag();
        }

        viewHolder.text.setText(list.get(position).getName());
        return view;
    }
}

when i scroll my list, app is crashing and generating NullPointerException. 当我滚动列表时,应用程序崩溃并生成NullPointerException。

And this error is generating 这个错误正在产生

java.lang.NullPointerException
            at com.aquib.android.placefinder.PlaceAdapter.getView(PlaceAdapter.java:46)
            at android.widget.AbsListView.obtainView(AbsListView.java:2255)
            at android.widget.ListView.makeAndAddView(ListView.java:1790)
            at android.widget.ListView.fillDown(ListView.java:691)
            at android.widget.ListView.fillGap(ListView.java:655)
            at android.widget.AbsListView.trackMotionScroll(AbsListView.java:5143)
            at android.widget.AbsListView.scrollIfNeeded(AbsListView.java:3243)
            at android.widget.AbsListView.onTouchMove(AbsListView.java:3587)
            at android.widget.AbsListView.onTouchEvent(AbsListView.java:3431)
            at android.view.View.dispatchTouchEvent(View.java:7706)
            at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2210)
            at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1945)
            at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2216)
            at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
            at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2216)
            at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
            at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2216)
            at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
            at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2216)
            at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
            at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2216)
            at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
            at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2068)
            at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1515)
            at android.app.Activity.dispatchTouchEvent(Activity.java:2458)
            at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2016)
            at android.view.View.dispatchPointerEvent(View.java:7886)
            at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:3947)
            at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:3826)
            at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3392)
            at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3442)
            at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3411)
            at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3518)
            at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3419)
            at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3575)
            at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3392)
            at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3442)
            at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3411)
            at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3419)
            at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3392)
            at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:5532)
            at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:5512)
            at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:5483)
            at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:5612)
            at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:185)
            at android.view.InputEventReceiver.nativeConsumeBatchedInputEvents(Native Method)
            at android.view.InputEventReceiver.consumeBatchedInputEvents(InputEventReceiver.java:176)
            at android.view.ViewRootImpl.doConsumeBatchedInput(ViewRootImpl.java:5585)
            at android.view.ViewRootImpl$ConsumeBatchedInputRunnable.run(ViewRootImpl.java:5631)
            at android.view.Choreographer$CallbackRecord.run(Choreographer.java:761)
            at android.view.Choreographer.doCallbacks(Choreographer.java:574)
            at android.view.Choreographer.doFrame(Choreographer.java:542)
            at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographe.

This happens because when you scrolling your list getView() method is getting called. 发生这种情况是因为在滚动列表时会调用getView()方法。 Now yor view is null so its showing ANR 现在您的视图为空,因此显示ANR

to overcome on this situation you should do this 要克服这种情况,你应该这样做

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

    //View view = null;
    ViewHolder viewHolder;

    if (convertView == null){
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView= inflater.inflate(R.layout.place_list, parent, false);
        viewHolder = new ViewHolder();
        viewHolder.text = (TextView) view.findViewById(R.id.placeName);
        convertView.setTag(viewHolder);
    }

    else {
        viewHolder = (ViewHolder) convertView.getTag();
    }

    viewHolder.text.setText(list.get(position).getName());
    return convertView;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM