简体   繁体   中英

Android fragment onCreate not working?

I am new to android programming so the question is still pretty basic. I am working with volley library inside a fragment, which gets a list of json objects and then add it to the list view. I handle all the data intensive code in the onCreate method of the fragment and save the json as string. I then put the string in the bundle outstate to get the data once the fragment is recreated. In the oncreate method I do a if else to check whether the bundle has any data or not. I then update the view items accordingly. But the app crashes with a null pointer exception. Here is the code for my fragment.

package com.itsyogesh.gottago.fragments;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ListView;

import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.VolleyLog;
import com.android.volley.toolbox.JsonArrayRequest;
import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapView;
import com.google.android.gms.maps.MapsInitializer;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import com.itsyogesh.gottago.R;
import com.itsyogesh.gottago.adapter.CustomListAdapter;
import com.itsyogesh.gottago.adapter.ListInScrollAdapter;
import com.itsyogesh.gottago.model.ToiletList;
import com.itsyogesh.gottago.utils.AppController;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.List;

public class ToiletListFragment extends Fragment {

public static final String ARG_RESPONSE = "response";
private String JSONResponse = null;
onListFragmentSelectedListener mCallback;
private GoogleMap googleMap;
private MapView mapView;
private Location location;
private int zoom;
private String url = "http://gotttago.herokuapp.com/api/toilets/";
private ProgressDialog pDialog;
private List<ToiletList> toiletList = new ArrayList<ToiletList>();
private ListView listView;
private CustomListAdapter customAdapter;
private Bundle savedInstanceState;

public ToiletListFragment() {
    // Required empty public constructor
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);


    customAdapter = new CustomListAdapter(getActivity());

    pDialog = new ProgressDialog(getActivity());

    this.savedInstanceState = savedInstanceState;
    if (savedInstanceState != null) {
        JSONResponse = savedInstanceState.getString(ARG_RESPONSE);
    }
    if(JSONResponse == null){
        MapsInitializer.initialize(getActivity());

        LocationManager locationManager = (LocationManager) getActivity()
                .getSystemService(Context.LOCATION_SERVICE);

        Criteria criteria = new Criteria();

        String provider = locationManager.getBestProvider(criteria, true);

        location = locationManager.getLastKnownLocation(provider);
        url = url + "nearby/?lat=" + location.getLatitude() + "&lng=" + location.getLongitude();
        Log.e("URL", url);
        pDialog.setMessage("Loading...");
        pDialog.show();
        JsonArrayRequest toiletReq = new JsonArrayRequest(url,
                new Response.Listener<JSONArray>() {
                    @Override
                    public void onResponse(JSONArray response) {
                        Log.e("List fragment", response.toString());
                        JSONResponse = null;
                        JSONResponse = response.toString();
                        hidePDialog();
                    }
                }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError volleyError) {
                VolleyLog.d("ListFragment", "Error: " + volleyError.getMessage());

            }
        }
        );
        AppController.getInstance().addToRequestQueue(toiletReq);
        hidePDialog();
    }
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    View ListFragmentView = inflater.inflate(R.layout.fragment_list, container, false);
    return ListFragmentView;

}

@Override
public void onStart() {
    super.onStart();

    mapView = (MapView) getView().findViewById(R.id.map);
    mapView.onCreate(savedInstanceState);
    listView = (ListView) getView().findViewById(R.id.list);
    listView.setAdapter(customAdapter);

    setupMap();

    Log.e(ARG_RESPONSE, JSONResponse);
    setUpElements(JSONResponse);


}

public void setupMap() {

    googleMap = mapView.getMap();
    googleMap.getUiSettings().setMyLocationButtonEnabled(true);
    googleMap.getUiSettings().setZoomControlsEnabled(false);
    googleMap.getUiSettings().setAllGesturesEnabled(true);
    googleMap.setMyLocationEnabled(true);

    MapsInitializer.initialize(getActivity());

    LocationManager locationManager = (LocationManager) getActivity()
            .getSystemService(Context.LOCATION_SERVICE);

    Criteria criteria = new Criteria();

    String provider = locationManager.getBestProvider(criteria, true);

    location = locationManager.getLastKnownLocation(provider);

    //Log.e("My Location", location.getLatitude() + ", " + location.getLongitude());
    zoom = 12;
    if (location != null) {
        CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLng(
                new LatLng(location.getLatitude(), location.getLongitude()));
        googleMap.moveCamera(cameraUpdate);
        googleMap.animateCamera(CameraUpdateFactory.zoomTo(zoom));

        url = url + "nearby/?lat=" + location.getLatitude() + "&lng=" + location.getLongitude();

    }

}

