отображение данных и изображений в поле списка из json Like Lazy loading Blackberry

Я создал список, содержащий изображение и некоторые данные в одной строке, изображение и данные, которые я получаю из Json. Мой код работает, но после получения списка мой пользовательский интерфейс зависает. Есть два шага: 1) проанализировать данные и URL-адрес изображения из json 2) и показать в поле списка. Я опубликую свой код и снимок экрана списка ниже

http://supportforums.blackberry.com/t5/image/serverpage/image-id/19759iD4089A71454F66E0/image-size/large/is-moderation-mode/true?v=mpbl-1&px=600

public final class MyScreen extends MainScreen implements ListFieldCallback
{
    HttpConnection httpConn;
    int responseCode;
    private static ListField _list;
    private static Vector listElements = new Vector();
    private static Vector elements = new Vector();
    private static Vector contentelements = new Vector();
    private static Vector datelements = new Vector();
    private static Vector Imageselements = new Vector();

    LabelField label;
    String imagename;

    Bitmap bit ;

    Connection connectionthread;

    public MyScreen()
    {        
        // Set the displayed title of the screen  
        //setTitle("MyTitle");

        _list = new ListField();

        _list.invalidate();
        _list.setEmptyString("please wait..", DrawStyle.HCENTER);
        _list.setRowHeight(100);
        _list.setCallback(this);
        add(_list);

        connectionthread = new Connection();
        connectionthread.start();

    }

    public class Connection extends Thread{

        public void run() { 
            try {
                String httpURL = "http://192.168.1.91/bjp_app/program"+ getConnectionString();  

                httpConn = (HttpConnection) Connector.open(httpURL);
                httpConn.setRequestMethod(HttpConnection.GET);

                responseCode = httpConn.getResponseCode(); 
                if (responseCode != HttpConnection.HTTP_OK) 
                { 
                    throw new IOException("HTTP response code: "+ responseCode); 
                    //System.out.println("\n Internaet problem HttpConnection. = "+responseCode);

                }else{
                    System.out.println("\n elseeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee= ");
                    System.out.println("\nHttpConnection.HTTP_OK = "+responseCode);

                DataOutputStream _outStream = new DataOutputStream(httpConn.openDataOutputStream());

                byte[] request_body = httpURL.getBytes();
                for (int i = 0; i < request_body.length; i++) {

                    _outStream.writeByte(request_body[i]);
                }

                DataInputStream _inputStream = new DataInputStream(
                httpConn.openInputStream());

                StringBuffer _responseMessage = new StringBuffer();
                int ch;
                while ((ch = _inputStream.read()) != -1) {

                    _responseMessage.append((char) ch);
                }

                String res = (_responseMessage.toString());
                String responce = res.trim();
                System.out.println("\nresponce= "+responce);


                JSONArray jsnarry = new JSONArray(responce);

                System.out.println("\n--length----- "+jsnarry.length());

                for (int i = 0; i < jsnarry.length(); i++){

                    JSONArray inerarray = jsnarry.getJSONArray(i);
                    System.out.println("\n-innerarray-length----- "+inerarray.length());

                    //for (int i1 = 0; i1 < inerarray.length(); i1++) {
                        //System.out.println("\n-inerarray-values----- "+inerarray.getString(i1));
                        String ID = inerarray.getString(0);
                        String TITTLE = inerarray.getString(1);
                        String CONTENT = inerarray.getString(2);
                        String DATE = inerarray.getString(3);
                        String IMAGE = inerarray.getString(4);
                        String six = inerarray.getString(5);

                        System.out.println("................................................");
                        System.out.println("ID= "+ID);
                        System.out.println("TITTLE= "+TITTLE);
                        System.out.println("CONTENT= "+CONTENT);
                        System.out.println("DATE= "+DATE);
                        System.out.println("IMAGE= "+IMAGE);
                        imagename = "http://sanjaytandon.in/admin/image/"+IMAGE.trim();
                        System.out.println("imagename= "+imagename);
                        //System.out.println("six "+six);
                        System.out.println("....................................................=");
                       // String jsonresponse = ""+inerarray.getString(i1);
                        //label = new LabelField(jsonresponse,LabelField.FOCUSABLE);
                        //add(label);
                    //}
                        elements.addElement(TITTLE);
                        contentelements.addElement(CONTENT);
                        datelements.addElement(DATE);
                        Imageselements.addElement(imagename); 



                }


                UiApplication.getUiApplication().invokeLater(new Runnable() { 

                    public void run() { 

                        try {
                            _list.setSize(elements.size());
                            _list.setSize(contentelements.size());
                            _list.setSize(datelements.size());
                            _list.setSize(Imageselements.size());
                            //invalidate();
                        } catch (Exception e) {
                            // TODO Auto-generated catch block
                            System.out.println("error _list.setSize"+e.toString());
                        }

                    } 

                });
                }

            } catch (Exception e) {
                // TODO Auto-generated catch block
                System.out.println("\nresponce code error "+e.toString());
                UiApplication.getUiApplication().invokeLater(new Runnable() {

                    public void run() {
                        // TODO Auto-generated method stub
                        Status.show("Check your internet connection!", 2000);
                    }
                });

            }

        }

    }

