大家好我正在尝试一个样本,我有一个按钮,下载图像,然后它需要在屏幕上呈现。我使用以下代码来完成它。不知道某个地方我真的错了。它抛出我非法的例外。任何人都可以看看我的代码并给我一些帮助。
import java.io.IOException;
import java.io.InputStream;
import javax.microedition.io.Connector;
import javax.microedition.io.HttpConnection;
import net.rim.device.api.system.Application;
import net.rim.device.api.system.Bitmap;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.FieldChangeListener;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.BitmapField;
import net.rim.device.api.ui.component.ButtonField;
import net.rim.device.api.ui.container.MainScreen;
public class GoogleChart extends MainScreen implements FieldChangeListener{
ButtonField btn = new ButtonField("Download");
GoogleChart activeScreen = null;
public GoogleChart() {
setTitle("Download image");
btn.setChangeListener(this);
add(btn);
this.activeScreen = (GoogleChart)UiApplication.getUiApplication().getActiveScreen();
}
public void fieldChanged(Field field, int context) {
if(field == btn){
updateUI();
}
}
private void updateUI(){
synchronized (Application.getEventLock()) {
activeScreen.add(new BitmapField(downloadImage()));
activeScreen.invalidate();
}
}
public Bitmap downloadImage() {
byte[] dataArray;
InputStream input;
StringBuffer url = new StringBuffer("IMAGE URL");
HttpConnection httpConn = null;
Bitmap googleImage = null;
try {
httpConn = (HttpConnection) Connector.open(url.toString());
input = httpConn.openInputStream();
dataArray = net.rim.device.api.io.IOUtilities.streamToBytes(input);
googleImage = Bitmap.createBitmapFromBytes(dataArray, 0, -1, 1);
} catch (IOException e) {
e.printStackTrace();
}
return googleImage;
}
}
注意:图像下载工作正常。即使我已经测试过其他样品。
根据Dan的建议,我更改了以下代码,并将下载逻辑分成另一个线程。
class Download extends Thread{
Bitmap googleImage = null;
private void updateUI(){
synchronized (Application.getEventLock()) {
if(googleImage != null){
activeScreen.add(new BitmapField(googleImage));
activeScreen.invalidate();
}
}
}
public void run() {
googleImage = downloadImage();
updateUI();
}
public Bitmap downloadImage() {
byte[] dataArray;
InputStream input;
StringBuffer url = new StringBuffer("http://");
HttpConnection httpConn = null;
Bitmap googleImage = null;
try {
httpConn = (HttpConnection) Connector.open(url.toString());
input = httpConn.openInputStream();
dataArray = net.rim.device.api.io.IOUtilities.streamToBytes(input);
googleImage = Bitmap.createBitmapFromBytes(dataArray, 0, -1, 1);
} catch (IOException e) {
e.printStackTrace();
}
return googleImage;
}
}
并像这样调用线程
public void fieldChanged(Field field, int context) {
if(field == btn){
new Download().start();
}
}
答案 0 :(得分:4)
你到底有什么例外(它有没有消息?)?在什么步骤/线?作为一种可能的情况,如果Bitmap
太大而无法创建BitmapField
实例,则可能会收到非法异常。您的Bitmap
有哪些尺寸(宽x高)?根据我从~1.5 Mpx开始的经验,无法创建BitmapField
(确切的限制取决于设备型号/操作系统级别)。
<强>更新强>
好的,然后找出发生了什么可以尝试以下方法吗?
private void updateUI() {
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
if (googleImage == null) {
Dialog.alert("googleImage is null");
} else {
Dialog.alert("googleImage is not null");
try {
BitmapField b = new BitmapField(googleImage);
Dialog.alert("BitmapField has been created OK");
activeScreen.add(b);
Dialog.alert("BitmapField has been added OK");
// no need to invalidate, since adding a new Field forces
// the screen to be repainted
} catch (Exception e) {
Dialog.alert("Got error: " + e);
}
}
}
});
}
你看到了什么消息?如果你已经“添加了BitmapField”,那么只需删除所有警报(只留在catch
部分 - 以防万一),它应该可以正常工作。
答案 1 :(得分:1)
您正在捕获事件锁定并执行下载(锁定整个应用程序直到完成。 您需要使用一个线程来执行UI线程的下载(不捕获事件锁定)并在线程完成其任务后调用您的更新UI
答案 2 :(得分:1)
一些事情......
1)由于Download
是内部类,因此您不需要引用activeScreen
因此,请将updateUI
方法更改为以下内容:
private void updateUI() {
synchronized (Application.getEventLock()) {
if(googleImage != null ) {
add(new BitmapField(googleImage));
//invalidate();
}
}
2)FieldChangeListener对我不起作用。如果您使用new ButtonField("blah", ButtonField.CONSUME_CLICK)
之类的实例进行实例化,则可能会有效。但是,我正在使用以下内容收听点击:
ButtonField btn = new ButtonField("Download") {
protected boolean navigationClick(int arg0, int arg1) {
new Download().start();
return true;
}
};
3)你下载什么类型的图像?要处理JPG,PNG等,你需要这样的东西来处理Bitmap
类上的字节数组而不是静态方法:
EncodedImage img = EncodedImage.createEncodedImage(dataArray, 0, dataArray.length);
googleImage = img.getBitmap();
4)在模拟器中,如果您没有使用MDS,则需要使用;deviceside=true
适合我。没有例外。在OS 5 9550模拟器上运行。