Java tutorial
/* * PanoramaGL library * Version 0.2 beta * Copyright (c) 2010 Javier Baez <javbaezga@gmail.com> * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.panoramagl.loaders; import java.util.HashMap; import java.util.Locale; import java.util.Map; import org.json.JSONArray; import org.json.JSONObject; import android.graphics.Bitmap; import com.panoramagl.PLBlankPanorama; import com.panoramagl.PLConstants; import com.panoramagl.PLCubicPanorama; import com.panoramagl.PLCylindricalPanorama; import com.panoramagl.PLICamera; import com.panoramagl.PLIImage; import com.panoramagl.PLIPanorama; import com.panoramagl.PLIQuadricPanorama; import com.panoramagl.PLITexture; import com.panoramagl.PLIView; import com.panoramagl.PLImage; import com.panoramagl.PLSpherical2Panorama; import com.panoramagl.PLSphericalPanorama; import com.panoramagl.PLTexture; import com.panoramagl.downloaders.PLFileDownloaderListener; import com.panoramagl.downloaders.PLHTTPFileDownloader; import com.panoramagl.downloaders.PLLocalFileDownloader; import com.panoramagl.enumerations.PLCameraParameterType; import com.panoramagl.enumerations.PLCubeFaceOrientation; import com.panoramagl.enumerations.PLPanoramaType; import com.panoramagl.enumerations.PLTextureColorFormat; import com.panoramagl.enumerations.PLViewParameterType; import com.panoramagl.hotspots.PLHotspot; import com.panoramagl.hotspots.PLIHotspot; import com.panoramagl.structs.PLCameraParameters; import com.panoramagl.structs.PLViewParameters; import com.panoramagl.transitions.PLITransition; import com.panoramagl.transitions.PLTransitionListener; import com.panoramagl.utils.PLLog; import com.panoramagl.utils.PLUtils; public class PLJSONLoader extends PLLoaderBase { /**member variables*/ private PLIView mView; private PLITransition mTransition; private float mInitialPitch, mInitialYaw; private byte[] mJSONData; private String mURL; private JSONObject mJSON; private boolean mIsPreloadingImages; private PLViewParameters mKeepParameters; private Map<String, PLITexture> mHotspotTextures; /**init methods*/ public PLJSONLoader(byte[] jsonData) { super(); mJSONData = jsonData; } public PLJSONLoader(String url) { super(); mURL = url.trim(); } @Override protected void initializeValues() { super.initializeValues(); mView = null; mTransition = null; mInitialPitch = mInitialYaw = PLConstants.kFloatUndefinedValue; mJSONData = null; mURL = null; mJSON = null; mIsPreloadingImages = true; mKeepParameters = null; mHotspotTextures = new HashMap<String, PLITexture>(); } /**property methods*/ protected PLIView getView() { return mView; } protected void setView(PLIView view) { mView = view; } protected PLITransition getTransition() { return mTransition; } protected void setTransition(PLITransition transition) { mTransition = transition; } protected byte[] getJSONData() { return mJSONData; } protected void setJSONData(byte[] jsonData) { mJSONData = jsonData; } protected String getURL() { return mURL; } protected void setURL(String url) { mURL = url; } protected JSONObject getJSON() { return mJSON; } protected void setJSON(JSONObject json) { mJSON = json; } protected boolean isPreloadingImages() { return mIsPreloadingImages; } protected void setPreloadingImages(boolean isPreloadingImages) { mIsPreloadingImages = isPreloadingImages; } protected Map<String, PLITexture> getHotspotTextures() { return mHotspotTextures; } /**utility methods*/ protected String buildURL(String url, String urlBase) { url = url.trim(); if (url.indexOf("://") == -1) url = urlBase + (urlBase.endsWith("/") || url.startsWith("/") ? url : "/" + url); return url; } protected boolean isHTTPURL(String url) { return (url.startsWith("http://") || url.startsWith("https://")); } protected PLIImage getLocalImage(String url, PLTextureColorFormat colorFormat) { Bitmap bitmap = PLUtils.getBitmap(mView.getActivity().getApplicationContext(), url, colorFormat); return (bitmap != null ? new PLImage(bitmap, false) : null); } protected PLIImage getLocalImageAsynchronously(String url, PLTextureColorFormat colorFormat) { PLIImage result = new PLImage(); mView.getDownloadManager().add(new PLLocalFileDownloader(mView.getActivity().getApplicationContext(), url, new PLImageFileDownloaderListener(result, colorFormat))); return result; } /**json methods*/ protected void requestJSON(PLFileDownloaderListener listener) { try { if (mURL != null) { if (this.isHTTPURL(mURL)) new PLHTTPFileDownloader(mURL, listener).downloadAsynchronously(); else new PLLocalFileDownloader(mView.getActivity().getApplicationContext(), mURL, listener) .downloadAsynchronously(); } else if (mJSONData != null) new Thread(new PLDataRunnable(listener, mURL, mJSONData, System.currentTimeMillis())).start(); else listener.didErrorDownload(mURL, "JSON string is empty", -1, null); } catch (Throwable e) { PLLog.error("PLJSONLoader::requestJSON", e); listener.didErrorDownload(mURL, e.getMessage(), -1, null); } } protected void parseJSON(byte[] jsonData) { try { mJSON = new JSONObject(new String(jsonData, "utf-8")); String urlBase = mJSON.getString("urlBase").trim(); if (urlBase == null) throw new RuntimeException("urlBase property not exists"); else if (!this.isHTTPURL(urlBase) && !urlBase.startsWith("res://") && !urlBase.startsWith("file://")) throw new RuntimeException("urlBase property is wrong"); String type = mJSON.getString("type").trim(); final PLIPanorama panorama; PLPanoramaType panoramaType = PLPanoramaType.PLPanoramaTypeUnknow; if (type != null) { if (type.equals("spherical")) { panoramaType = PLPanoramaType.PLPanoramaTypeSpherical; panorama = new PLSphericalPanorama(); } else if (type.equals("spherical2")) { panoramaType = PLPanoramaType.PLPanoramaTypeSpherical2; panorama = new PLSpherical2Panorama(); } else if (type.equals("cubic")) { panoramaType = PLPanoramaType.PLPanoramaTypeCubic; panorama = new PLCubicPanorama(); } else if (type.equals("cylindrical")) { panoramaType = PLPanoramaType.PLPanoramaTypeCylindrical; panorama = new PLCylindricalPanorama(); } else throw new RuntimeException("Panorama type is wrong"); } else throw new RuntimeException("type property not exists"); PLTextureColorFormat colorFormat = PLTextureColorFormat.PLTextureColorFormatRGBA8888; if (mJSON.has("imageColorFormat")) { String imageColorFormat = mJSON.getString("imageColorFormat").trim().toUpperCase(Locale.US); if (imageColorFormat.equals("RGB565")) colorFormat = PLTextureColorFormat.PLTextureColorFormatRGB565; else if (imageColorFormat.equals("RGBA4444")) colorFormat = PLTextureColorFormat.PLTextureColorFormatRGBA4444; } if (panoramaType == PLPanoramaType.PLPanoramaTypeCylindrical && mJSON.has("height")) ((PLCylindricalPanorama) panorama).setHeight((float) mJSON.getDouble("height")); if (mJSON.has("divisions") && panorama instanceof PLIQuadricPanorama) { JSONObject divisions = mJSON.getJSONObject("divisions"); if (divisions != null) { PLIQuadricPanorama quadricPanorama = (PLIQuadricPanorama) panorama; if (divisions.has("preview")) quadricPanorama.setPreviewDivs(divisions.getInt("preview")); if (divisions.has("panorama")) quadricPanorama.setDivs(divisions.getInt("panorama")); } } PLIPanorama oldPanorama = mView.getPanorama(); mKeepParameters = (oldPanorama != null && !(oldPanorama instanceof PLBlankPanorama) && mJSON.has("keep") ? PLViewParameterType.checkViewParametersWithStringMask(mJSON.getString("keep")) : PLViewParameterType.checkViewParametersWithMask(PLViewParameterType.PLViewParameterTypeNone)); if (!mKeepParameters.reset && mJSON.has("reset")) { JSONObject reset = mJSON.getJSONObject("reset"); if (reset != null) { if (reset.has("enabled")) mView.setResetEnabled(reset.getBoolean("enabled")); if (reset.has("numberOfTouches")) mView.setNumberOfTouchesForReset(reset.getInt("numberOfTouches")); if (reset.has("shake")) { JSONObject shake = reset.getJSONObject("shake"); if (shake != null) { if (shake.has("enabled")) mView.setShakeResetEnabled(shake.getBoolean("enabled")); if (shake.has("threshold")) mView.setShakeThreshold((float) shake.getDouble("threshold")); } } } } if (!mKeepParameters.scrolling && mJSON.has("scrolling")) { JSONObject scrolling = mJSON.getJSONObject("scrolling"); if (scrolling != null) { if (scrolling.has("enabled")) mView.setScrollingEnabled(scrolling.getBoolean("enabled")); if (scrolling.has("minDistanceToEnableScrolling")) mView.setMinDistanceToEnableScrolling(scrolling.getInt("minDistanceToEnableScrolling")); } } if (!mKeepParameters.inertia && mJSON.has("inertia")) { JSONObject inertia = mJSON.getJSONObject("inertia"); if (inertia != null) { if (inertia.has("enabled")) mView.setInertiaEnabled(inertia.getBoolean("enabled")); if (inertia.has("interval")) mView.setInertiaInterval((float) inertia.getDouble("interval")); } } if (!mKeepParameters.accelerometer && mJSON.has("accelerometer")) { JSONObject accelerometer = mJSON.getJSONObject("accelerometer"); if (accelerometer != null) { if (accelerometer.has("enabled")) mView.setAccelerometerEnabled(accelerometer.getBoolean("enabled")); if (accelerometer.has("interval")) mView.setAccelerometerInterval((float) accelerometer.getDouble("interval")); if (accelerometer.has("sensitivity")) mView.setAccelerometerSensitivity((float) accelerometer.getDouble("sensitivity")); if (accelerometer.has("leftRightEnabled")) mView.setAccelerometerLeftRightEnabled(accelerometer.getBoolean("leftRightEnabled")); if (accelerometer.has("upDownEnabled")) mView.setAccelerometerUpDownEnabled(accelerometer.getBoolean("upDownEnabled")); } } boolean hasPreviewImage = false; JSONObject images = mJSON.getJSONObject("images"); if (images != null) { if (images.has("preview")) { String previewURL = this.buildURL(images.getString("preview"), urlBase); if (this.isHTTPURL(previewURL)) { byte[] previewData = new PLHTTPFileDownloader(previewURL).download(); if (previewData != null) { panorama.setPreviewImage(new PLImage(previewData)); hasPreviewImage = true; } } else { PLIImage previewImage = this.getLocalImage(previewURL, colorFormat); if (previewImage != null) { panorama.setPreviewImage(previewImage); hasPreviewImage = true; } } } if (mHotspotTextures.size() > 0) mHotspotTextures.clear(); JSONArray hotspots = mJSON.getJSONArray("hotspots"); if (hotspots != null) { for (int i = 0, hotspotsCount = hotspots.length(); i < hotspotsCount; i++) { JSONObject hotspot = hotspots.getJSONObject(i); if (hotspot != null) { if (hotspot.has("image")) { long identifier = (hotspot.has("id") ? hotspot.getLong("id") : -1); float atv = (hotspot.has("atv") ? (float) hotspot.getDouble("atv") : 0.0f); float ath = (hotspot.has("ath") ? (float) hotspot.getDouble("ath") : 0.0f); float width = (hotspot.has("width") ? (float) hotspot.getDouble("width") : PLConstants.kDefaultHotspotSize); float height = (hotspot.has("height") ? (float) hotspot.getDouble("height") : PLConstants.kDefaultHotspotSize); PLIHotspot currentHotspot = new PLHotspot(identifier, atv, ath, width, height); if (hotspot.has("alpha")) { currentHotspot.setDefaultAlpha((float) hotspot.getDouble("alpha")); currentHotspot.setAlpha(currentHotspot.getDefaultAlpha()); } if (hotspot.has("overAlpha")) { currentHotspot.setDefaultOverAlpha((float) hotspot.getDouble("overAlpha")); currentHotspot.setOverAlpha(currentHotspot.getDefaultOverAlpha()); } if (hotspot.has("onClick")) currentHotspot.setOnClick(hotspot.getString("onClick")); this.loadHotspotTexture(currentHotspot, hotspot.getString("image"), urlBase, colorFormat); panorama.addHotspot(currentHotspot); } } } mHotspotTextures.clear(); } if (panoramaType == PLPanoramaType.PLPanoramaTypeCubic) { PLCubicPanorama cubicPanorama = (PLCubicPanorama) panorama; this.loadCubicPanoramaImage(cubicPanorama, PLCubeFaceOrientation.PLCubeFaceOrientationFront, images, "front", urlBase, hasPreviewImage, colorFormat); this.loadCubicPanoramaImage(cubicPanorama, PLCubeFaceOrientation.PLCubeFaceOrientationBack, images, "back", urlBase, hasPreviewImage, colorFormat); this.loadCubicPanoramaImage(cubicPanorama, PLCubeFaceOrientation.PLCubeFaceOrientationLeft, images, "left", urlBase, hasPreviewImage, colorFormat); this.loadCubicPanoramaImage(cubicPanorama, PLCubeFaceOrientation.PLCubeFaceOrientationRight, images, "right", urlBase, hasPreviewImage, colorFormat); this.loadCubicPanoramaImage(cubicPanorama, PLCubeFaceOrientation.PLCubeFaceOrientationUp, images, "up", urlBase, hasPreviewImage, colorFormat); this.loadCubicPanoramaImage(cubicPanorama, PLCubeFaceOrientation.PLCubeFaceOrientationDown, images, "down", urlBase, hasPreviewImage, colorFormat); } else { if (images.has("image")) { String imageURL = this.buildURL(images.getString("image"), urlBase); if (this.isHTTPURL(imageURL)) mView.getDownloadManager().add(new PLHTTPFileDownloader(imageURL, new PLPanoramaImageFileDownloaderListener(panorama, colorFormat))); else if (panoramaType == PLPanoramaType.PLPanoramaTypeSpherical2) ((PLSpherical2Panorama) panorama).setImage(this.getLocalImage(imageURL, colorFormat)); else if (panorama instanceof PLIQuadricPanorama) ((PLIQuadricPanorama) panorama) .setImage(this.getLocalImageAsynchronously(imageURL, colorFormat)); } else if (!hasPreviewImage) throw new RuntimeException("images.image and images.preview properties not exist"); } if (images.has("preload")) mIsPreloadingImages = images.getBoolean("preload"); } else throw new RuntimeException("images property not exists"); if (mIsPreloadingImages) mView.getDownloadManager().start(); mView.getActivity().runOnUiThread(new Runnable() { @Override public void run() { mView.reset(false); if (mTransition != null && mView.getPanorama() != null) { mTransition.getListeners().add(new PLTransitionListener() { @Override public boolean isRemovableListener() { return true; } @Override public void didBeginTransition(PLITransition transition) { synchronized (transition) { parseCameraJSON(transition.getNewPanorama()); } } @Override public void didProcessTransition(PLITransition transition, int progressPercentage) { } @Override public void didStopTransition(PLITransition transition, int progressPercentage) { if (parseSensorialRotationJSON()) { mView.getDownloadManager().removeAll(); didStop(true); } } @Override public void didEndTransition(PLITransition transition) { if (parseSensorialRotationJSON()) { if (!mIsPreloadingImages) mView.getDownloadManager().start(); didComplete(true); } } }); mView.startTransition(mTransition, panorama); } else { if (parseCameraJSON(panorama)) { mView.setPanorama(panorama); if (parseSensorialRotationJSON()) { if (!mIsPreloadingImages) mView.getDownloadManager().start(); didComplete(false); } } } } }); } catch (Throwable e) { this.didError(e); } } protected boolean parseCameraJSON(PLIPanorama panorama) { try { JSONObject camera = mJSON.getJSONObject("camera"); if (camera != null) { PLIPanorama oldPanorama = mView.getPanorama(); PLICamera oldCamera = (oldPanorama != null && !(oldPanorama instanceof PLBlankPanorama) ? oldPanorama.getCamera() : null); PLICamera currentCamera = panorama.getCamera(); PLCameraParameters keep = (oldCamera != null && camera.has("keep") ? PLCameraParameterType.checkCameraParametersWithStringMask(camera.getString("keep")) : PLCameraParameterType .checkCameraParametersWithMask(PLCameraParameterType.PLCameraParameterTypeNone)); float pitch = currentCamera.getInitialPitch(), yaw = currentCamera.getInitialYaw(); if (keep.atvMin) currentCamera.setPitchMin(oldCamera.getPitchMin()); else if (camera.has("atvMin")) currentCamera.setPitchMin((float) camera.getDouble("atvMin")); if (keep.atvMax) currentCamera.setPitchMax(oldCamera.getPitchMax()); else if (camera.has("atvMax")) currentCamera.setPitchMax((float) camera.getDouble("atvMax")); if (keep.athMin) currentCamera.setYawMin(oldCamera.getYawMin()); else if (camera.has("athMin")) currentCamera.setYawMin((float) camera.getDouble("athMin")); if (keep.athMax) currentCamera.setYawMax(oldCamera.getYawMax()); else if (camera.has("athMax")) currentCamera.setYawMax((float) camera.getDouble("athMax")); if (keep.reverseRotation) currentCamera.setReverseRotation(oldCamera.isReverseRotation()); else if (camera.has("reverseRotation")) currentCamera.setReverseRotation(camera.getBoolean("reverseRotation")); if (keep.rotationSensitivity) currentCamera.setRotationSensitivity(oldCamera.getRotationSensitivity()); else if (camera.has("rotationSensitivity")) currentCamera.setRotationSensitivity((float) camera.getDouble("rotationSensitivity")); if (mInitialPitch != PLConstants.kFloatUndefinedValue) pitch = mInitialPitch; else if (keep.vLookAt) pitch = oldCamera.getLookAtRotation().pitch; else if (camera.has("vLookAt")) pitch = (float) camera.getDouble("vLookAt"); if (mInitialYaw != PLConstants.kFloatUndefinedValue) yaw = mInitialYaw; else if (keep.hLookAt) yaw = oldCamera.getLookAtRotation().yaw; else if (camera.has("hLookAt")) yaw = (float) camera.getDouble("hLookAt"); currentCamera.setInitialLookAt(pitch, yaw); currentCamera.lookAt(pitch, yaw); if (keep.zoomLevels) currentCamera.setZoomLevels(oldCamera.getZoomLevels()); else if (camera.has("zoomLevels")) currentCamera.setZoomLevels(camera.getInt("zoomLevels")); if (keep.fovMin) currentCamera.setFovMin(oldCamera.getFovMin()); else if (camera.has("fovMin")) currentCamera.setFovMin((float) camera.getDouble("fovMin")); if (keep.fovMax) currentCamera.setFovMax(oldCamera.getFovMax()); else if (camera.has("fovMax")) currentCamera.setFovMax((float) camera.getDouble("fovMax")); if (keep.fovSensitivity) currentCamera.setFovSensitivity(oldCamera.getFovSensitivity()); else if (camera.has("fovSensitivity")) currentCamera.setFovSensitivity((float) camera.getDouble("fovSensitivity")); if (keep.fov) currentCamera.setFov(oldCamera.getFov()); else if (camera.has("fov")) currentCamera.setFov((float) camera.getDouble("fov")); else if (camera.has("fovFactor")) currentCamera.setFovFactor((float) camera.getDouble("fovFactor")); else if (camera.has("zoomFactor")) currentCamera.setZoomFactor((float) camera.getDouble("zoomFactor")); else if (camera.has("zoomLevel")) currentCamera.setZoomLevel(camera.getInt("zoomLevel")); } } catch (Throwable e) { this.didError(e); return false; } return true; } protected boolean parseSensorialRotationJSON() { try { if (!mKeepParameters.sensorialRotation && mJSON.has("sensorialRotation")) { if (mJSON.getBoolean("sensorialRotation")) { if (!mView.startSensorialRotation()) mView.updateInitialSensorialRotation(); } else mView.stopSensorialRotation(); } else mView.updateInitialSensorialRotation(); } catch (Throwable e) { this.didError(e); return false; } return true; } /**load methods*/ protected void loadCubicPanoramaImage(PLCubicPanorama panorama, PLCubeFaceOrientation face, JSONObject images, String property, String urlBase, boolean hasPreviewImage, PLTextureColorFormat colorFormat) throws Exception { if (images.has(property)) { String url = this.buildURL(images.getString(property), urlBase); if (this.isHTTPURL(url)) mView.getDownloadManager().add(new PLHTTPFileDownloader(url, new PLPanoramaImageFileDownloaderListener(panorama, colorFormat, face.ordinal()))); else panorama.setImage(this.getLocalImageAsynchronously(url, colorFormat), face); } else if (!hasPreviewImage) throw new RuntimeException(String.format("images.%s property not exists", property)); } protected void loadHotspotTexture(PLIHotspot hotspot, String filename, String urlBase, PLTextureColorFormat colorFormat) { if (filename != null) { String url = this.buildURL(filename, urlBase); if (mHotspotTextures.containsKey(url)) hotspot.addTexture(mHotspotTextures.get(url)); else { boolean isHTTPURL = this.isHTTPURL(url); PLITexture texture = new PLTexture( isHTTPURL ? new PLImage() : this.getLocalImageAsynchronously(url, colorFormat)); mHotspotTextures.put(url, texture); hotspot.addTexture(texture); if (isHTTPURL) mView.getDownloadManager().add(new PLHTTPFileDownloader(url, new PLImageFileDownloaderListener(texture.getImage(), colorFormat))); } } } @Override public void load(PLIView view) { this.load(view, null, PLConstants.kFloatUndefinedValue, PLConstants.kFloatUndefinedValue); } @Override public void load(PLIView view, PLITransition transition) { this.load(view, transition, PLConstants.kFloatUndefinedValue, PLConstants.kFloatUndefinedValue); } @Override public void load(PLIView view, PLITransition transition, float initialPitch, float initialYaw) { if (view != null && (mURL != null || mJSONData != null)) { mView = view; mTransition = transition; mInitialPitch = initialPitch; mInitialYaw = initialYaw; mIsPreloadingImages = true; mKeepParameters = null; view.setLocked(true); PLLoaderListener internalListener = this.getInternalListener(), listener = this.getListener(); if (internalListener != null) internalListener.didBegin(this); if (listener != null) listener.didBegin(this); this.requestJSON(new PLFileDownloaderListener() { @Override public void didBeginDownload(String url, long startTime) { } @Override public void didProgressDownload(String url, int progress) { } @Override public void didStopDownload(String url) { } @Override public void didEndDownload(String url, byte[] data, long elapsedTime) { parseJSON(data); } @Override public void didErrorDownload(String url, String error, int responseCode, byte[] data) { didError(new Exception(error)); } }); } } /**event methods*/ protected void didComplete(boolean runOnUiThread) { if (runOnUiThread) { mView.getActivity().runOnUiThread(new Runnable() { @Override public void run() { didComplete(); } }); } else this.didComplete(); } protected void didComplete() { PLLoaderListener internalListener = this.getInternalListener(), listener = this.getListener(); if (internalListener != null) internalListener.didComplete(this); if (listener != null) listener.didComplete(this); this.didEnd(); } protected void didStop(boolean runOnUiThread) { if (runOnUiThread) { mView.getActivity().runOnUiThread(new Runnable() { @Override public void run() { didStop(); } }); } else this.didStop(); } protected void didStop() { PLLoaderListener internalListener = this.getInternalListener(), listener = this.getListener(); if (internalListener != null) internalListener.didStop(this); if (listener != null) listener.didStop(this); this.didEnd(); } protected void didError(final Throwable e) { mView.getActivity().runOnUiThread(new Runnable() { @Override public void run() { didError(e.toString()); PLLog.error("PLJSONLoader", e); } }); } protected void didError(String error) { if (mTransition != null) { mTransition.getListeners().removeAll(); mTransition.stop(); } mView.getDownloadManager().removeAll(); PLLoaderListener internalListener = this.getInternalListener(), listener = this.getListener(); if (internalListener != null) internalListener.didError(this, error); if (listener != null) listener.didError(this, error); this.didEnd(); } protected void didEnd() { if (mView != null) { mView.setLocked(false); mView = null; } mTransition = null; } /**dealloc methods*/ @Override protected void finalize() throws Throwable { mView = null; mTransition = null; mJSON = null; mKeepParameters = null; mHotspotTextures.clear(); mHotspotTextures = null; super.finalize(); } /**internal classes declaration*/ protected class PLDataRunnable implements Runnable { /**member variables*/ private PLFileDownloaderListener mListener; private String mURL; private byte[] mData; private long mStartTime; /**init methods*/ public PLDataRunnable(PLFileDownloaderListener listener, String url, byte[] data, long startTime) { super(); mListener = listener; mURL = url; mData = data; mStartTime = startTime; } /**Runnable methods*/ @Override public void run() { mListener.didEndDownload(mURL, mData, System.currentTimeMillis() - mStartTime); } /**dealloc methods*/ @Override protected void finalize() throws Throwable { mListener = null; mURL = null; mData = null; super.finalize(); } } protected class PLPanoramaImageFileDownloaderListener implements PLFileDownloaderListener { /**member variables*/ private PLIPanorama mPanorama; private PLTextureColorFormat mColorFormat; private int mIndex; /**init methods*/ public PLPanoramaImageFileDownloaderListener(PLIPanorama panorama, PLTextureColorFormat colorFormat) { this(panorama, colorFormat, 0); } public PLPanoramaImageFileDownloaderListener(PLIPanorama panorama, PLTextureColorFormat colorFormat, int index) { super(); mPanorama = panorama; mColorFormat = colorFormat; mIndex = 0; } /**PLFileDownloaderListener methods*/ @Override public void didBeginDownload(String url, long startTime) { } @Override public void didProgressDownload(String url, int progress) { } @Override public void didStopDownload(String url) { } @Override public void didEndDownload(String url, byte[] data, long elapsedTime) { PLIImage image = new PLImage(PLUtils.getBitmap(data, mColorFormat), false); if (mPanorama instanceof PLCubicPanorama) ((PLCubicPanorama) mPanorama).setImage(image, mIndex); else if (mPanorama instanceof PLIQuadricPanorama) ((PLIQuadricPanorama) mPanorama).setImage(image); } @Override public void didErrorDownload(String url, String error, int responseCode, byte[] data) { } /**dealloc methods*/ @Override protected void finalize() throws Throwable { mPanorama = null; super.finalize(); } } protected class PLImageFileDownloaderListener implements PLFileDownloaderListener { /**member variables*/ private PLIImage mImage; private PLTextureColorFormat mColorFormat; /**init methods*/ public PLImageFileDownloaderListener(PLIImage image, PLTextureColorFormat colorFormat) { super(); mImage = image; mColorFormat = colorFormat; } /**PLFileDownloaderListener methods*/ @Override public void didBeginDownload(String url, long startTime) { } @Override public void didProgressDownload(String url, int progress) { } @Override public void didStopDownload(String url) { } @Override public void didEndDownload(String url, byte[] data, long elapsedTime) { mImage.assign(PLUtils.getBitmap(data, mColorFormat), false); } @Override public void didErrorDownload(String url, String error, int responseCode, byte[] data) { } /**dealloc methods*/ @Override protected void finalize() throws Throwable { mImage = null; super.finalize(); } } }