您好我制作了一个小应用程序来显示所有sdcard图像应该在我的应用程序中显示为缩略图视图。我的程序如下所示
这里的问题是,在模拟器中,它可以快速准确地加载,因为手机需要花费大量时间。它装满了30MB左右,没有出现问题。 whare它是80MB左右它没有在我的屏幕上显示图像。
注意:这在模拟器中完全有效,但不是设备 我的图片路径是" file:/// SDCard / images /" 我的代码是:
这是我的应用程序入门类
public class StartUp extends UiApplication{
public static void main(String[] args) {
StartUp start=new StartUp();
start.enterEventDispatcher();
}
public StartUp() {
pushScreen(new ViewerMainScreen());
}
}
这是我的ViewerMainScreen.java
public class ViewerMainScreen extends MainScreen implements FieldChangeListener{
private ObjectListField fileList;
private String currentPath = "file:///";
public VerticalFieldManager vert_manager=null;
private BitmapField before[]=null,next[]=null;
private int size=0;Border b1,b2;
TableLayoutManager colFMgr=null;
private Vector img_data=null;
private int count=0;
public ViewerMainScreen() {
super();
setTitle("Browse to image...");
initGUI();
}
public void initGUI() {
try {
// add(getFileList());
img_data=getAllList("file:///SDCard/images");
b1=BorderFactory.createSimpleBorder(new XYEdges(3,3,3,3),new XYEdges(Color.RED, Color.RED, Color.RED, Color.RED),Border.STYLE_SOLID);
b2=BorderFactory.createSimpleBorder(new XYEdges(0,0,0,0));
size=img_data.size();
before=new BitmapField[size];
next=new BitmapField[size];
vert_manager=new VerticalFieldManager(VERTICAL_SCROLL|VERTICAL_SCROLLBAR){
protected void sublayout(int maxWidth, int maxHeight) {
super.sublayout(Display.getWidth(),Display.getHeight());
setExtent(Display.getWidth(),Display.getHeight());
}
};
colFMgr = new TableLayoutManager(new int[] {
TableLayoutManager.USE_PREFERRED_SIZE,
TableLayoutManager.USE_PREFERRED_SIZE,
TableLayoutManager.USE_PREFERRED_SIZE,
TableLayoutManager.USE_PREFERRED_SIZE,
}, Manager.HORIZONTAL_SCROLL|VERTICAL_SCROLL|VERTICAL_SCROLLBAR);
for(int i= 0;i < size;i++)
{
EncodedImage load_img=EncodedImage.getEncodedImageResource("loading.jpg");
before[i] = new BitmapField(load_img.getBitmap(),Field.FOCUSABLE){
protected boolean navigationClick(int status,int time) {
fieldChangeNotify(0);
return super.navigationClick(status, time);
}
protected void onFocus(int direction)
{
this.setBorder(b1);
invalidate();
}
protected void onUnfocus()
{
this.setBorder(b2);
invalidate();
}
};
colFMgr.add(before[i]);
}
add(colFMgr);
Thread t=new Thread(){
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
callImageThread();
}
};
t.start();
} catch (Exception e) {
Dialog.alert(e.getMessage());
}
}
private void callImageThread() {
for(int i=0;i<size;i++)
{
if(count==6){
try {
Thread.sleep(400);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
ImageThread th=new ImageThread(this, "file:///SDCard/images/"+img_data.elementAt(i), i);
th.start();
count++;
}
}
public void ReplaceImage(EncodedImage img,int index)
{
before[index].setBitmap(img.getBitmap());
before[index].setChangeListener(this);
count--;
System.out.println("Thread count: ========================"+Thread.activeCount()+"============================================="+count);
}
public void fieldChanged(Field field, int context) {
for(int i=0;i<size;i++)
{
if(field==before[i])
{
synchronized (UiApplication.getEventLock()) {
EncodedImage img=null;
img=loadFile("file:///SDCard/images/"+img_data.elementAt(i));
int displayWidth = Fixed32.toFP(Display.getWidth()-100);
int imageWidth = Fixed32.toFP(img.getWidth());
int scalingFactorX = Fixed32.div(imageWidth, displayWidth);
int displayHeight = Fixed32.toFP(Display.getHeight()-100);
int imageHeight = Fixed32.toFP(img.getHeight());
int scalingFactorY = Fixed32.div(imageHeight, displayHeight);
EncodedImage scaledImage = img.scaleImage32(scalingFactorX, scalingFactorY);
UiApplication.getUiApplication().pushScreen(new ZoomScreen(scaledImage));
}
}
}
}
public void displayMessage(final String message)
{
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
Dialog.inform(message);
}
});
}
private Vector getAllList(String path){
Vector data=new Vector();
FileConnection fileConnection=null;
try{
fileConnection = (FileConnection) Connector.open(path);
if (fileConnection.isDirectory()) {
Enumeration directoryEnumerator = fileConnection.list();
while (directoryEnumerator.hasMoreElements()) {
data.addElement(directoryEnumerator.nextElement());
}
}
}catch (Exception e) {
System.out.println(e.getMessage());
}
finally
{
if(fileConnection!=null){
try {
fileConnection.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return data;
}
private EncodedImage loadFile(String path) {
FileConnection fileConnection =null;
InputStream inputStream =null;
EncodedImage encodedImage=null;
try {
fileConnection = (FileConnection) Connector.open(path);
if(fileConnection.exists()){
inputStream = fileConnection.openInputStream();
byte[] imageBytes = new byte[(int)fileConnection.fileSize()];
inputStream.read(imageBytes);
encodedImage = EncodedImage.createEncodedImage(imageBytes, 0, imageBytes.length);
if(fileConnection!=null){
try {
fileConnection.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(inputStream!=null){
try {
inputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
} catch (IOException e) {
Dialog.alert("Insert an SD Card.");
}
return encodedImage;
}
}
这是我的ImageThread.java
public class ImageThread extends Thread{
private ViewerMainScreen screen;
private String path;
private int index;
private EncodedImage scaledImage=null;
public ImageThread(ViewerMainScreen screen,String path,int index) {
this.screen=screen;
this.path=path;
this.index=index;
}
public void callMainScreen(EncodedImage eimg,int Rindex) {
screen.ReplaceImage(eimg, Rindex);
}
public void run() {
FileConnection fileConnection =null;
InputStream inputStream =null;
EncodedImage encodedImage=null;
try {
fileConnection = (FileConnection) Connector.open(path);
if(fileConnection.exists()){
inputStream = fileConnection.openInputStream();
byte[] imageBytes = new byte[(int)fileConnection.fileSize()];
inputStream.read(imageBytes);
encodedImage = EncodedImage.createEncodedImage(imageBytes, 0, imageBytes.length);
int displayWidth = Fixed32.toFP(100);
int imageWidth = Fixed32.toFP(encodedImage.getWidth());
int scalingFactorX = Fixed32.div(imageWidth, displayWidth);
int displayHeight = Fixed32.toFP(100);
int imageHeight = Fixed32.toFP(encodedImage.getHeight());
int scalingFactorY = Fixed32.div(imageHeight, displayHeight);
scaledImage = encodedImage.scaleImage32(scalingFactorX, scalingFactorY);
callMainScreen(scaledImage, index);
}
} catch (IOException e) {
Dialog.alert("Insert an SD Card.");
}
finally
{
if(fileConnection!=null){
try {
fileConnection.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(inputStream!=null){
try {
inputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
请帮助我如何提高代码的性能
答案 0 :(得分:3)
我只会在用户滚动屏幕时加载图片。例如,在屏幕启动时(在不同的线程中)加载前两个屏幕,并在用户向下移动时加载下一个屏幕。因此,请将ScrollListener
设置为您的经理,并使用字段位置和高度来确定屏幕上的内容以及即将在屏幕上显示的内容。
还使用有限大小的线程池和队列来加载图像。不幸的是,java并发不是j2me的标准。但是有几种类似的模式实现,比如ThreadPool。
如果您还记得用户快速滚动的情况,那将是超级的 - 如果不需要则取消预定加载。对于每个加载任务,请记住BitmapField
位置和大小。在任务开始文件加载之前,检查BitmapField
是否在当前滚动位置可见(将可见)。
还要注意线程计数。我看到你在count为6时尝试睡眠主加载线程。但是400 ms的可能性仍然不足以完成当前线程的工作,你可以轻松地开始创建更多的线程。
同样轻微的事情 - 使用Bitmap.scaleInto(如果你的目标是5.0+),使用size
字段周围的同步,从不使用next
,使用更好的名称,如nextImages
,threadsCount
等。