3

urlHi i've this code that works receiving data from a php page and i want to put that data in a listview. I receive that data and i've seen that with a system.out.println but i have white rows in the listview. Code:

public class Utenti extends ListActivity {


ListView lv;
    
ListView listView;

static String temp;
    //ListAdapter adapter;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    

    
           
        
          
    StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
    
      StrictMode.setThreadPolicy(policy);
      
    


lv = getListView();
lv.setTextFilterEnabled(true);
lv.setOnItemClickListener(new OnItemClickListener() {
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        

        }
    });

     
      

      
      Thread t = new Thread(new Runnable (){

          public void run() {
              //Looper.prepare();
              JSONObject json =conn("ketut.php");

              try {
                  //Get the element that holds the earthquakes ( JSONArray )
                  JSONArray  ute = json.getJSONArray("success");
                  final List<HashMap<String, String>> mylist = 
                          new ArrayList<HashMap<String, String>>();
                  HashMap<String, String> map = new HashMap<String, String>();
                     for(int i=0;i < ute.length();i++){

                      JSONObject e = ute.getJSONObject(i);
                       System.out.println(e.getString("user"));

                      
                      
                       map.put("name",  e.getString("user"));
                       
                      
                     
                       mylist.add(map);
                  }

                     runOnUiThread(new Runnable() {


                         public void run() {

                          ListAdapter adapter = new SimpleAdapter(Utenti.this, mylist , R.layout.utentii,new String[] { "name" },new int[] { 1});
                          Utenti.this.setListAdapter(adapter);
                          }

                      });

              } catch (JSONException e) {
                  System.out.println("4");
                  e.printStackTrace();
              }

          }
      });
              t.start();
        //  t.start();  
      

     


        

}


public  static JSONObject conn(String pagina){
    HttpURLConnection connection;
    OutputStreamWriter request = null;
    URL url = null;
    String response = null;
    JSONObject jArray = null;
    

    try
        {
            url = new URL("url"+pagina);
            connection = (HttpURLConnection) url.openConnection();
            connection.setDoOutput(true);
            connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            connection.setRequestMethod("POST");

            
            String line = "";

            InputStreamReader isr = new InputStreamReader(connection.getInputStream());
            BufferedReader reader = new BufferedReader(isr);
            StringBuilder sb = new StringBuilder();
            while ((line = reader.readLine()) != null)
            {
                sb.append(line + "\n");
            }
            response = sb.toString();
            System.out.println(response);
            try{jArray=new JSONObject (response);}
            catch(JSONException e){}
            
            isr.close();
            reader.close(); 
        }
        catch(IOException e)
        {
            Log.i("NetworkTest","Network Error: " + e);
        }
    return jArray;
}}

utentii.xml

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dp"
android:textSize="20sp" >

Image of the problem

Community
  • 1
  • 1
  • We'll need to see the JSON you're getting from the server – Matt Taylor Apr 24 '13 at 14:19
  • {"success":[{"user":"anto"},{"user":"Francesco"},{"user":"giuseppe"},{"user":"lol"},{"user":"sdasad"}],"message":"loggato"} i want only "user" – Francesco Stranieri Apr 24 '13 at 14:21
  • http://stackoverflow.com/questions/3674951/whats-the-role-of-adapters-in-android – Budius Apr 24 '13 at 14:22
  • you are runnning your connection on the ui thread ... – njzk2 Apr 24 '13 at 14:24
  • you are not calling notifyDatasetChanged – njzk2 Apr 24 '13 at 14:25
  • the problem isn't the connection or the data received because that works, the problem is the listview – Francesco Stranieri Apr 24 '13 at 14:26
  • where are you calling `ListAdapter adapter = new SimpleAdapter(this, mylist , R.layout.utentii,newString[] { "name" },new int[] { 1}); setListAdapter(adapter);` after you have populated your `mylist` on click and then `notifyDatasetChanged`? – Sergey Benner Apr 24 '13 at 18:07
  • i've tried to remove the thread declaration, so i do it only with try and catch and the result is the same of before : white rows...now i've tried with ((BaseAdapter) adapter).notifyDataSetChanged(); and nothing, always white rows but always i see that the number of rows is the number of results of json data, so is it only a problem of text? – Francesco Stranieri Apr 24 '13 at 18:15