    public void drawListRow (ListField listField, Graphics graphics, int index, int y, int w) {

        try {


            graphics.setGlobalAlpha(255);
            final int margin =5;

            String tittle = (String)elements.elementAt(index);
            String content = (String)contentelements.elementAt(index);
            String date = (String)datelements.elementAt(index);
            String imagesurl = (String)Imageselements.elementAt(index);

            UrlToImage img = new UrlToImage( imagesurl);

            bit =img.getbitmap();

            graphics.drawText(tittle.trim(), 3*margin+bit.getWidth(),  y+margin);

            graphics.drawText(content.trim(), 3*margin+bit.getWidth(), y+ margin+30);

            graphics.drawText(date.trim(), 3*margin+bit.getWidth(),    y+ margin+60);

            graphics.drawBitmap(2, y+margin+5, bit.getWidth(), bit.getHeight(), bit, 0, 0);


        } catch (Exception e) {
            // TODO Auto-generated catch block
            System.out.println("error drawListRow"+e.toString());
        }

    }


    public Object get(ListField listField, int index) {
        // TODO Auto-generated method stub
        return null;
    }

    public int getPreferredWidth(ListField listField) {
        // TODO Auto-generated method stub
        return 0;
    }

    public int indexOfList(ListField listField, String prefix, int start) {
        // TODO Auto-generated method stub
        return 0;
    }

и МОЙ класс UrlToImage.java, который загружает изображения из URL

public class UrlToImage {

    public static Bitmap _bmap;

    UrlToImage(final String url){

        HttpConnection connection = null; 
        InputStream inputStream = null; 
        EncodedImage bitmap;
        byte[] dataArray = null;

        try { 

            connection = (HttpConnection) Connector.open(url+ getConnectionString(), 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); 
            }else{
                System.out.println("\nHttpConnection.HTTP_OK = "+responseCode);
            }

            final String result = rawResponse.toString(); 
            dataArray = result.getBytes(); 
            /*System.out.println("\ndataArray.length = "+dataArray.length);
            System.out.println("\ndataArray.length = "+dataArray[0]);
            System.out.println("\ndataArray.length = "+dataArray[1]);
            System.out.println("\ndataArray.length = "+dataArray[2]);
            System.out.println("\ndataArray.length = "+dataArray[3]);*/

        } catch (final Exception ex) { 

        }finally { 

            try { 

                inputStream.close(); 
                inputStream = null; 
                connection.close(); 
                connection = null; 
            } 
            catch(Exception e){

            } 
        } 

        bitmap = EncodedImage.createEncodedImage(dataArray, 0,dataArray.length);
        // this will scale your image acc. to your height and width of bitmapfield

        int multH;
        int multW;
        int currHeight = bitmap.getHeight();
        int currWidth = bitmap.getWidth();
        multH= Fixed32.div(Fixed32.toFP(currHeight),Fixed32.toFP(80));//height
        multW = Fixed32.div(Fixed32.toFP(currWidth),Fixed32.toFP(80));//width
        bitmap = bitmap.scaleImage32(multW,multH);

        _bmap=bitmap.getBitmap();

    }

