Добавление поля из нонуи-нить выдает исключение в Blackberry? - PullRequest
0 голосов
/ 13 сентября 2011

Привет, ребята, я пробую пример, где у меня есть кнопка, которая загружает изображение, а затем оно должно отображаться на экране.Я использую следующий код, чтобы сделать это.Не знаю, где-то я иду неправильно.это бросает мне незаконное исключение.Может кто-нибудь, пожалуйста, посмотрите на мой код и предоставьте мне некоторую помощь.

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;
    }
}

Примечание: загрузка изображения работает нормально.даже я проверил с другим образцом.

Согласно предложению Дэна, я изменил следующий код и разделил логику загрузки в другой поток.

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();
        }
    }

Ответы [ 3 ]

4 голосов
/ 17 сентября 2011

Какое исключение вы получаете (есть ли в нем сообщение?)?На каком этапе / линии?В качестве возможного случая вы можете получить недопустимое исключение, если ваш Bitmap слишком велик для создания экземпляра BitmapField.Какие размеры (ширина х высота) у вашего Bitmap?По моему опыту, начиная с ~ 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 был добавлен OK», просто удалите все оповещения (просто оставьте только в разделе catch - на всякий случай), и он должен работать Ok.

1 голос
/ 17 сентября 2011

Несколько вещей ...

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, вам нужно добавить суффикс URL к ;deviceside=true

. Работает для меня.Без исключений.Работает на симуляторе OS 5 9550.

1 голос
/ 13 сентября 2011

Вы захватываете блокировку события и выполняете загрузку (блокируете все приложение до завершения. Вам нужно использовать поток, чтобы выполнить загрузку из потока пользовательского интерфейса (без захвата блокировки события), и вызывать свой пользовательский интерфейс обновления. Послепоток завершает свою задачу

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