从子活动返回后的listview错误

时间:2016-08-27 04:36:33

标签: java android listview notifydatasetchanged

所以,我有这个相当有趣的问题,我有这个活动持有ListView。当我按下ListView时,它会启动另一项活动。一旦我回到那个父母的活动,我按下另一个项目,它崩溃说我需要notifyDatasetChanged,我不知道应该去哪里,我想,但是,想法?

public class StartEsole extends FragmentActivity implements OnMapReadyCallback, LocationListener {

    private GoogleMap mMap;
    LocationManager locationManager;
    ParseGeoPoint point;
    ListView listview;
    ArrayList<Details> businessList = new ArrayList<>();
    SwipeRefreshLayout mySwipeRefreshLayout;
    venueDetail vDetailAdapter;
    String userGender;
    int userAge;
    LocationManager mLocationManager;


    /**
     * ATTENTION: This was auto-generated to implement the App Indexing API.
     * See https://g.co/AppIndexing/AndroidStudio for more information.
     */
    private GoogleApiClient client;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        super.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        setContentView(R.layout.activity_start_esole);
        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);
        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        listview = (ListView) findViewById(R.id.whatsLit);
        mySwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swiperefresh);
        mySwipeRefreshLayout.setRefreshing(true);
        runHot();
        // ATTENTION: This was auto-generated to implement the App Indexing API.
        // See https://g.co/AppIndexing/AndroidStudio for more information.
        client = new GoogleApiClient.Builder(this).addApi(AppIndex.API).build();
        //For The Adbanner-loads ads from admob
        AdView adView = (AdView) findViewById(R.id.adView);
        AdRequest adRequest = new AdRequest.Builder().build();
        adView.loadAd(adRequest);
        //FIY userFeed is VenueFeed
        listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Intent i = new Intent(getApplicationContext(), userFeed.class);
                startActivity(i);
                i.putExtra("venueName", businessList.get(position).name);
                startActivity(i);

            }
        });


        mySwipeRefreshLayout.setOnRefreshListener(
                new SwipeRefreshLayout.OnRefreshListener() {
                    @Override
                    public void onRefresh() {
                        Log.i("AppInfo", "onRefresh called from SwipeRefreshLayout");
                        runHot();
                    }
                }

        );




    }
    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;
        LatLng home = new LatLng(getLocation().getLatitude(), getLocation().getLongitude());
        mMap.setMyLocationEnabled(true);
        mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(home, 18));
    }


    @Override
    public void onLocationChanged(Location curLocation) {
        mMap.clear();
        mMap.setMyLocationEnabled(true);
        mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(curLocation.getLatitude(), curLocation.getLongitude()), 18));
        Log.i("AppInfo", "Location Changed");
        runHot();
        listview.setAdapter(vDetailAdapter);

    }


    @Override
    protected void onPause() {
        super.onPause();
        try {
            locationManager.removeUpdates(this);
            checkLogic();
        } catch (Exception e) {
            e.printStackTrace();
            e.getCause();
        }

    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {

    }


    @Override
    public void onProviderEnabled(String provider) {

    }


    @Override
    public void onProviderDisabled(String provider) {

    }


    @Override
    public void onBackPressed() {
        Intent intent = new Intent(Intent.ACTION_MAIN);
        intent.addCategory(Intent.CATEGORY_HOME);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(intent);
    }


       @Override
protected void onResume() {
    super.onResume();
    mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,1800000,0,this);
    mMap.setMyLocationEnabled(true);
    mySwipeRefreshLayout.setRefreshing(true);
    vDetailAdapter = new venueDetail(StartEsole.this,businessList);
    vDetailAdapter.notifyDataSetChanged();
    runHot();
}


    private void runHot() {
        mySwipeRefreshLayout.setRefreshing(true);
        aggregateTaskBars taskBars = new aggregateTaskBars();
        taskBars.execute();
        getLocation();
        checkLogic();
    }


    public Location getLocation() {
        mLocationManager = (LocationManager) getApplicationContext().getSystemService(LOCATION_SERVICE);
        List<String> providers = mLocationManager.getProviders(true);
        Location bestLocation = null;
        for (String provider : providers) {
            Location l = mLocationManager.getLastKnownLocation(provider);
            if (l == null) {
                continue;
            }
            if (bestLocation == null || l.getAccuracy() < bestLocation.getAccuracy()) {
                bestLocation = l;
            }

        }

        try {
            assert bestLocation != null;
            point = new ParseGeoPoint(bestLocation.getLatitude(), bestLocation.getLongitude());
            //ParseQuery to update user activity on the serverside.
            final ParseObject userActivity = new ParseObject("UserActivity");
            ParseQuery<ParseObject> quserActivity = ParseQuery.getQuery("UserActivity");
            quserActivity.whereEqualTo("userId", ParseUser.getCurrentUser().getUsername());
            quserActivity.findInBackground(new FindCallback<ParseObject>() {
                @Override
                public void done(List<ParseObject> objects, ParseException e) {
                    if (e == null) {
                        if (objects.size() > 0) {
                            for (ParseObject object : objects) {
                                object.put("UserLocation", point);
                                object.saveInBackground();
                            }
                        }
                        if (objects.size() == 0) {
                            userActivity.put("UserLocation", point);
                            userActivity.put("userId", ParseUser.getCurrentUser().getUsername());
                            userActivity.saveInBackground();
                        }
                    } else {
                        e.printStackTrace();
                    }
                }
            });

        } catch (Exception e) {
            e.printStackTrace();
        }
        return bestLocation;
    }


    public void checkLogic(){
        ParseQuery<ParseObject> qUserActivity = ParseQuery.getQuery("UserActivity");
        if(businessList.size()>0){
            if(Double.valueOf(businessList.get(0).adistance)<0.00189394){
                qUserActivity.whereEqualTo("userId",ParseUser.getCurrentUser().getUsername());
                try{
                    List<ParseObject>qReply = qUserActivity.find();
                    if(qReply.size()>0){
                        for(ParseObject object : qReply){
                            object.put("CurrentHotspot",businessList.get(0).name);
                            object.put("venueId",businessList.get(0).id);
                            object.saveInBackground();
                        }

                    }
                }catch(Exception e){
                    e.printStackTrace();
                }
            }else if(Double.valueOf(businessList.get(0).adistance)>0.00189394){
                qUserActivity.whereEqualTo("userId",ParseUser.getCurrentUser().getUsername());
                try{
                    List<ParseObject>qReply = qUserActivity.find();
                    if(qReply.size()>0){
                        for(ParseObject object : qReply){
                            object.put("CurrentHotspot","None");
                            object.put("venueId","empty");
                            object.saveInBackground();
                        }

                    }
                }catch(Exception e){
                    e.printStackTrace();
                }
            }
        }

    }


    //For Set Map to the hottest place nearby
    public void startHeat(View view) {
        Log.i("App info", "Started Lit House");
    }


    //To get the GCD(math) to get a generic ratio between 2 numbers
    public int egcd(int a, int b) {
        if (a == 0)
            return b;

        while (b != 0) {
            if (a > b)
                a = a - b;
            else
                b = b - a;
        }

        return a;
    }


    public String truncateDistance(String x){
        Double dTempDist = Double.valueOf(x);
        if(dTempDist<1.0){
            //
            double feet =  dTempDist*(5280);
            x = "~"+String.valueOf((int)feet) + " ft";
        }
        else if(dTempDist>1){
            x="~"+String.valueOf(dTempDist.intValue()) + " mi";
        }
        return x;
    }