    public String getConnectionString() {

      String connectionString = null;

      // Simulator behaviour is controlled by the USE_MDS_IN_SIMULATOR
      // variable.
      if (DeviceInfo.isSimulator()) {

          connectionString = ";deviceside=true";
          System.out.println("11111111111111111");
      }

      // Wifi is the preferred transmission method
      else if (WLANInfo.getWLANState() == WLANInfo.WLAN_STATE_CONNECTED) {

          connectionString = ";interface=wifi";
          System.out.println("222222222222222222");
      }

      // Is the carrier network the only way to connect?
      else if ((CoverageInfo.getCoverageStatus() & CoverageInfo.COVERAGE_DIRECT) == CoverageInfo.COVERAGE_DIRECT) 
      {

          String carrierUid = getCarrierBIBSUid();

          if (carrierUid == null) {
              // Has carrier coverage, but not BIBS. So use the carrier's TCP
              // network
             System.out.println("33333333333333333");
              connectionString = ";deviceside=true";
          } else {
              // otherwise, use the Uid to construct a valid carrier BIBS
              // request
             System.out.println("444444444444444444");
              connectionString = ";deviceside=false;connectionUID="+carrierUid + ";ConnectionType=mds-public";
          }
      }

      // Check for an MDS connection instead (BlackBerry Enterprise Server)
      else if ((CoverageInfo.getCoverageStatus() & CoverageInfo.COVERAGE_MDS) == CoverageInfo.COVERAGE_MDS) 
      {
         System.out.println("55555555555555555555");
          connectionString = ";deviceside=false";
      }

      // If there is no connection available abort to avoid hassling the user
      // unnecssarily.
      else if (CoverageInfo.getCoverageStatus() == CoverageInfo.COVERAGE_NONE) 
      {
         System.out.println("66666666666666666666");
          connectionString = "none";

      }

      // In theory, all bases are covered by now so this shouldn't be reachable.But hey, just in case ...
      else {
         System.out.println("77777777777777777777777");
          connectionString = ";deviceside=true";
      }

      return connectionString;
  }

  /**//**
   * Looks through the phone's service book for a carrier provided BIBS
   * network
   * 
   * @return The uid used to connect to that network.
   *//*
*/  private synchronized String getCarrierBIBSUid() {
      ServiceRecord[] records = ServiceBook.getSB().getRecords();
      int currentRecord;

      for (currentRecord = 0; currentRecord < records.length; currentRecord++) {
          if (records[currentRecord].getCid().toLowerCase().equals("ippp")) {
              if (records[currentRecord].getName().toLowerCase()
                      .indexOf("bibs") >= 0) {
                  return records[currentRecord].getUid();
              }
          }
      }

      return null;
  }
public Bitmap getbitmap()
{

    return _bmap;

}


}

person Achin    schedule 01.11.2013    source источник
comment
Я получаю список, содержащий данные с изображениями, но мой пользовательский интерфейс зависает   -  person Achin    schedule 01.11.2013


Ответы (1)


Для ListField этот метод:

public void drawListRow (ListField listField, Graphics graphics, int index, int y, int w) 

будет вызываться в основном потоке (он же "UI"). Этот метод предназначен для рисования. Однако у вас есть эти строки кода в этом методе:

       UrlToImage img = new UrlToImage( imagesurl);
       bit =img.getbitmap();

Поскольку вы реализовали класс UrlToImage, этот код выполняет сетевой вызов. Сетевые вызовы не должны выполняться в потоке пользовательского интерфейса. Если вы это сделаете, ваш пользовательский интерфейс будет зависать/зависать.

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

Возможно, вы захотите взглянуть на этот недавний ответ, который выполняет ленивую загрузку изображений в фоновом режиме. Этот ответ немного отличается тем, что в нем используется пользовательский список, а не стандартный ListField. Для стандартного ListField вы можете вызвать перерисовку строки списка с помощью ListField#invalidate(int):

 // image for row 'x' download complete.  save image as member data
 //  that can be accessed in drawListRow().

 UiApplication.getUiApplication().invokeLater(new Runnable() {
    public void run() {
       _list.invalidate(x);
    }
 });
person Nate    schedule 01.11.2013
comment
@ user12345 - Думаю, отдельный вопрос. Не забудьте провести некоторое исследование, прежде чем задать вопрос, чтобы вы могли задать конкретные вопросы. - person Peter Strange; 01.11.2013