[英]Android fragment onCreate not working?
I am new to android programming so the question is still pretty basic. 我是android编程的新手,所以问题仍然很基本。 I am working with volley library inside a fragment, which gets a list of json objects and then add it to the list view. 我正在一个片段中使用volley库,该片段获取json对象的列表,然后将其添加到列表视图中。 I handle all the data intensive code in the onCreate method of the fragment and save the json as string. 我在该片段的onCreate方法中处理所有数据密集型代码,并将json保存为字符串。 I then put the string in the bundle outstate to get the data once the fragment is recreated. 然后,在重新创建片段后,将字符串放入bundle outstate以获取数据。 In the oncreate method I do a if else to check whether the bundle has any data or not. 在oncreate方法中,如果不是,则检查捆绑包是否有任何数据。 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. 这是我第一次问有关stackoverflow的问题,所以请耐心等待。
EDIT: Here is the logcat(just the required snippet). 编辑:这是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)
Try to put your oncreate codes to oncreateview in-between View and return. 尝试将您的oncreate代码放在View和return之间的oncreateview上。 If that doesn't help post the nullpointer log. 如果这样不帮助发布nullpointer日志。
Your println needs a message
NPE comes when you try to log a null
here in onStart()
: 当您尝试在onStart()
记录null
时,您的println needs a message
NPE到来:
Log.e(ARG_RESPONSE, JSONResponse);
Seems like JSONResponse
is initialized possibly only later in the lifecycle. 似乎JSONResponse
可能仅在生命周期的后期才初始化。 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 arg强制为非空字符串,例如,通过添加空字符串:
Log.e(ARG_RESPONSE, "" + JSONResponse);
The Log.e(ARG_RESPONSE, JSONResponse); 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. JSONResponse为空,如果不在oncreate或onstart中取决于您,我认为您应该替换JSON检索的代码,也请阅读onResume可能也有帮助。 Best way to debug this is to avoid having to declare nulls. 调试此错误的最佳方法是避免必须声明null。 better to declare it as JSONParser response; 最好将其声明为JSONParser响应; or something like that and Log.e(ARG_RESPONSE, JSONResponse.toString()); 或类似的东西和Log.e(ARG_RESPONSE,JSONResponse.toString());
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.