public void setUpElements(String responseString) {

    JSONArray response = new JSONArray();
    try {
        response = new JSONArray(responseString);
    } catch (JSONException e) {
        e.printStackTrace();
    }

    Log.e(ARG_RESPONSE, response.toString());

    //Parsing JSON
    for (int i = 0; i < response.length(); i++) {
        try {
            JSONObject obj = response.getJSONObject(i);
            ToiletList toilet = new ToiletList();
            toilet.setTitle(obj.getString("name"));
            toilet.setGender(obj.getString("gender"));
            toilet.setRating(obj.getDouble("overall_rating"));
            JSONArray loc = obj.getJSONArray("loc");
            Location toilet_location = new Location(obj.getString("name"));
            toilet_location.setLatitude((Double) loc.get(1));
            toilet_location.setLongitude((Double) loc.get(0));
            double distance = 0;
            if (location != null) {
                distance = Math.round(location.distanceTo(toilet_location) / 10.0);
            }
            toilet.setDistance(distance / 100);
            toilet.setToilet_id(obj.getString("_id"));
            //Add marker
            addMarker(toilet_location, toilet.getTitle());
            toiletList.add(toilet);
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }
    //notifying list adapter for data changes
    customAdapter.swapToiletRecords(toiletList);
    ListInScrollAdapter.getListView(listView);

    listView.setOnItemClickListener(new AdapterView.OnItemClickListener()

                                    {
                                        @Override
                                        public void onItemClick(AdapterView<?> arg0, View view, int position, long id) {
                                            mCallback.onListItemSelected(JSONResponse, position);
                                        }
                                    }
    );

}

public void addMarker(Location location, String title) {
    MarkerOptions marker = new MarkerOptions().position(
            new LatLng(location.getLatitude(), location.getLongitude())).title(title);
    Log.e("Added marker", location.toString());
    googleMap.addMarker(marker);
}

private void hidePDialog() {
    if (pDialog != null) {
        pDialog.dismiss();
        pDialog = null;
    }
}

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);

    try {
        mCallback = (onListFragmentSelectedListener) activity;
    } catch (ClassCastException e) {
        throw new ClassCastException(activity.toString()
                + " must implement onListFragmentSelectedListener");
    }
}

@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);

    //Save the current json response so that we don't have to utilise volley again
    if (JSONResponse != null) {
        outState.putString(ARG_RESPONSE, JSONResponse);
    }
}

//The container activity must implement this interface so that fragment can deliver messages
public interface onListFragmentSelectedListener {
    //Called by list fragment when an item is selected
    public void onListItemSelected(String response, int position);
}

}

Its my first asking a question on stackoverflow, so please bear with me.

EDIT: Here is the logcat(just the required snippet).

3783-3783/com.itsyogesh.gottago E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.itsyogesh.gottago, PID: 3783
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.itsyogesh.gottago/com.itsyogesh.gottago.MainActivity}: java.lang.NullPointerException: println needs a message
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2596)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2653)
        at android.app.ActivityThread.access$800(ActivityThread.java:156)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1355)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:157)
        at android.app.ActivityThread.main(ActivityThread.java:5872)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:515)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1069)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:885)
        at dalvik.system.NativeStart.main(Native Method)
 Caused by: java.lang.NullPointerException: println needs a message
        at android.util.Log.println_native(Native Method)
        at android.util.Log.e(Log.java:232)
        at com.itsyogesh.gottago.fragments.ToiletListFragment.onStart(ToiletListFragment.java:133)
        at android.support.v4.app.Fragment.performStart(Fragment.java:1528)
        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:972)
        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1121)
        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1103)
        at android.support.v4.app.FragmentManagerImpl.dispatchStart(FragmentManager.java:1906)
        at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:588)
        at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1239)
        at android.app.Activity.performStart(Activity.java:5322)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2569)

Try to put your oncreate codes to oncreateview in-between View and return. If that doesn't help post the nullpointer log.

Your println needs a message NPE comes when you try to log a null here in onStart() :

Log.e(ARG_RESPONSE, JSONResponse);

Seems like JSONResponse is initialized possibly only later in the lifecycle. If you insist on logging it, you can enforce the log arg to be a non-null string eg by appending an empty string:

Log.e(ARG_RESPONSE, "" + JSONResponse);

The Log.e(ARG_RESPONSE, JSONResponse); JSONResponse is null, I think you should replace the code of your JSON retrieval if not in oncreate or in onstart depends on you, also get a read on the onResume it might help also. Best way to debug this is to avoid having to declare nulls. better to declare it as JSONParser response; or something like that and Log.e(ARG_RESPONSE, JSONResponse.toString());

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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