1 Answers1

2

no. runOnUiThread() is necessary because you want to call setListAdapter.

again. - move these two lines

ListAdapter adapter = new SimpleAdapter(Utenti.this, mylist , R.layout.utentii,new String[] { "name" },new int[] { 1});
setListAdapter(adapter);

right after the for(){} loop in the onClick() method.

if you are sure that your mylist list is populated with data in your json call.

basically something like this as a sample:

replace your xml file contents with the following:

test.xml

<ListView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/list"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" /> 

for rows of the ListView

row.xml

 <?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="match_parent">

    <TextView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="New Text"
            android:id="@+id/textView" android:layout_gravity="center"/>
</LinearLayout>

then the onCreate():

  @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.test);
        StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();

        StrictMode.setThreadPolicy(policy);

        ListView lv = getListView();
        populateListView();

        lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

                populateListView();
            }
        });

    }

    private void populateListView(){

        Thread t = new Thread(new Runnable (){

            public void run() {

                JSONObject json = getUserObject("http://myhost:8080/login/email");
                Log.i("json",json.toString());

                try {
                    //Get the element that holds the earthquakes ( JSONArray )
                    JSONArray friends = json.getJSONObject("user").getJSONArray("friends");

                    final List<Map<String, String>> mylist =
                            new ArrayList<Map<String, String>>();

                    //get list of friend ids in the user object
                    for(int i=0;i < friends.length();i++){
                        Map<String,String> map = new LinkedHashMap<String, String>();
                        map.put("friendid", friends.getString(i));
                        mylist.add(map);

                    }
                    runOnUiThread(new Runnable() {
                        public void run() {
                            ListAdapter adapter = new SimpleAdapter(MyTestListActivity.this, mylist , R.layout.row,new String[] { "friendid" },new int[] {R.id.textView});
                            setListAdapter(adapter);
                        }
                    });

                } catch (JSONException e) {
                    System.out.println("4");
                    e.printStackTrace();
                }

            }
        });
        t.start();

    }

    public  static JSONObject getUserObject(String page){

        JSONObject jArray = null;

        try
        {
            HttpClient httpclient = new DefaultHttpClient();
            HttpPost httppost = new HttpPost(page);

            List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
            nameValuePairs.add(new BasicNameValuePair("user", "test"));
            nameValuePairs.add(new BasicNameValuePair("pwd", "test"));

            httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
            HttpResponse response = httpclient.execute(httppost);
            String str = EntityUtils.toString(response.getEntity(), HTTP.UTF_8);
            try{
                jArray=new JSONObject (str);}
            catch(JSONException e){Log.d("error",e);}    

        }
        catch(Exception e)
        {
            Log.i("NetworkTest", "Network Error: " + e);
        }
        return jArray;
    }

hope this helps abit.

