【问题标题】:Blackberry switch screen黑莓开关屏
【发布时间】:2014-05-30 18:56:17
【问题描述】:

浏览我使用的应用页面:

UiApplication.getUiApplication().invokeLater(new Runnable(){
    public void run(){
                    UiApplication.getUiApplication().pushScreen(screen);
    }
});

这在没有太多字段的简单屏幕上运行良好。但是当我尝试进入一个更详细的屏幕(它包含一个由具有多个字段的多个管理器组成的自定义“listField”)时,UI 需要很多时间来更新。我注意到页面实际上已经构建完成,但它只是没有显示,我必须移动触控板或单击然后屏幕才会显示。

屏幕代码:

public class List extends MainScreen{

public List(Categoria categoria){
    Bitmap bmap = Bitmap.getBitmapResource("img/fondo.png");
    getMainManager().setBackground(BackgroundFactory.createBitmapBackground(bmap, Background.POSITION_X_LEFT, Background.POSITION_Y_TOP, Background.REPEAT_SCALE_TO_FIT));
    setTitle("Establecimientos");
    vfm = new VerticalFieldManager(Manager.VERTICAL_SCROLL | Manager.VERTICAL_SCROLLBAR);
    try {
        DbHelper dbHelper = new DbHelper();
        dbHelper.open();
        EstablecimientoDAO eDao = new EstablecimientoDAO(dbHelper.db);
        OfertaDAO oDao = new OfertaDAO(dbHelper.db);
        Vector ests = eDao.getEstablecimientosPorCategoria(categoria);
        for(int i = 0; i < ests.size(); i++){
            Establecimiento est = (Establecimiento) ests.elementAt(i);
            Oferta oferta = oDao.getOferta(est.getIdEstablecimiento());
            EstablecimientosListField elf1 = new EstablecimientosListField();
            Bitmap bm = null;
            String location = "";
            FileSystem fs = Utilities.getFileSystem();
            if(fs.hasSdCard()){
                location = "/SDCard/Blackberry/pictures/";
            }
            else if(fs.hasMCard()){
                location = "/store/";
            }
            FileConnection fc = (FileConnection)Connector.open("file://" + location + "e_" + est.getIdEstablecimiento() + ".jpg");
            if(fc.exists() && fc.fileSize() > 0){
                InputStream is = fc.openInputStream();
                byte [] data = new byte[(int) fc.fileSize()];
                data = IOUtilities.streamToBytes(is);
                is.close();
                fc.close();
                //bm = Bitmap.createBitmapFromBytes(data, 0, data.length, 1);
                EncodedImage eImage = EncodedImage.createEncodedImage(data, 0, data.length);
                eImage = Utilities.resizeToWidth(eImage, Display.getWidth() / 3, 1, true);
                Bitmap tmp = eImage.getBitmap();
                if(tmp.getHeight() > 150){
                    eImage = Utilities.resizeToHeight(eImage, 1, 150, true);
                }
                bm = eImage.getBitmap();
            }
            else{
                EncodedImage eImage = EncodedImage.getEncodedImageResource("img/default_esta.png");
                eImage = Utilities.resizeToHeight(eImage, 1, 150, true);
                bm = eImage.getBitmap();
            }
            String desc = "";
            if(oferta != null && oferta.getDescripcion() != null){
                desc = oferta.getDescripcion();
            }
            if(est.getDescEstablecimiento() != null){
                desc += est.getDescEstablecimiento();
            }


            ButtonField verMas = new ButtonField("VER MÁS"){
                protected boolean touchEvent( TouchEvent message )    {
                    int x = message.getX( 1 );        
                    int y = message.getY( 1 );        
                    if( x < 0 || y < 0 || x > getExtent().width || y > getExtent().height ) {
                        // Outside the field            
                        return false;       
                    }        

                    switch( message.getEvent() ) {                  
                    case TouchEvent.UNCLICK:                
                        fieldChangeNotify(0);               
                        return true;        
                    }        
                    return super.touchEvent( message );    
                }

                protected boolean navigationClick(int status, int time) {
                    if (status != 0) {        // you did not have this check
                        fieldChangeNotify(0);
                    }
                    return true;
                }

                protected boolean trackwheelClick( int status, int time )
                {        
                    if (status != 0) fieldChangeNotify(0);    
                    return true;
                }
            };
            verMas.setCookie(est);
            verMas.setChangeListener(new FieldChangeListener(){
                public void fieldChanged(Field field, int context) {
                    final Establecimiento est = (Establecimiento)field.getCookie();
                    //if(field instanceof )
                    /*UiApplication.getUiApplication().invokeLater(new Runnable(){
                        public void run(){
                            UiApplication.getUiApplication().pushScreen(new DetalleEstablecimientoScreen(est));
                        }
                    });*/
                    Runnable runnable = new Runnable(){
                        public void run(){
                            UiApplication.getUiApplication().pushScreen(new DetalleEstablecimientoScreen(est));
                        }
                    };
                    PleaseWaitPopupScreen.showScreenAndWait(runnable, "Cargando...");
                }
            });

            EncodedImage eImage = EncodedImage.getEncodedImageResource("img/det_fb.png");
            eImage = Utilities.resizeToWidth(eImage, (int) (Display.getWidth() / 16), (int) (Display.getWidth() / 16), true);
            BitmapField bmFb = new BitmapField(eImage.getBitmap(), Field.FOCUSABLE){
                protected boolean touchEvent( TouchEvent message )    {
                    int x = message.getX( 1 );        
                    int y = message.getY( 1 );        
                    if( x < 0 || y < 0 || x > getExtent().width || y > getExtent().height ) {
                        // Outside the field            
                        return false;       
                    }        

                    switch( message.getEvent() ) {                  
                    case TouchEvent.UNCLICK:                
                        fieldChangeNotify(0);               
                        return true;        
                    }        
                    return super.touchEvent( message );    
                }

                protected boolean navigationClick(int status, int time) {
                    if (status != 0) {        // you did not have this check
                        fieldChangeNotify(0);
                    }
                    return true;
                }

                protected boolean trackwheelClick( int status, int time )
                {        
                    if (status != 0) fieldChangeNotify(0);    
                    return true;
                }
            };
            bmFb.setCookie(est);
            bmFb.setChangeListener(new FieldChangeListener(){
                public void fieldChanged(Field field, int context){
                    try{
                        DbConnection dbHelper = new DbConnection();
                        dbHelper.open();
                        OfertaDAO oDao = new OfertaDAO(dbHelper.db);
                        final Establecimiento est = (Establecimiento)field.getCookie();
                        final Oferta oferta = oDao.getOferta(est.getIdEstablecimiento());
                        dbHelper.close();
                        UiApplication.getUiApplication().invokeLater(new Runnable(){
                            public void run(){
                                try{
                                    String post = "Banco de Bogotá";
                                    if(oferta.getDescripcion() != null){
                                        post = oferta.getDescripcion();
                                    }
                                    //String [] opciones = {"Aceptar", "Cancelar"};
                                    int respuesta = Dialog.ask(Dialog.D_OK_CANCEL, "Usted está a punto de compartir la siguiente oferta:\n" + post, Dialog.YES);
                                    if(respuesta == Dialog.D_OK){
                                        new FacebookPost(oferta, est);
                                    }
                                }
                                catch(Exception ex){
                                    Dialog.alert("ERROR: " + ex.toString());
                                }
                            }
                        });
                    } catch(Exception ex){
                        UiApplication.getUiApplication().invokeLater(new Runnable(){
                            public void run(){
                                Dialog.alert("Error al compartir");
                            }
                        });
                    }
                }
            });

            eImage = EncodedImage.getEncodedImageResource("img/det_tw.png");
            eImage = Utilities.resizeToWidth(eImage, (int) (Display.getWidth() / 16), (int) (Display.getWidth() / 16), true);
            BitmapField bmTw = new BitmapField(eImage.getBitmap(), Field.FOCUSABLE){
                protected boolean touchEvent( TouchEvent message )    {
                    int x = message.getX( 1 );        
                    int y = message.getY( 1 );        
                    if( x < 0 || y < 0 || x > getExtent().width || y > getExtent().height ) {
                        // Outside the field            
                        return false;       
                    }        

                    switch( message.getEvent() ) {                  
                    case TouchEvent.UNCLICK:                
                        fieldChangeNotify(0);               
                        return true;        
                    }        
                    return super.touchEvent( message );    
                }

                protected boolean navigationClick(int status, int time) {
                    if (status != 0) {        // you did not have this check
                        fieldChangeNotify(0);
                    }
                    return true;
                }

                protected boolean trackwheelClick( int status, int time )
                {        
                    if (status != 0) fieldChangeNotify(0);    
                    return true;
                }
            };
            bmTw.setCookie(est);
            bmTw.setChangeListener(new FieldChangeListener(){
                public void fieldChanged(Field field, int context){
                    try{
                        DbConnection dbHelper = new DbConnection();
                        dbHelper.open();
                        OfertaDAO oDao = new OfertaDAO(dbHelper.db);
                        final Establecimiento est = (Establecimiento)field.getCookie();
                        final Oferta oferta = oDao.getOferta(est.getIdEstablecimiento());
                        dbHelper.close();
                        UiApplication.getUiApplication().invokeLater(new Runnable(){
                            public void run(){
                                String tuit = "tweeteando desde fidelity";
                                if(oferta.getDescripcion() != null){
                                    tuit = oferta.getDescripcion();
                                }
                                //String [] opciones = {"Aceptar", "Cancelar"};
                                int respuesta = Dialog.ask(Dialog.D_OK_CANCEL, "Usted está a punto de compartir la siguiente oferta:\n" + tuit, Dialog.OK);
                                if(respuesta == Dialog.OK){
                                    UiApplication.getUiApplication().pushScreen(new BrowserFieldScreen(tuit));
                                }
                            }
                        });
                    } catch(Exception ex){
                        UiApplication.getUiApplication().invokeLater(new Runnable(){
                            public void run(){
                                Dialog.alert("Error al compartir");
                            }
                        });
                    }
                }
            });

            BitmapField pin = new BitmapField(Bitmap.getBitmapResource("img/pin.png"), Field.FOCUSABLE){
                protected boolean touchEvent( TouchEvent message )    {
                    int x = message.getX( 1 );        
                    int y = message.getY( 1 );        
                    if( x < 0 || y < 0 || x > getExtent().width || y > getExtent().height ) {
                        // Outside the field            
                        return false;       
                    }        

                    switch( message.getEvent() ) {                  
                    case TouchEvent.UNCLICK:                
                        fieldChangeNotify(0);               
                        return true;        
                    }        
                    return super.touchEvent( message );    
                }

                protected boolean navigationClick(int status, int time) {
                    if (status != 0) {        // you did not have this check
                        fieldChangeNotify(0);
                    }
                    return true;
                }

                protected boolean trackwheelClick( int status, int time )
                {        
                    if (status != 0) fieldChangeNotify(0);    
                    return true;
                }
            };
            pin.setCookie(new Long(est.getIdEstablecimiento()));
            //pin.setChangeListener(this);
            pin.setChangeListener(new FieldChangeListener(){
                public void fieldChanged(Field field, int context) {
                    final long idEstablecimiento = ((Long)field.getCookie()).longValue();
                    //if(field instanceof )
                    UiApplication.getUiApplication().invokeLater(new Runnable(){
                        public void run(){
                            UiApplication.getUiApplication().pushScreen(new MapaScreen(idEstablecimiento, "establecimiento"));
                        }
                    });
                }
            });
            elf1.add(new BitmapField(bm));
            elf1.add(new LabelField(est.getNombre(), LabelField.ELLIPSIS));
            elf1.add(new LabelField(desc, LabelField.ELLIPSIS));
            elf1.add(verMas);
            elf1.add(pin);
            elf1.add(bmFb);
            elf1.add(bmTw);
            vfm.add(elf1);
        }
    } catch (Exception ex){

    }
    add(vfm);
    //UiApplication.getUiApplication().requestForeground();
    //invalidate();
}
}

