我试图通过演示使用连续的雷达图像阵列的连续GroundOverlay
来在Google地图上显示渐进式雷达图像。为了不使用户界面繁忙,我为此使用了另一个线程。不幸的是,似乎正在发生怪异的NullPointerException
。我已经调试了代码,但是没有找到任何可能导致此错误的空变量。
我该怎么办?
我将仅显示相关代码:(请注意,radaroverlay,map,images,image_index和MAP_BOUNDS是全局变量,并且不为null-请参见1)。
编辑-简化了下面的代码。仍然给出完全相同的错误。
public void createLooper() {
final Runnable runnable = new Runnable() {
public void run() {
if(run == true) {
mHandler.postDelayed(this,500);
} else {
return;
}
if(radaroverlay != null) {
radaroverlay.remove();
}
// Problem happens in the line below.
try {
GroundOverlayOptions opts = new GroundOverlayOptions()
.image(images[image_index])
.positionFromBounds(MAP_BOUNDS)
.transparency((float) 0.3);
radaroverlay = map.addGroundOverlay(opts);
} catch (Exception e) {
e.printStackTrace();
run = false;
}
if(image_index == 19) {
image_index = 0;
} else {
image_index++;
}
}
};
//mHandler.postDelayed(runnable, 500);
new Thread(runnable).start();
并对应的
logcat
02-27 16:58:04.815: E/AndroidRuntime(6791): FATAL EXCEPTION: main
02-27 16:58:04.815: E/AndroidRuntime(6791): java.lang.NullPointerException
02-27 16:58:04.815: E/AndroidRuntime(6791): at maps.z.aa.<init>(Unknown Source)
02-27 16:58:04.815: E/AndroidRuntime(6791): at maps.z.bi.a(Unknown Source)
02-27 16:58:04.815: E/AndroidRuntime(6791): at maps.z.bi.b(Unknown Source)
02-27 16:58:04.815: E/AndroidRuntime(6791): at maps.z.ag.addGroundOverlay(Unknown Source)
02-27 16:58:04.815: E/AndroidRuntime(6791): at com.google.android.gms.maps.internal.IGoogleMapDelegate$Stub.onTransact(IGoogleMapDelegate.java:182)
02-27 16:58:04.815: E/AndroidRuntime(6791): at android.os.Binder.transact(Binder.java:249)
02-27 16:58:04.815: E/AndroidRuntime(6791): at com.google.android.gms.maps.internal.IGoogleMapDelegate$a$a.addGroundOverlay(Unknown Source)
02-27 16:58:04.815: E/AndroidRuntime(6791): at com.google.android.gms.maps.GoogleMap.addGroundOverlay(Unknown Source)
02-27 16:58:04.815: E/AndroidRuntime(6791): at com.aquamet.saramap.MapActivity$2$1.run(MapActivity.java:520)
02-27 16:58:04.815: E/AndroidRuntime(6791): at android.os.Handler.handleCallback(Handler.java:587)
02-27 16:58:04.815: E/AndroidRuntime(6791): at android.os.Handler.dispatchMessage(Handler.java:92)
02-27 16:58:04.815: E/AndroidRuntime(6791): at android.os.Looper.loop(Looper.java:123)
02-27 16:58:04.815: E/AndroidRuntime(6791): at android.app.ActivityThread.main(ActivityThread.java:4627)
02-27 16:58:04.815: E/AndroidRuntime(6791): at java.lang.reflect.Method.invokeNative(Native Method)
02-27 16:58:04.815: E/AndroidRuntime(6791): at java.lang.reflect.Method.invoke(Method.java:521)
02-27 16:58:04.815: E/AndroidRuntime(6791): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:876)
02-27 16:58:04.815: E/AndroidRuntime(6791): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:634)
02-27 16:58:04.815: E/AndroidRuntime(6791): at dalvik.system.NativeStart.main(Native Method)
调试:
最佳答案
好吧,事实证明,问题是当我使用一个线程更新GroundOverlays时,虽然我可以读取变量(如果是在创建新线程之前由主线程编写的,则是这样),但是我无法写入变量,并且期望主线程得到相同的结果。
这解释了为什么我可以生成opts(从images
,image_index
和MAP_BOUND
读取),但是不能使地图设置新的GroundOverlay(写入map
对象)。
我最终使用了runOnUiThread而不是线程,它可以处理并发变量问题。
结果代码:
public void createLooper() {
final Runnable runnable = new Runnable() {
public void run() {
if(run == true) {
mHandler.postDelayed(this,500);
} else {
return;
}
if(image_index == img_size) {
image_index = 0;
}
if(radaroverlay != null) {
radaroverlay.remove();
}
// Problem happens in the line below.
try {
GroundOverlayOptions opts = new GroundOverlayOptions()
.image(images[image_index])
.positionFromBounds(MAP_BOUNDS)
.transparency((float) 0.3);
radaroverlay = map.addGroundOverlay(opts);
image_index++;
} catch (Exception e) {
e.printStackTrace();
run = false;
}
}
};
runOnUiThread(runnable);
}