Sergey Benner
  • 4,421
  • 2
  • 22
  • 29
  • it's impossible because 'this' is a reference of the main thread, can't be a runnable() – Francesco Stranieri Apr 24 '13 at 18:43
  • yes. i've updated the reference to your activity in the call. – Sergey Benner Apr 24 '13 at 18:48
  • `Utenti.this.setListAdapter(adapter);` should do it. i've updated the answer. – Sergey Benner Apr 24 '13 at 19:07
  • `public void run()` override missed in the `RunOnUiThread()` of course – Sergey Benner Apr 24 '13 at 19:14
  • nothing, neither the 5 rows, all white...maybe i've to search another way to put json data array in a listview... – Francesco Stranieri Apr 24 '13 at 19:24
  • are you sure you're getting the data? + your listview has to have rows before you click on them naturally. in order to get them there move the `Thread t = new.....` part into a separate method then call it in the `onCreate()` method. then `onClick()` will work because your rows will be there already but in order to get it more robust you will have to get the data from the rows which will lead you to make your custom ListAdapter where you override the `getView()` method for it. and so on and so forth. – Sergey Benner Apr 24 '13 at 19:30
  • the mylist you have created is final into that try, after you use another mylist into the adapter, is it right? – Francesco Stranieri Apr 24 '13 at 19:47
  • it has to be `final` otherwise it wont be referenced from within the Runnable's run() of the RunOnUiThread() method and remove the `ArrayList> mylist;` member of the activity class of course. – Sergey Benner Apr 24 '13 at 19:49
  • because it suggests a cast on mylist in ListAdapter adapter = new SimpleAdapter(Utenti.this, mylist , R.layout.utentii,new String[] { "name" },new int[] { 1}); because it's an error, before i've tried with the other mylist (my error) – Francesco Stranieri Apr 24 '13 at 20:03
  • Indeed? sorry the `SimpleAdapter` accepts the `List extends Map> ` type parameter as data. – Sergey Benner Apr 24 '13 at 20:14
  • another syntax error with put() method , i've solved adding HashMap map = new HashMap(); map.put("name", e.getString("user")); mylist.add(map); but always that 5 white rows...i'm sorry if you're wasting time – Francesco Stranieri Apr 24 '13 at 20:29
  • this is the proof that the data is there : http://imageshack.us/a/img829/1076/outputn.jpg – Francesco Stranieri Apr 24 '13 at 20:34
  • k i've updated it with the new xml for you and the onCreate and new method separated for the filling out the list when the activity is started the first time. – Sergey Benner Apr 24 '13 at 21:36
  • 04-24 22:43:58.156: E/AndroidRuntime(1110): FATAL EXCEPTION: main 04-24 22:43:58.156: E/AndroidRuntime(1110): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.ciaomondo/pack.chatapp.Utenti}: java.lang.RuntimeException: Your content must have a ListView whose id attribute is 'android.R.id.list' – Francesco Stranieri Apr 24 '13 at 22:45
  • android:id="@android:id/list" in the xml file – Sergey Benner Apr 25 '13 at 01:04
  • okay. I've rebuilt it. Take a look how i did the post call and then I've recreated the row.xml layout for the SimpleAdapter and see how it's being created with constructor params. I've tested the code and it's working. Hope it helps. – Sergey Benner Apr 25 '13 at 15:59
  • what's R.layout.test? Don't i have to use row.xml? – Francesco Stranieri Apr 25 '13 at 18:05
  • i pasted it - it's layout test.xml with definition of the ListView in it – Sergey Benner Apr 25 '13 at 19:30
  • 04-25 19:41:57.315: I/json(1612): {"message":"loggato","success":[{"user":"anto"},{"user":"Francesco"},{"user":"giuseppe"},{"user":"lol"},{"user":"sdasad"}]} json found but : 04-25 19:41:57.365: W/System.err(1612): org.json.JSONException: No value for user 04-25 19:41:57.365: W/System.err(1612): at org.json.JSONObject.get(JSONObject.java:354) – Francesco Stranieri Apr 25 '13 at 19:44
  • i've tried also with JSONArray friends = json.getJSONObject("user").getJSONArray("success"); but nothing – Francesco Stranieri Apr 25 '13 at 19:46
  • because you dont have to do it this way. it was an example. don't do the blind copypasting. :) I tested it on my json. You should use `JSONArray friends = json.getJSONArray("success");` instead – Sergey Benner Apr 25 '13 at 19:51
  • IT WORKS!!! GREAT!!! i've added : JSONObject e = friends.getJSONObject(i); map.put("name", e.getString("user")); – Francesco Stranieri Apr 25 '13 at 20:04