public class aggregateTaskBars extends AsyncTask<String, Void, String> {
    ParseGeoPoint myPoint = new ParseGeoPoint(getLocation().getLatitude(), getLocation().getLongitude());
    public void downloadLocally() {
        downLoadTask nightClubDownload = new downLoadTask();
        nightClubDownload.execute("https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=" + String.valueOf(getLocation().getLatitude()) + "," + String.valueOf(getLocation().getLongitude()) + "&rankby=distance" + "&types=" + "night_club" + "&sensor=true" + "&key=A");
        downLoadTask barDownload = new downLoadTask();
        barDownload.execute("https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=" + String.valueOf(getLocation().getLatitude()) + "," + String.valueOf(getLocation().getLongitude()) + "&rankby=distance" + "&types=" + "bar" + "&sensor=true" + "&key=A");
    }

    @Override
    protected String doInBackground(String... params) {
        //Query the user demographic for current user
        ParseQuery<ParseObject> userDemo = new ParseQuery<>("UserActivity");
        //Log.i("AppInfo",ParseUser.getCurrentUser().getUsername());
        userDemo.whereEqualTo("userId", ParseUser.getCurrentUser().getUsername());
        try{
            List<ParseObject> qReply=userDemo.find();
            userAge = qReply.get(0).getInt("Age");
            userGender = qReply.get(0).getString("Gender");
        }
        catch (Exception e){
            e.printStackTrace();
        }


        //Query the bars
        ParseQuery<ParseObject> HotSpotBars = new ParseQuery<>("HotSpots");
        HotSpotBars.whereWithinMiles("venueLocation", myPoint, 10);
        try {
            List<ParseObject> qReply = HotSpotBars.find();
            if(qReply.size()>10){
                for(int i = 0; i<qReply.size();i++){
                    ParseGeoPoint myloc = new ParseGeoPoint(getLocation().getLatitude(),getLocation().getLongitude());
                    String sDistance = truncateDistance(String.valueOf(myloc.distanceInMilesTo(qReply.get(i).getParseGeoPoint("venueLocation"))));
                    String aDistance = String.valueOf(myloc.distanceInMilesTo(qReply.get(i).getParseGeoPoint("venueLocation")));
                    String venueName = qReply.get(i).getString("venue");
                    String id = qReply.get(i).getObjectId();
                    //TODO Create method to count total number of users
                    int count = queryCount(venueName,id,false,"",false);
                    String sCount="";
                    if(count ==0){
                        sCount="  Dead";}
                    if(count> 0 && count < 10){
                        sCount = " Nothing big";
                    }
                    if (count>=10 && count < 25){
                        sCount = " a little something";
                    }
                    if(count>=25 && count<50){
                        sCount = "May b a good one";
                    }
                    if(count>=50 && count< 70){
                        sCount = "  Packed";
                    }
                    if(count>=70){
                        sCount = "Its goin to b litt";
                    }


                    //TODO Create a method getGenderCount
                    int genderCountM = queryCount(venueName,id,true,"M",false);
                    int genderCountF = queryCount(venueName,id,true,"F",false);
                    int GCD = egcd(genderCountF,genderCountM);
                    String genderRatio="";
                    if(GCD == 0){
                         genderRatio = "Its dead";
                    }
                    else if (GCD>0){
                        genderRatio = String.valueOf(genderCountF/GCD)+" F :"+ String.valueOf(genderCountM/GCD)+" M";
                    }
                    Details newVenue = new Details(venueName,"Dist: "+sDistance, aDistance,"ageRange", genderRatio,sCount,count,id);
                    businessList.add(newVenue);

                }

            }
            else{
                //Log.i("AppInfo", "Downloading info... From Google API");
                downloadLocally();
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }

        return null;
    }
    protected int queryCount(String name, String objectID, boolean onGender, String gender,boolean onAge){
        int total = 0;
        ParseQuery<ParseObject> qUserActivity=new ParseQuery<>("UserActivity");
        qUserActivity.whereEqualTo("CurrentHotspot",name);
        qUserActivity.whereEqualTo("venueId", objectID);
        if(onAge){
            //TODO work with breaking down agegroup

        }

        if(onGender){
            qUserActivity.whereEqualTo("Gender", gender);
        }

        try{
            List<ParseObject> qReply = qUserActivity.find();
            total = qReply.size();
        }catch (Exception e){
            e.printStackTrace();
        }
        //Log.i("AppInfo",String.valueOf(total));
        return total;
    }

    @Override
    protected void onProgressUpdate(Void... values) {
        super.onProgressUpdate(values);

    }


    @Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);
        mySwipeRefreshLayout.setRefreshing(false);
        vDetailAdapter = new venueDetail(StartEsole.this,businessList);
        listview.setAdapter(vDetailAdapter);
    }
}

