Question

Hi can you please tell me which is a better approach while getting data from server and displaying on a list?

package mypackage;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import javax.microedition.io.Connector;
import javax.microedition.io.HttpConnection;

import net.rim.device.api.io.IOUtilities;
import net.rim.device.api.ui.component.Dialog;

public class ConnectJson extends Thread {

 private String url;
 public String response;
 private String myinterface = ";deviceside=true";
 private JsonObserver observer;


  public void run() {
         HttpConnection conn = null;
         InputStream in = null;
         int code;

   try {
      conn = (HttpConnection) Connector.open(this.url + this.myinterface, Connector.READ);
         conn.setRequestMethod(HttpConnection.GET);
         code = conn.getResponseCode();
         System.out.println("naveen-------------------------");
         if (code == HttpConnection.HTTP_OK) {
             in = conn.openInputStream();
             byte[] buffer = IOUtilities.streamToBytes(in);
             this.response = new String(buffer,"UTF-8");
             if (observer != null) {
                 observer.onResponseReceived(this.response);
             }



             if (in != null){
                 in.close();
             }
             if (conn != null){
                 conn.close();
             }
         }

     } catch (Exception e) {
        Dialog.inform(e.toString());
     }
}  

public String jsonResult(String url){
  this.url = url;
 this.start();
// this.run();
  return response;
 }

public void setObserver(JsonObserver o) {
    this.observer = o;
}
}

package mypackage;

import java.util.Vector;

import xjson.me.JSONArray;
import xjson.me.JSONException;
import xjson.me.JSONObject;


import net.rim.device.api.system.Display;
import net.rim.device.api.ui.Color;
import net.rim.device.api.ui.Graphics;
import net.rim.device.api.ui.component.ButtonField;
import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.component.ObjectChoiceField;
import net.rim.device.api.ui.container.MainScreen;
import net.rim.device.api.ui.container.VerticalFieldManager;

/**
 * A class extending the MainScreen class, which provides default standard
 * behavior for BlackBerry GUI applications.
 */
public final class MyScreen extends MainScreen implements JsonObserver
{
    /**
     * Creates a new MyScreen object
     */
    public MyScreen()
    {        

        ConnectJson connectJson = new ConnectJson();
        System.out.println("------------------");
        connectJson.setObserver(this);

        connectJson.jsonResult("http://musicbrainz.org/ws/2/release/59211ea4-ffd2-4ad9-9a4e-941d3148024a?inc=artist-credits+labels+discids+recordings&fmt=json");

        System.out.println("---------bbbbb---------");





    }


    public void onResponseReceived(String response) {
        System.out.println("000000000000000000000000000000000"+response);

        // TODO: create or update your ListField here!!!
    }
}

package mypackage;

public interface JsonObserver {
       public void onResponseReceived(String response);
    }
Was it helpful?

Solution

Well, first of all, this will not work:

public String jsonResult(String url){
   this.url = url;
   this.start();

   return response;
}

Calling start() will cause run() to be called on a background thread (that's good). However, immediately after you start the background thread, you return the response member variable. That won't work, because the run() method hasn't had time to actually assign the response variable.

What you need to do is assign the response variable at the end of the run() method, and then notify the UI on the main/UI thread, to let it update the user interface. Something like this:

     if (code == HttpConnection.HTTP_OK) {
         in = conn.openInputStream();
         byte[] buffer = IOUtilities.streamToBytes(in);
         this.response = new String(buffer,"UTF-8");
         UiApplication.getUiApplication().invokeLater(new Runnable() {
            public void run() {
                // this code is run on the main/UI thread
                if (observer != null) {
                    observer.onResponseReceived(this.response);
                }
            }
         });

where you add a new observer interface

public interface JsonObserver {
   public void onResponseReceived(String response);
}

and then you can let your MainScreen implement that interface:

public class MyScreen extends MainScreen implements JsonObserver {

    public MyScreen()
    {        
        connectJson.setObserver(this);
        // start the json request
        connectJson.jsonResult("http://musicbrainz.org/ws/2/release/59211ea4-ffd2-4ad9-9a4e-941d3148024a?inc=artist-credits+labels+d...");
    }

    public void onResponseReceived(String response) {
        System.out.println("000000000000000000000000000000000"+response);

        // TODO: create or update your ListField here!!!
    }

Of course, you'll need a new member and method in the ConnectJson class, too:

private JsonObserver observer;

public void setObserver(JsonObserver o) {
    observer = o;
}

Note: it also might be better, for thread safety, to change your response member variable to a simple local final variable. I can't know all the ways that you plan on using it, but if it's just a way to hold onto the JSON response, you probably don't need a member variable. Try this instead (inside of run()):

     final String response = new String(buffer,"UTF-8");
     UiApplication.getUiApplication().invokeLater(new Runnable() {
         public void run() {
             observer.onResponseReceived(response);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top