要浏览我的应用页面,请使用:
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();
}
}
答案 0 :(得分:3)
我很想知道你看到了什么设备和操作系统级别。
我不认为我们可以从所提供的信息中找出问题所在,我们只是在猜测。如果您需要更详细的帮助,则需要提供示例代码。我感谢您可能不想发布自己的代码,但也许您可以使用数据数组创建一个小样本。
那说,我的经验是,在屏幕的初始加载时,如果有延迟,那么很可能是加载内容而不是屏幕本身的延迟。因此,例如,如果您正在从SD卡读取数据和图像以填充屏幕,那么这将减慢它的速度。事实上,你不应该这样做,你应该用你的屏幕填充你的屏幕&#39;然后通过从SD卡读取所需数据并在从后台线程中更新屏幕来进行更新。
我想到的另一件事是,更新一个存在大量经理的屏幕会导致这些经理必须重新定位。一旦获得大量管理器,此更新可能会引入明显的延迟。但是你可能需要100个经理/领域来注意这一点。这种布局发生在屏幕显示时,而不是在施工期间。
最后您是否看到任何存储不足的迹象,例如在此缓慢处理期间屏幕上的沙漏或表盘图标。
我希望上述内容有所帮助,如果没有,您可能需要向我们提供代表性代码。
<强>更新强>
查看代码,在转换为异步加载之前,您似乎可以对此代码进行大量优化。记住位图操作在性能方面很昂贵。我建议分两个阶段进行:
此处为步骤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");
)
这个具体的例子可能不太相关,但你可以理解这种方法可以停止两次工作。
我参与过的大多数大型应用程序都为Bitmaps实现了某种缓存,这通常涉及预加载(可能会显示启动画面)所有静态位图并动态加载但保留对其他已使用位图的引用这样他们只加载一次。位图是不可变的,因此您可以在BitmapField中多次引用它们。
其他一些可能有所贡献的东西,但您需要考虑的一些代码正在取代它:
byte [] data = new byte[(int) fc.fileSize()];
data = IOUtilities.streamToBytes(is);
与
byte [] data = IOUtilities.streamToBytes(is);
可以节省分配,然后丢掉一大块内存。
如果你做了这一切,并异步加载图片,你不能加载一次,我认为你会发现性能显着提高。另外,作为实验,请始终使用(加载一次)默认图像作为列表项,这样可以让您了解事物的速度。
答案 1 :(得分:2)
您是否检查过设备或模拟器上的事件日志以查看是否抛出了异常?您可以通过转到设备主屏幕,按住&#39; alt&#39;然后按下L G L G.在第一个画面上可能会出现问题,然后用户与触控板的交互会导致刷新。
答案 2 :(得分:2)
所有给出的答案对于拥有更好的应用程序非常有用,我会做到这一点,但实际的错误&#34;我在调试后发现代码无法被我给出的代码猜到。错误是在我传递给管理器的LabelField中,在管理器内部我正在更改Labelfield的字体并导致这个疯狂的错误。要解决它,我只需更改主屏幕构造函数中的字体,而不是管理器内部。
答案 3 :(得分:1)
您的代码存在潜在问题:
fieldChanged
实际上很有用)。即使在主线程中执行IO不是当前数据集的问题,这也是一种不好的做法,并且您将来可能会遇到问题。
你应该做什么:
A)
或
B)