05-31-2012 11:17 AM
Hi guys, actually um doing an app that needs to make list of managers with a bitmap field and text beside it um using FieldManager to be listed and retrieving bitmaps but when It comes the app stopped till it retreive all bitmaps and that's the source code of the screen and the connection which get the bitmap
import java.io.IOException;
import java.io.InputStream;
import javax.microedition.io.Connector;
import javax.microedition.io.HttpConnection;
import net.rim.device.api.math.Fixed32;
import net.rim.device.api.system.Bitmap;
import net.rim.device.api.system.EncodedImage;
public class ImageFromUrl {
public static Bitmap _bmap;
HttpConnection connection = null;
InputStream inputStream = null;
EncodedImage bitmap;
byte[] dataArray = null;
String url;
ImageFromUrl(String url) {
this.url = url;
}
public byte[] getbitmap() {
// TODO Auto-generated method stub
try {
connection = (HttpConnection) Connector.open(url, Connector.READ,
true);
inputStream = connection.openInputStream();
byte[] responseData = new byte[10000];
int length = 0;
StringBuffer rawResponse = new StringBuffer();
while (-1 != (length = inputStream.read(responseData))) {
rawResponse.append(new String(responseData, 0, length));
}
int responseCode = connection.getResponseCode();
if (responseCode != HttpConnection.HTTP_OK) {
throw new IOException("HTTP response code: " + responseCode);
}
final String result = rawResponse.toString();
dataArray = result.getBytes();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return dataArray;
}
}and that's the horizontalFieldManager class
import net.rim.device.api.i18n.Locale; import net.rim.device.api.system.Bitmap; import net.rim.device.api.system.Display; import net.rim.device.api.ui.Color; import net.rim.device.api.ui.FieldChangeListener; import net.rim.device.api.ui.Font; import net.rim.device.api.ui.Graphics; import net.rim.device.api.ui.TouchEvent; import net.rim.device.api.ui.TouchGesture; import net.rim.device.api.ui.UiApplication; import net.rim.device.api.ui.component.BitmapField; import net.rim.device.api.ui.component.LabelField; import net.rim.device.api.ui.container.HorizontalFieldManager; import net.rim.device.api.ui.container.VerticalFieldManag er; import net.rim.device.api.ui.decor.BackgroundFactory; public class ItemsTitle extends HorizontalFieldManager { private ItemBean item; // private ActivityIndicatorView indicatorView; private BitmapField indicatorView; private int fieldHeight; private int width; private int titleHeight; private int dateHeight; private int managerWidth; private Bitmap bitmap; public final static int SMALL_SIZE = 0; public final static int LARGE_SIZE = 1; public final static int PADDING = 5; private ItemsTitle(final ItemBean item, int size) { super(); this.item = item; int mySize = 0; Font titleFont = null; Font dateFont = null; if (size == LARGE_SIZE) { mySize = getFont().getHeight(); int allWidth = getFont().getAdvance(item.getLink()); width = 100; titleFont = getFont().derive(Font.PLAIN, mySize); int lineNumbers = (allWidth / (Display.getWidth() - width)) + 1; titleHeight = (titleFont.getDescent() + titleFont.getHeight() * lineNumbers); dateFont = getFont().derive(Font.PLAIN, mySize - 3); dateHeight = (dateFont.getDescent() + dateFont.getHeight()); fieldHeight = titleHeight + dateHeight + (PADDING * 2); } else if (size == SMALL_SIZE) { mySize = getFont().getHeight() - 2; width = 80; titleFont = getFont().derive(Font.PLAIN, mySize); titleHeight = ((titleFont.getDescent() + titleFont.getHeight()) * 2); dateFont = getFont().derive(Font.PLAIN, mySize - 3); dateHeight = (dateFont.getDescent() + dateFont.getHeight()); fieldHeight = titleHeight + dateHeight + (PADDING * 2); } managerWidth = Display.getWidth() - width; // width = item.getDescription().getImgWidth(); VerticalFieldManager fieldManager = new VerticalFieldManager() { protected void sublayout(int maxWidth, int maxHeight) { super.sublayout(managerWidth, fieldHeight); setExtent(managerWidth, fieldHeight); } }; fieldManager.setPadding(0, PADDING, 0, PADDING); LabelField title = new LabelField(item.getLink(), USE_ALL_WIDTH) { protected void layout(int width, int maxHeight) { super.layout(managerWidth, titleHeight); setExtent(managerWidth, titleHeight); } protected void paint(Graphics graphics) { graphics.setColor(Color.AQUA); super.paint(graphics); } }; title.setFont(titleFont); fieldManager.add(title); LabelField date = new LabelField(item.getId(), USE_ALL_WIDTH) { protected void layout(int width, int maxHeight) { super.layout(managerWidth, dateHeight); setExtent(managerWidth, dateHeight); } protected void paint(Graphics graphics) { graphics.setColor(Color.AZURE); super.paint(graphics); } }; date.setFont(dateFont); date.setPadding(PADDING, 0, 0, 0); fieldManager.add(date); indicatorView = new BitmapField( Bitmap.getBitmapResource("loading.png"), BitmapField.HCENTER | BitmapField.VCENTER) { protected void layout(int width, int height) { super.layout(Display.getWidth() - managerWidth, fieldHeight); setExtent(Display.getWidth() - managerWidth, fieldHeight); } }; imageRecevied(); // indicatorView = LoadingIndicator.getWaitingField( // LoadingIndicator.SPINNER_PATTERN, width, height); // if (Locale.getDefault().getCode() == Locale.LOCALE_ar) { // add(fieldManager); // add(indicatorView); // } else { add(indicatorView); add(fieldManager); // } } private void setBitmap(final byte[] bytes) { // TODO Auto-generated method stub if (bytes != null) { if (bytes.length < 500) bitmap = Bitmap.getBitmapResource("Placeholder.png"); else bitmap = Bitmap.createBitmapFromBytes(bytes, 0, bytes.length, Bitmap.SCALE_TO_FIT); } if (bitmap != null) { Bitmap newBitmap = new Bitmap(width, fieldHeight); bitmap.scaleInto(newBitmap, Bitmap.SCALE_TO_FIT); indicatorView.setBitmap(newBitmap); } } public boolean isFocusable() { return true; } protected void onFocus(int direction) { setVisualState(VISUAL_STATE_FOCUS); setBackground(VISUAL_STATE_FOCUS, BackgroundFactory.createSolidBackground(Color.CORA L)); if (direction == 1) { if (getTop() + getPreferredHeight() >= (getManager() .getVerticalScroll() + getManager().getVisibleHeight())) getManager().setVerticalScroll(getTop(), true); } else { if (getTop() < getManager().getVerticalScroll()) getManager().setVerticalScroll(getTop(), true); } super.onFocus(direction); } protected void onUnfocus() { setVisualState(VISUAL_STATE_NORMAL); invalidate(); super.onUnfocus(); } protected void sublayout(int maxWidth, int maxHeight) { super.sublayout(Display.getWidth(), fieldHeight); setExtent(Display.getWidth(), fieldHeight); } // protected void paint(Graphics graphics) { // if (bitmap == null && !imageRequestSent) { // ImageController controller = new ImageController(); // controller.setImageListener(this); // controller.requestImage(item); // imageRequestSent = true; // } // super.paint(graphics); // } protected boolean navigationClick(int status, int time) { fieldChangeNotify(FieldChangeListener.PROGRAMMATIC ); return true; } protected boolean touchEvent(TouchEvent message) { int x = message.getX(1); int y = message.getY(1); if (x > 0 && x < getWidth() && y > 0 && y < getHeight()) { setFocus(); if (message.getEvent() == TouchEvent.GESTURE) { if (message.getGesture().getEvent() == TouchGesture.TAP) { fieldChangeNotify(FieldChangeListener.PROGRAMMATIC ); } } return true; } return super.touchEvent(message); } public static ItemsTitle getNewInstance(ItemBean item, int size) { return new ItemsTitle(item, size); } public void retry() { System.out.println("NewsTitle.retry()"); } public void connectionLost() { System.out.println("NewsTitle.connectionLost()"); } public void imageRecevied() { // imageRequestSent = false; UiApplication.getUiApplication().invokeLater(new Runnable() { public void run() { // TODO Auto-generated method stub ImageFromUrl _img = new ImageFromUrl(item.getThumbLink()); setBitmap(_img.getbitmap()); } }); }
and that's the class responsible of the screen
import net.rim.device.api.i18n.Locale;
import net.rim.device.api.system.Bitmap;
import net.rim.device.api.ui.DrawStyle;
import net.rim.device.api.ui.Graphics;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.BitmapField;
import net.rim.device.api.ui.component.ListField;
import net.rim.device.api.ui.component.ListFieldCallback;
import net.rim.device.api.ui.component.SeparatorField;
import net.rim.device.api.ui.container.MainScreen;
public class ItemsScreen extends MainScreen {
AppManger appManger;
ItemBean[] items;
ListField itemsList;
int i = 0;
public ItemsScreen() {
Locale.setDefault(Locale.get(Locale.LOCALE_ar));
appManger = AppManger.getInstance();
items = appManger.getItemsBean();
for (int i = 0; i < items.length; i++) {
ItemsTitle newsTitle = ItemsTitle.getNewInstance(items[i],
ItemsTitle.SMALL_SIZE);
add(newsTitle);
add(new SeparatorField());
}
}
}please guys help me
05-31-2012 11:24 AM
05-31-2012 11:39 AM
05-31-2012 11:42 AM
05-31-2012 11:49 AM
05-31-2012 12:24 PM
Sounds like you are still not running your bitmap downloads in a separate Thread. Perhaps you can show us the code to confirm this?
05-31-2012 12:34 PM
that's the method which get the images
public byte[] getbitmap() {
new Thread(new Runnable() {
public void run() {
// TODO Auto-generated method stub
try {
connection = (HttpConnection) Connector.open(url,
Connector.READ, true);
inputStream = connection.openInputStream();
byte[] responseData = new byte[10000];
int length = 0;
StringBuffer rawResponse = new StringBuffer();
while (-1 != (length = inputStream.read(responseData))) {
rawResponse.append(new String(responseData, 0, length));
}
int responseCode = connection.getResponseCode();
if (responseCode != HttpConnection.HTTP_OK) {
throw new IOException("HTTP response code: "
+ responseCode);
}
final String result = rawResponse.toString();
dataArray = result.getBytes();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
// TODO Auto-generated method stub
return dataArray;
}
and I made the method which update the bitmap void to set the indicator
private void setBitmap() {
// TODO Auto-generated method stub
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
// TODO Auto-generated method stub
ImageFromUrl _img = new ImageFromUrl(item.getThumbLink());
byte[] bytes = _img.getbitmap();
Bitmap newBitmap = new Bitmap(width, fieldHeight);
bitmap = Bitmap.createBitmapFromBytes(bytes, 0, bytes.length,
Bitmap.SCALE_TO_FIT);
bitmap.scaleInto(newBitmap, Bitmap.SCALE_TO_FIT);
indicatorView.setBitmap(bitmap);
}
});
}now it shows nullPointerException and enter the list without updating the images
05-31-2012 04:49 PM
Unfortunately there are a couple of significant issues with the code:
Remember that a Thread does not run synchronously wit the process that invokes it. Your
getbitmap()
method, assumes that immediately after the
new Thread (...
).start(), that the data is there. It isn't. In fact the Thread probably hasn't even started by the time you hit the
return dataArray;
statement.
So I have no idea what is going to be in dataArray but I suspect it is not what you want. Put breakpoints in your code, or System.out.println(..) statements to see this in action.
To resolve this you are going to have to figure out a way of only updating the Bitmap on the screen when the response comes back.
When it does come back, you should perform as little processing in the invokeLater as possible - i.e. do as much processing using the background Thread as you can. the only statement that needs to be in the invokeLater is:
indicatorView.setBitmap(bitmap);
All the scaling and so on can be done in the Background Thread.
Anyway, to fix this code, you really need to move the code you have in the invokeLater into your getBitmap(), so getBitmap obtains the Bitmap and updates the Ui - with only the Ui update actually being done with invokeLater.
Once you have got this going, you may start running into problems with multiple Threads, as I suspect you start a Thread per download and you have quite a number of Bitmaps to get. Have a think about how you could restrict the number of concurrent downloads you do.
One final thing. Don't just do this because we tell you. Try to understand why this is happening and what you are actually doing about it. Unless you actually understand these basics, you will hit other problems when you do other processing in Blackberry java (and in other platforms as well actually).