【问题讨论】:

    标签: blackberry java-me screen blackberry-eclipse-plugin blackberry-jde


    【解决方案1】:

    我很想知道您在哪个设备和操作系统级别上看到此内容。

    我认为我们无法从提供的信息中找出您的问题,我们只是猜测。如果您需要更详细的帮助,则需要提供示例代码。我很欣赏您可能不想发布自己的代码,但也许您可以使用数据数组创建一个小示例。

    也就是说,我的经验是,在屏幕的初始加载时,如果有延迟,那么很可能是加载内容的延迟,而不是屏幕本身。因此,例如,如果您从 SD 卡读取数据和图像以填充屏幕,那么它会减慢速度。事实上,您不应该这样做,您应该使用“文件管理器”填充屏幕,然后通过从 SD 卡中读取所需数据并从后台线程更新屏幕来进行更新。

    我想到的另一件事是,更新一个有很多经理在场的屏幕,可能会导致这些经理中的每一个都不得不重新定位。一旦您获得大量经理,此更新可能会引入明显的滞后。但是您可能需要 100 个经理/字段才能注意到这一点。这种布局发生在屏幕显示时,而不是在施工期间。

    最后,您是否看到任何存储空间不足的迹象,例如在这个缓慢的处理过程中屏幕上出现沙漏或表盘图标。

    希望以上对您有所帮助,如果没有,您可能需要给我们代表代码。

    更新

    查看您的代码,您似乎可以在转换为异步加载之前对此代码进行大量优化。请记住,位图操作在性能方面是昂贵的。我建议分两个阶段进行:

    1. 将重复的代码移出循环
    2. 只执行一次循环外的加载。

    这里作为步骤 1 的示例。

    当前在你拥有的循环内:

    eImage = EncodedImage.getEncodedImageResource("img/det_tw.png");
    eImage = Utilities.resizeToWidth(eImage, (int) (Display.getWidth() / 16), (int) (Display.getWidth() / 16), true);
    BitmapField bmTw = new BitmapField(eImage.getBitmap(), Field.FOCUSABLE){  
    

    在循环之外做

    int displayWidth = Display.getWidth(); // I was told this was an expensive call so minimise its use
    EncodedImage det_twEImage = EncodedImage.getEncodedImageResource("img/det_tw.png");
    det_twEImage = Utilities.resizeToWidth(det_twEImage, (int) (displayWidth / 16), (int) (displayWidth / 16), true);
    Bitmap bmTwBitmap = eImage.getBitmap();
    

    在循环中:

    BitmapField bmTw = new BitmapField(bmTwBitmap, Field.FOCUSABLE){ 
    

    以及第 2 步的示例。

    目前你有这个:

    public List(Categoria categoria){
        Bitmap bmap = Bitmap.getBitmapResource("img/fondo.png");
    

    你可以看看这样做:

    static Bitmap bmap = null;
    
    public List(Categoria categoria){
        if ( bmap == null ) {
            bmap = Bitmap.getBitmapResource("img/fondo.png");
        )
    

    这个具体的例子可能不太相关,但你可以理解这种方法可以停止工作两次。

    我从事的大多数大型应用程序都为位图实现了某种缓存,这通常涉及预加载(可能在显示初始屏幕时)所有静态位图并动态加载但保留对其他使用的位图的引用这样它们只加载一次。位图是不可变的,因此您可以在 BitmapFields 中多次引用它们。

    可能有一些其他的东西可能会起作用,但您需要查看的一段代码正在替换它:

    byte [] data = new byte[(int) fc.fileSize()];
    data = IOUtilities.streamToBytes(is);
    

    byte [] data = IOUtilities.streamToBytes(is);
    

    这样可以节省分配然后丢弃大量内存。

    如果您执行所有这些操作,并异步加载一次无法加载的图像,我想您会发现性能会显着提高。同样作为一项实验,请始终为您的列表项使用(加载一次)默认图像,这将使您对事情的速度有一个印象。

    【讨论】:

    • 感谢您的帮助。我添加了代码中最重要的部分,总而言之,它是一个具有 1 个位图字段、2 个标签字段、1 个按钮字段和 3 个可聚焦位图字段的管理器。
    • 我会按照你的建议在后台线程上读取图像,但我认为这不是问题,有时屏幕可能只有三个自定义管理器,如果我使用触控板屏幕将在 3-5 秒内刷新,但如果我不是,可能需要几分钟才能显示。屏幕确实在那里,因为如果我点击它会执行经理按钮的操作之一
    • 补充彼得的建议:您可以更精确地围绕调用 Utilities.resizeToHeight 和 Utilities.resizeToWidth 的逻辑。您不需要同时调用两者,只需使用一个即可。然后,您的代码路径将恰好有一次 EncodedImage.getBitmap() 调用。 getBitmap() 函数是这里最昂贵的部分之一,您为每个图像调用了两次。
    【解决方案2】:

    您是否检查过设备或模拟器上的事件日志以查看是否引发了异常?您可以通过转到设备主屏幕,按住“alt”并按 L G L G 来查看它。这可能是第一次绘制时出现问题,然后用户与触控板的交互会导致刷新。

    【讨论】:

      【解决方案3】:

      给出的所有答案对于拥有更好的应用程序非常有用,我会这样做,但我在调试代码后发现的实际“错误”无法被我给出的代码猜到。错误出现在我传递给经理的 LabelField 中,在经理内部我正在更改 Labelfield 的字体并导致了这个疯狂的错误。为了解决这个问题,我只是在主屏幕的构造函数中而不是在管理器中更改了字体。

      【讨论】:

      • 感谢您告知我们。有许多可能的方法可以导致重复调用绘画,因此下面答案中的原则 - 只做一次 - 也适用于此。下次,如果您能提供一段代码来实际演示该问题,那将有助于我们为您提供帮助。
      【解决方案4】:

      代码的潜在问题:

      • 在主线程上执行 IO(数据库/文件/网络连接)
      • FieldchangeListeners 不检查编程上下文(是的,fieldChanged 的第二个参数实际上很有用)。
      • 为单个用户输入处理多个事件(touchEvent + navigationClick + trackwheelClick)

      即使在主线程中做 IO 对您当前的数据集来说不是问题,但这是一种不好的做法,您将来可能会遇到问题。

      你应该做什么:
      一)

      1. 显示加载对话框
      2. 在后台获取数据
      3. 初始化列表屏幕
      4. 隐藏加载对话框
      5. 更改为列表屏幕

      B)

      1. 更改为列表屏幕
      2. 显示加载对话框或消息
      3. 在 BG 中获取数据
      4. 初始化列表
      5. 隐藏加载对话框/消息

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多