Open yanickv opened 6 years ago
Possibly because the onSceneReady that was posted on the UI thread gets callled after the com.mapzen.tangram.MapView disposeMap() method was called.
// Called from JNI on worker or render-thread.
void sceneReadyCallback(final int sceneId, final SceneError error) {
final SceneLoadListener cb = sceneLoadListener;
if (cb != null) {
uiThreadHandler.post(new Runnable() {
@Override
public void run() {
cb.onSceneReady(sceneId, error);
}
});
}
}
The com.mapzen.tangram.MapView disposeMap() method sets the mapController to null but does not free the GLSurfaceView.
protected void disposeMap() {
if (mapController != null) {
// MapController has been initialized, so we'll dispose it now.
mapController.dispose();
}
mapController = null;
}
Then when the MapView.getMap gets called the mapController is null so it creates a new MapController.
public MapController getMap(MapController.SceneLoadListener listener) {
if (mapController != null) {
return mapController;
}
mapController = getMapInstance();
mapController.setSceneLoadListener(listener);
mapController.init();
return mapController;
}
protected MapController getMapInstance() {
return new MapController(glSurfaceView);
}
And the MapController constructor calls view.setRenderer(this), but the view (which is the old undisposed GLSurfaceView) already has a renderer. Then setRenderer throws this IllegalStateException.
Description
GLSurfaceView IllegalStateException: setRenderer has already been called for this instance. Happens on line 211 of MapController.js (in call to view.setRenderer(this))
Here is the call stack:
06-06 22:33:19.824 16800-16800/AndroidRuntime: FATAL EXCEPTION: main java.lang.IllegalStateException: setRenderer has already been called for this instance. at android.opengl.GLSurfaceView.checkRenderThreadState(GLSurfaceView.java:1893) at android.opengl.GLSurfaceView.setRenderer(GLSurfaceView.java:348) at com.mapzen.tangram.MapController.(MapController.java:211)
at com.mapzen.tangram.MapView.getMapInstance(MapView.java:49)
at com.mapzen.tangram.MapView.getMap(MapView.java:41)
at com.mapzen.android.graphics.MapReadyInitializer.onMapReady(MapReadyInitializer.java:29)
at com.mapzen.android.graphics.MapInitializer$1.onSceneReady(MapInitializer.java:113)
at com.mapzen.tangram.MapController$14.run(MapController.java:1355)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6940)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
Steps to Reproduce
To reproduce you must rotate the phone 90 degree and rotate it back -90 degree quickly. It must be rotated back -90 degree so that your MainActivity onStop gets called before the onMapReady gets called.
Mapzen SDK & Android Version
Mapzen 1.6.1. Android 8 Oreo.