【发布时间】:2017-09-13 15:05:05
【问题描述】:
我正在开发一个小型人员应用程序来帮助我学习 Android 开发和 Java。
首先让我让大家知道 Google 地图部分正在应用中运行。它在应用启动并获取手机的正确当前位置时加载。
另外,我的 JSON 文件也可以正常工作。数据是使用他们的 API 从 www.wunderground.com 提取的,我的代码抓取了我所要求的内容并创建了一个 Arraylist 并很好地填充它并在应用程序中按应有的方式显示它。
问题是,我正在尝试获取一些 JSON 数据,并创建一个谷歌地图标记对象并将其显示在地图上。
下面是我的代码:
这个方法是从它从 JsonData.java 获得的 JSON 数据创建一个 Cyclone 对象,我将在下面展示。
Cyclone.java
public class Cyclone {
// Category of the cyclone (e.g. -2, -1, 0, 1, 2, 3, 4, or 5)
private int category;
// Latitude & Longitude of Cyclone
private float latitude, longitude;
// Cyclone name
private String name;
// Cyclone heading (N, S, E, or W)
private String heading;
// Wind speed in Cyclone
private String windSpeedKnots;
// Url to website with Cyclone data
private String url;
/**
* CONSTRUCTOR
* Create a new Cyclone object.
*
* @param constCategory is the category of the cyclone (e.g. -2, -1, 0, 1, 2, 3, 4, or 5)
* @param constLatitude is the Latitude of the cyclone
* @param constLongitude is the Longitude of the cyclone
* @param constName is the name of the Cyclone
* @param constHeading is the direction the cyclone is moving
* @param constWindSpeedKnots is the speed of the wind the Cyclone is producing
* @param constUrl is the url of the website that is providing the data
*/
public Cyclone(int constCategory, float constLatitude, float constLongitude,String constName,
String constHeading, String constWindSpeedKnots, String constUrl) {
category = constCategory;
latitude = constLatitude;
longitude = constLongitude;
name = constName;
heading = constHeading;
windSpeedKnots = constWindSpeedKnots;
url = constUrl;
}
/**
* Setting public getters for the private variables above for use of other classes
*/
// Get the storm category
public int getCategory() {
return category;
}
// Get the cyclones Latitude
public float getLatitude() {
return latitude;
}
//Get the cyclones Longitude
public float getLongitude() {
return longitude;
}
// Get the cyclones name
public String getName() {
return name;
}
// Get the cyclones heading
public String getHeading() {
return heading;
}
// Get the cyclones wind speed
public String getWindSpeedKnots() {
return windSpeedKnots;
}
// Get the Url
public String getUrl() {
return url;
}
}
此类从 www.wunderground.com 提取 JSON 数据。我已经从底部切断了一堆代码。如果没有返回,它主要只是处理异常。 JsonData.java
/**
* Return a list of {@link Cyclone} objects that has been built up from
* parsing a JSON response.
*/
public static ArrayList<Cyclone> extractFeatureFromJson(String cycloneJSON) {
// Create an empty ArrayList to start adding Cyclones to
ArrayList<Cyclone> cyclones = new ArrayList<>();
// Try to parse the cycloneJSON response string. If there's a problem with the way the JSON
// is formatted, a JSONException exception object will be thrown.
// Catch the exception , and print the error message to the logs.
try {
JSONObject rootJsonObject = new JSONObject(cycloneJSON);
// Create JSONArray associated with the key called "currenthurricane", which represents
// a list of cyclones from JSON response.
JSONArray currentHurricaneArray = rootJsonObject.getJSONArray("currenthurricane");
/**
* Loop through each section in the currentHurricaneArray array & create an
* {@link Cyclone} object for each one
*
*/
for (int i = 0; i < currentHurricaneArray.length(); i++) {
//Get cyclone JSONObject at position i in the array
JSONObject cycloneProperties = currentHurricaneArray.getJSONObject(i);
// Extract "stormInfo" object
JSONObject stormInfo = cycloneProperties.optJSONObject("stormInfo");
//Extract “stormName_Nice” & "requesturl" for Cyclone's name and url
String name = stormInfo.optString("stormName_Nice");
String url = stormInfo.optString("wuiurl");
// Extract "Current" object
JSONObject current = cycloneProperties.optJSONObject("Current");
// Extract "SaffirSimpsonCategory" key
int category = current.optInt("SaffirSimpsonCategory");
//Extract "Lat" & "Lon" keys to get cyclone position
float latitude = (float) current.optDouble("lat");
float longitude = (float) current.optDouble("lon");
//Extract "WindSpeed" object
JSONObject windSpeed = current.optJSONObject("WindSpeed");
//Extract wind speed in "Knots" Key
int Kts = windSpeed.optInt("Kts");
String knots = Kts + " Knots";
//Extract "Movement" object
JSONObject movement = current.optJSONObject("Movement");
//Extract movement direction in "Text" key
String direction = movement.optString("Text");
Cyclone cyclone = new Cyclone(category, latitude, longitude, name, direction, knots, url);
//Add new cyclone to list
cyclones.add(cyclone);
}
我将在这里展示相关的部分。
MainActivity.java
public class MainActivity extends AppCompatActivity implements
LoaderManager.LoaderCallbacks<List<Cyclone>>,
OnMapReadyCallback,
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
LocationListener {
....
//Creating a Cyclone object, calling it from Cyclone.java
Cyclone trackedCyclone = null;
//getting the three bits of info I need/want (Name, lat, lon)
String name = trackedCyclone.getName();
float lat = trackedCyclone.getLatitude();
float lon = trackedCyclone.getLongitude();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.cyclone_list);
....
// Obtain the SupportMapFragment and get notified when the map is ready
//Calling up the map fragment from cyclone_list.xml
MapFragment mapFragment = (MapFragment) getFragmentManager().findFragmentById(R.id.google_map);
mapFragment.getMapAsync(this);
....
@Override
public void onMapReady(GoogleMap mapLocalInstance) {
//Setting mapReady to true
mapReady = true;
//displaying cyclone map marker on the map
LatLng cycloneMarker = new LatLng(lat, lon);
googleMap.addMarker(new MarkerOptions().position(cycloneMarker).title(name));
//Loading local instance map from Callback
googleMap = mapLocalInstance;
googleMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
//checks for permission using the Support library before enabling the My Location layer
//Initialize Google Play Services
if (android.os.Build.VERSION.SDK_INT >= M) {
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
buildGoogleApiClient();
googleMap.setMyLocationEnabled(true);
}
} else {
buildGoogleApiClient();
googleMap.setMyLocationEnabled(true);
}
}
当应用程序启动时,它会崩溃并显示以下内容:
04-17 16:11:29.546 7028-7028/com.palarran.cycloops E/AndroidRuntime: 致命异常: main 进程:com.palarran.cycloops,PID:7028 java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法“java.lang.String com.palarran.cycloops.Cyclone.getName()” 在 com.palarran.cycloops.MainActivity.onMapReady(MainActivity.java:266) 在 com.google.android.gms.maps.MapFragment$zza$1.zza(未知来源) 在 com.google.android.gms.maps.internal.zzt$zza.onTransact(未知来源) 在 android.os.Binder.transact(Binder.java:499) 在 com.google.android.gms.maps.internal.bw.a(:com.google.android.gms.DynamiteModulesB:82) 在 com.google.maps.api.android.lib6.impl.bf.run(:com.google.android.gms.DynamiteModulesB:1805) 在 android.os.Handler.handleCallback(Handler.java:751) 在 android.os.Handler.dispatchMessage(Handler.java:95) 在 android.os.Looper.loop(Looper.java:154) 在 android.app.ActivityThread.main(ActivityThread.java:6121) 在 java.lang.reflect.Method.invoke(本机方法) 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:889) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:779)
我只在 Android 和 Java 上玩了大约一年。所以OOP对我来说还是很新的。我不明白很多。我有一半认为问题在于,由于 JsonData.java 类正在创建 JsonArray,我可能无法使用 Cyclone.java 调用我需要的部分> 类。如果是这种情况,那么我要创建不同的 JsonArray 吗?这对我来说似乎很笨拙?但我真的不知道。
感谢您提供的任何帮助。
【问题讨论】:
-
Cyclone trackedCyclone = null;不会创建Cyclone对象,如相应行上方的注释所述。以下行崩溃。
标签: java android json google-maps