Android片段onCreate无法正常工作?

时间:2014-09-07 07:23:55

标签: android json android-fragments android-listview android-volley

我是Android编程的新手,所以问题仍然很基础。我正在使用一个片段内的volley库,它获取一个json对象列表,然后将其添加到列表视图中。我处理片段的onCreate方法中的所有数据密集型代码,并将json保存为字符串。然后,我将字符串放在bundle outstate中,以便在重新创建片段后获取数据。在oncreate方法中,我执行if else来检查bundle是否有任何数据。然后我相应地更新视图项。但应用程序崩溃时出现空指针异常。这是我片段的代码。

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);
}

}

我的第一个问关于stackoverflow的问题,所以请耐心等待。

编辑:这是logcat(只是必需的片段)。

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)

3 个答案:

答案 0 :(得分:0)

尝试将您的oncreate代码放在View和return之间的oncreateview上。如果这没有帮助发布nullpointer日志。

答案 1 :(得分:0)

当您尝试在println needs a message中记录null时,会出现onStart() NPE:

Log.e(ARG_RESPONSE, JSONResponse);

似乎JSONResponse似乎只在生命周期的后期初始化。如果您坚持记录它,则可以将日志arg强制为非空字符串,例如通过附加一个空字符串:

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

答案 2 :(得分:0)

Log.e(ARG_RESPONSE,JSONResponse); JSONResponse为null,我认为你应该替换你的JSON检索代码,如果不在oncreate或onstart取决于你,也可以在onResume上读取它也可能有帮助。调试它的最佳方法是避免声明空值。最好将其声明为JSONParser响应;或类似的东西和Log.e(ARG_RESPONSE,JSONResponse.toString());