* Andrid - AndroidLocator now follows spec when regards to multiple call support with AssetInfo.openStream()
* Android - fix exception with recycled bitmaps that occurs when jME3 application is restored/maximized after pause git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@9144 75d07b2b-3a1a-0410-a2c5-0572b91ccdca3.0
parent
3fa629053a
commit
a64db6fc7b
@ -1,74 +1,90 @@ |
|||||||
package com.jme3.asset.plugins; |
package com.jme3.asset.plugins; |
||||||
|
|
||||||
import android.content.res.Resources; |
import com.jme3.asset.*; |
||||||
import com.jme3.asset.AssetInfo; |
|
||||||
import com.jme3.asset.AssetKey; |
|
||||||
import com.jme3.asset.AssetLocator; |
|
||||||
import com.jme3.system.android.JmeAndroidSystem; |
import com.jme3.system.android.JmeAndroidSystem; |
||||||
import java.io.IOException; |
import java.io.IOException; |
||||||
import java.io.InputStream; |
import java.io.InputStream; |
||||||
|
import java.net.URL; |
||||||
|
import java.net.URLConnection; |
||||||
|
import java.util.logging.Level; |
||||||
import java.util.logging.Logger; |
import java.util.logging.Logger; |
||||||
|
|
||||||
public class AndroidLocator implements AssetLocator { |
public class AndroidLocator implements AssetLocator { |
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(AndroidLocator.class.getName()); |
private static final Logger logger = Logger.getLogger(AndroidLocator.class.getName()); |
||||||
private Resources resources; |
|
||||||
private android.content.res.AssetManager androidManager; |
private android.content.res.AssetManager androidManager; |
||||||
private String rootPath = ""; |
private String rootPath = ""; |
||||||
|
|
||||||
private class AndroidAssetInfo extends AssetInfo { |
private class AndroidAssetInfo extends AssetInfo { |
||||||
|
|
||||||
private final InputStream in; |
private InputStream in; |
||||||
|
private final String assetPath; |
||||||
|
|
||||||
public AndroidAssetInfo(com.jme3.asset.AssetManager manager, AssetKey<?> key, InputStream in) |
public AndroidAssetInfo(com.jme3.asset.AssetManager assetManager, AssetKey<?> key, String assetPath, InputStream in) { |
||||||
{ |
super(assetManager, key); |
||||||
super(manager, key); |
this.assetPath = assetPath; |
||||||
this.in = in; |
this.in = in; |
||||||
} |
} |
||||||
|
|
||||||
@Override |
@Override |
||||||
public InputStream openStream() { |
public InputStream openStream() { |
||||||
return in; |
if (in != null){ |
||||||
|
// Reuse the already existing stream (only once)
|
||||||
|
InputStream in2 = in; |
||||||
|
in = null; |
||||||
|
return in2; |
||||||
|
}else{ |
||||||
|
// Create a new stream for subsequent invocations.
|
||||||
|
try { |
||||||
|
return androidManager.open(assetPath); |
||||||
|
} catch (IOException ex) { |
||||||
|
throw new AssetLoadException("Failed to open asset " + assetPath, ex); |
||||||
|
} |
||||||
|
} |
||||||
} |
} |
||||||
} |
} |
||||||
|
|
||||||
|
private AndroidAssetInfo create(AssetManager assetManager, AssetKey key, String assetPath) throws IOException { |
||||||
|
try { |
||||||
|
InputStream in = androidManager.open(assetPath); |
||||||
|
if (in == null){ |
||||||
|
return null; |
||||||
|
}else{ |
||||||
|
return new AndroidAssetInfo(assetManager, key, assetPath, in); |
||||||
|
} |
||||||
|
} catch (IOException ex) { |
||||||
|
// XXX: Prefer to show warning here?
|
||||||
|
// Should only surpress exceptions for "file missing" type errors.
|
||||||
|
return null; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
public AndroidLocator() |
public AndroidLocator() { |
||||||
{ |
androidManager = JmeAndroidSystem.getResources().getAssets(); |
||||||
resources = JmeAndroidSystem.getResources(); |
|
||||||
androidManager = resources.getAssets(); |
|
||||||
} |
} |
||||||
|
|
||||||
public void setRootPath(String rootPath) |
public void setRootPath(String rootPath) { |
||||||
{ |
|
||||||
this.rootPath = rootPath; |
this.rootPath = rootPath; |
||||||
} |
} |
||||||
|
|
||||||
@SuppressWarnings("rawtypes") |
@SuppressWarnings("rawtypes") |
||||||
@Override |
@Override |
||||||
public AssetInfo locate(com.jme3.asset.AssetManager manager, AssetKey key) |
public AssetInfo locate(com.jme3.asset.AssetManager manager, AssetKey key) { |
||||||
{ |
String assetPath = rootPath + key.getName(); |
||||||
InputStream in = null; |
|
||||||
String sAssetPath = rootPath + key.getName(); |
|
||||||
// Fix path issues
|
// Fix path issues
|
||||||
if (sAssetPath.startsWith("/")) |
if (assetPath.startsWith("/")) { |
||||||
{ |
|
||||||
// Remove leading /
|
// Remove leading /
|
||||||
sAssetPath = sAssetPath.substring(1); |
assetPath = assetPath.substring(1); |
||||||
} |
} |
||||||
sAssetPath = sAssetPath.replace("//", "/"); |
assetPath = assetPath.replace("//", "/"); |
||||||
try { |
try { |
||||||
in = androidManager.open(sAssetPath); |
return create(manager, key, assetPath); |
||||||
if (in == null) |
}catch (IOException ex){ |
||||||
return null; |
// This is different handling than URL locator
|
||||||
|
// since classpath locating would return null at the getResource()
|
||||||
return new AndroidAssetInfo(manager, key, in); |
// call, otherwise there's a more critical error...
|
||||||
|
throw new AssetLoadException("Failed to open asset " + assetPath, ex); |
||||||
} |
} |
||||||
catch (IOException ex) |
|
||||||
{ |
|
||||||
//logger.log(Level.WARNING, "Failed to locate {0} ", sAssetPath);
|
|
||||||
} |
} |
||||||
return null; |
|
||||||
} |
|
||||||
|
|
||||||
} |
} |
||||||
|
@ -1,78 +1,20 @@ |
|||||||
package com.jme3.texture.plugins; |
package com.jme3.texture.plugins; |
||||||
|
|
||||||
import android.graphics.Bitmap; |
import android.graphics.Bitmap; |
||||||
import android.graphics.BitmapFactory; |
import com.jme3.asset.AndroidImageInfo; |
||||||
import android.graphics.Matrix; |
|
||||||
import com.jme3.asset.AssetInfo; |
import com.jme3.asset.AssetInfo; |
||||||
import com.jme3.asset.AssetLoader; |
import com.jme3.asset.AssetLoader; |
||||||
import com.jme3.asset.TextureKey; |
|
||||||
import com.jme3.texture.Image; |
import com.jme3.texture.Image; |
||||||
import com.jme3.texture.Image.Format; |
|
||||||
import com.jme3.util.BufferUtils; |
|
||||||
import java.io.IOException; |
import java.io.IOException; |
||||||
import java.io.InputStream; |
|
||||||
import java.nio.ByteBuffer; |
|
||||||
|
|
||||||
public class AndroidImageLoader implements AssetLoader { |
public class AndroidImageLoader implements AssetLoader { |
||||||
|
|
||||||
public Object load2(AssetInfo info) throws IOException { |
|
||||||
ByteBuffer bb = BufferUtils.createByteBuffer(1 * 1 * 2); |
|
||||||
bb.put((byte) 0xff).put((byte) 0xff); |
|
||||||
bb.clear(); |
|
||||||
return new Image(Format.RGB5A1, 1, 1, bb); |
|
||||||
} |
|
||||||
|
|
||||||
public Object load(AssetInfo info) throws IOException { |
public Object load(AssetInfo info) throws IOException { |
||||||
InputStream in = null; |
AndroidImageInfo imageInfo = new AndroidImageInfo(info); |
||||||
Bitmap bitmap = null; |
Bitmap bitmap = imageInfo.getBitmap(); |
||||||
try { |
|
||||||
in = info.openStream(); |
|
||||||
bitmap = BitmapFactory.decodeStream(in); |
|
||||||
if (bitmap == null) { |
|
||||||
throw new IOException("Failed to load image: " + info.getKey().getName()); |
|
||||||
} |
|
||||||
} finally { |
|
||||||
if (in != null) { |
|
||||||
in.close(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
int width = bitmap.getWidth(); |
|
||||||
int height = bitmap.getHeight(); |
|
||||||
Format fmt; |
|
||||||
|
|
||||||
switch (bitmap.getConfig()) { |
|
||||||
case ALPHA_8: |
|
||||||
fmt = Format.Alpha8; |
|
||||||
break; |
|
||||||
case ARGB_4444: |
|
||||||
fmt = Format.ARGB4444; |
|
||||||
break; |
|
||||||
case ARGB_8888: |
|
||||||
fmt = Format.RGBA8; |
|
||||||
break; |
|
||||||
case RGB_565: |
|
||||||
fmt = Format.RGB565; |
|
||||||
break; |
|
||||||
default: |
|
||||||
return null; |
|
||||||
} |
|
||||||
|
|
||||||
if (((TextureKey) info.getKey()).isFlipY()) { |
|
||||||
Bitmap newBitmap = null; |
|
||||||
Matrix flipMat = new Matrix(); |
|
||||||
flipMat.preScale(1.0f, -1.0f); |
|
||||||
newBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), flipMat, false); |
|
||||||
bitmap.recycle(); |
|
||||||
bitmap = newBitmap; |
|
||||||
|
|
||||||
if (bitmap == null) { |
|
||||||
throw new IOException("Failed to flip image: " + info.getKey().getName()); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
Image image = new Image(fmt, width, height, null); |
Image image = new Image(imageInfo.getFormat(), bitmap.getWidth(), bitmap.getHeight(), null); |
||||||
image.setEfficentData(bitmap); |
image.setEfficentData(imageInfo); |
||||||
return image; |
return image; |
||||||
} |
} |
||||||
} |
} |
||||||
|
Loading…
Reference in new issue