我知道每次你添加一些东西......你需要notifyDatasetChanged,但我不知道应该去哪里。

我用这个作为参考: notifyDataSetChanged example

还没有运气,错误如下:

编辑:请求错误和venueDetail类。

08-27 01:00:54.215 15492-15492/com.esole.esole E/AndroidRuntime: FATAL EXCEPTION: main
                                                             Process: com.esole.esole, PID: 15492
                                                             java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread. Make sure your adapter calls notifyDataSetChanged() when its content changes. [in ListView(2131624124, class android.widget.ListView) with Adapter(class com.esole.esole.venueDetail)]
                                                                 at android.widget.ListView.layoutChildren(ListView.java:1575)
                                                                 at android.widget.AbsListView.onTouchUp(AbsListView.java:4069)
                                                                 at android.widget.AbsListView.onTouchEvent(AbsListView.java:3820)
                                                                 at android.view.View.dispatchTouchEvent(View.java:9297)
                                                                 at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2549)
                                                                 at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2240)
                                                                 at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2555)
                                                                 at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2254)
                                                                 at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2555)
                                                                 at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2254)
                                                                 at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2555)
                                                                 at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2254)
                                                                 at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2555)
                                                                 at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2254)
                                                                 at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2555)
                                                                 at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2254)
                                                                 at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2555)
                                                                 at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2254)
                                                                 at com.android.internal.policy.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2445)
                                                                 at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent_aroundBody0(PhoneWindow.java:1756)
                                                                 at com.android.internal.policy.PhoneWindow$AjcClosure1.run(PhoneWindow.java:1)
                                                                 at android.view.PhoneWindowAO.ajc$around$android_view_PhoneWindowAO$2$99ce526bproceed(PhoneWindowAO.aj:113)
                                                                 at android.view.PhoneWindowAO.ajc$around$android_view_PhoneWindowAO$2$99ce526b(PhoneWindowAO.aj:117)
                                                                 at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1756)
                                                                 at android.app.Activity.dispatchTouchEvent(Activity.java:2800)
                                                                 at com.android.internal.policy.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2406)
                                                                 at android.view.View.dispatchPointerEvent(View.java:9517)
                                                                 at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4309)
                                                                 at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4175)
                                                                 at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3682)
                                                                 at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3735)
                                                                 at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3701)
                                                                 at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3709)
                                                                 at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3682)
                                                                 at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3735)
                                                                 at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3701)
                                                                 at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3828)
                                                                 at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3709)
                                                                 at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3885)
                                                                 at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3682)
                                                                 at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3735)
                                                                 at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3701)
                                                                 at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3709)
                                                                 at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3682)
                                                                 at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:6001)
                                                                 at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:5975)
                                                                at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:5936

