Как повысить производительность для загрузки изображений с SDCard в мое приложение? - PullRequest
0 голосов
/ 30 декабря 2011

Привет, я сделал одно маленькое приложение, чтобы показать, что все изображения sdcard должны отображаться в моем приложении как вид миниатюр. Моя программа похожа на следующую:

Здесь проблема в том, что в симуляторе он загружается быстро и точно, где, как телефон, это занимает много времени. он загружен около 30 МБ, так что проблем не возникает. В то время как он размером 80 МБ, он не показывает изображения на моем экране.

Примечание: это прекрасно работает в симуляторе, но не в устройстве и мой путь к изображениям "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();
                }
            }
        }
    }

}

пожалуйста, помогите мне, как увеличить производительность моего кода

1 Ответ

3 голосов
/ 30 декабря 2011
  1. Я бы загружал изображения только тогда, когда пользователь прокручивает экран.Например, загрузите первые два экрана в начале экрана (в другом потоке) и загрузите следующий, когда пользователь движется вниз.Поэтому установите ScrollListener для своего менеджера и используйте поле и высоту поля, чтобы определить, что будет на экране, а какое скоро появится на экране.

  2. Также используйте пул потоков ограниченного размера иочередь для загрузки изображений.К сожалению, java-параллелизм не является частью j2me.Но есть несколько похожих реализаций шаблонов, например ThreadPool .

  3. И было бы супер, если бы вы также помнили случай, когда пользователь прокручивает быстро - отмените запланированную загрузку, если она не требуется.Для каждой задачи загрузки помните BitmapField положение и размер.Перед началом загрузки файла проверьте, видна ли BitmapField (будет ли она видимой) текущая позиция прокрутки.

Также следует учитывать количество потоков.Я вижу, что вы пытаетесь заснуть основной поток загрузки, когда счетчик равен 6. Но все еще существует небольшая вероятность того, что 400 мс недостаточно для завершения работы с текущими потоками, и вы можете легко начать создавать больше потоков.

Такжевторостепенные вещи - используйте Bitmap.scaleInto (если вы выбираете 5.0+), используйте синхронизацию вокруг поля size, next никогда не используется, используйте более подходящие имена, такие как nextImages, threadsCount и т. д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...