场地详情类:

public class venueDetail extends ArrayAdapter<Details> {
public venueDetail(Context context, ArrayList<Details> venues) {
    super(context, 0,venues);
}

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

    Details detail = getItem(position);
    if(convertView==null){
        convertView= LayoutInflater.from(getContext()).inflate(R.layout.mylayout,parent,false);
    }
    TextView tvName = (TextView) convertView.findViewById(R.id.venueName);
    TextView tvDistance = (TextView) convertView.findViewById(R.id.textDistance);
    TextView tvAgeRange = (TextView) convertView.findViewById(R.id.textAgeRange);
    TextView tvUserCount = (TextView) convertView.findViewById(R.id.textUserCount);
    TextView tvGenderRatio = (TextView) convertView.findViewById(R.id.textGenderRatio);
    tvName.setText(detail.name);
    tvDistance.setText(detail.sdistance);
    tvAgeRange.setText(detail.ageRange);
    tvUserCount.setText(detail.sCount);
    tvGenderRatio.setText(detail.genderRatio);
    //notifyDataSetChanged();



    return convertView;
}

}

1 个答案:

答案 0 :(得分:0)

我想出了问题,问题是当我运行on resume方法时,它会运行一个请求位置更新,而这又会运行onLocationChanged,这意味着每次GPS位置发生变化时它都会运行任务后台,不断向列表添加项目,这意味着它需要运行notifyDataSetChanged()。我刚刚在这里注释了runhot方法调用

    @Override
public void onLocationChanged(Location curLocation) {
    mMap.clear();
    mMap.setMyLocationEnabled(true);
    mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(curLocation.getLatitude(), curLocation.getLongitude()), 18));
    Log.i("AppInfo", "Location Changed");
    //runHot();
    listview.setAdapter(vDetailAdapter);

}