0

I have an app which downloads YouTube JSON data. The code works perfectly in a desktop app, but not in android (the list is null when trying to iterate through it). Here's my code which matters:

    public String DownloadJSONData(){
    BufferedReader reader = null;
    String webc = "";
    try{
        URL url = new URL("http://gdata.youtube.com/feeds/api/users/thecovery/uploads?v=2&alt=json");
        reader = new BufferedReader(new InputStreamReader(url.openStream()));
        StringBuffer buffer = new StringBuffer();
        int read;
        char[] chars = new char[1024];
        while((read = reader.read(chars)) != -1){
            buffer.append(chars,0,read);
        }
        webc = buffer.toString();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (reader != null) {
            try {
                reader.close();
                return webc;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    System.out.println(webc);
    return webc;
}
public void GetData() throws JSONException {
    JSONObject obj = new JSONObject(DownloadJSONData());
    JSONArray feed = obj.getJSONObject("feed").getJSONArray("entry");
    for(int i = 0; i < feed.length(); i++){
        EPISODE_NAME.add(feed.getJSONObject(i).getJSONObject("title").getString("$t"));
        EPISODE_LINK.add(feed.getJSONObject(i).getJSONArray("link").getJSONObject(0).getString("href"));
    }
    ListView episodes = (ListView) findViewById(R.id.episodeChooser);
    ArrayAdapter<String> episodesSource = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,EPISODE_NAME);
}

}

In the onCreate method, I call the GetData() method, and I try to set the adapter to the ListView from the EPISODE_NAME ArrayList, but it's null. I also tried to set the adapter after the method, in onCreate, but no luck. Anyone can help?

  • Where have you called the `DownloadJSONData()` ? – M. Reza Nasirloo Jan 25 '15 at 13:25
  • Android does use different classes and some work different from normal Java, hence it's called android. I don't see why you'd make your code this complicated though. – Mathijs Segers Jan 25 '15 at 13:26
  • I think the problem is that you're doing the network call on the main ui thread. You should do the network call on a background thread. Depending on the android version, you might / might not get an exception. You should read this : http://stackoverflow.com/questions/6343166/android-os-networkonmainthreadexception – Shivam Verma Jan 25 '15 at 13:29
  • What are EPISODE_NAME, EPISODE_LINK? – sandeepmaaram Jan 25 '15 at 14:53

2 Answers2

1

It works fine

Add Below permission in Manifest.xml

 <uses-permission android:name="android.permission.INTERNET"/>

ManiActivity.java

public class MainActivity extends Activity {
private ListView listView;
private List<FeedsDTO> feedsList = new ArrayList<FeedsDTO>();
private FeedsDTO dto  = null;
private BackgroundThread backgroundThread;
private CustomAdapter customAdapter = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    listView = (ListView) findViewById(R.id.listview);
    backgroundThread = new BackgroundThread();
    backgroundThread.execute();
}
private void setListViewAdapter(){
    customAdapter = new CustomAdapter(this, R.layout.listitem, feedsList);
    listView.setAdapter(customAdapter);
}
private class BackgroundThread extends AsyncTask<Void, Void, String> {
    private ProgressDialog progressBar = null;
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        progressBar = new ProgressDialog(MainActivity.this);
        progressBar.setCancelable(false);
        progressBar.show();

    }
    @Override
    protected String doInBackground(Void... params) {
        BufferedReader reader = null;
        String webc = "";
        try{
            URL url = new URL("http://gdata.youtube.com/feeds/api/users/thecovery/uploads?v=2&alt=json");
            reader = new BufferedReader(new InputStreamReader(url.openStream()));
            StringBuffer buffer = new StringBuffer();
            int read;
            char[] chars = new char[1024];
            while((read = reader.read(chars)) != -1){
                buffer.append(chars,0,read);
            }
            webc = buffer.toString();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                    return webc;
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        System.out.println(webc);
        return webc;
    }
    @Override
    protected void onPostExecute(String result) {
        JSONObject obj;
        try {
            obj = new JSONObject(result);
            JSONArray feed = obj.getJSONObject("feed").getJSONArray("entry");
            Log.i("=======", "========="+feed.length());
            for(int i = 0; i < feed.length(); i++){
                dto = new FeedsDTO();
                dto.setName(feed.getJSONObject(i).getJSONObject("title").getString("$t"));
                dto.setLink(feed.getJSONObject(i).getJSONArray("link").getJSONObject(0).getString("href"));
                feedsList.add(dto);
                dto = null;
            }
            Log.i("=======LIst Size", "========="+feedsList.size());
            progressBar.dismiss();
            setListViewAdapter();
        } catch (JSONException e) {
            e.printStackTrace();
        }
        super.onPostExecute(result);
    }
}

}

CustomAdapter.java

public class CustomAdapter extends ArrayAdapter<FeedsDTO>{
private LayoutInflater inflater;
private int layoutID;
public CustomAdapter(Context cntx, int resource, List<FeedsDTO> objects) {
    super(cntx, resource, objects);
    this.inflater =(LayoutInflater) cntx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    this.layoutID = resource;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
    try {
        ViewHolder holder = null;
        if (convertView == null) {
            convertView = inflater.inflate(layoutID, null);
            holder = new ViewHolder();
            holder.NameTV = (TextView) convertView.findViewById(R.id.textview);

            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }
        FeedsDTO feedsDTO = getItem(position);
        holder.NameTV.setText(feedsDTO.getName());

        feedsDTO = null;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return convertView;
}
private class ViewHolder{
    TextView NameTV;
}

}

FeedsDTO.java

public class FeedsDTO {
private String name;
public String getName() {
    return name;
}
public void setName(String name) {
    this.name = name;
}
public String getLink() {
    return link;
}
public void setLink(String link) {
    this.link = link;
}
private String link;
}

listitem.xlm:-

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:orientation="vertical" >

<TextView
    android:id="@+id/textview"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
</TextView>

I hope this code will work perfectly

sandeepmaaram
  • 4,191
  • 2
  • 37
  • 42
  • So a backgroundThread.execute() to the onCreate method and a new ArrayAdapter from the feedsList? –  Jan 27 '15 at 17:18
  • Yes, call backgroundThread.execute(); After that set feedsList to adapter and set this adapter to listview. – sandeepmaaram Jan 27 '15 at 17:22
  • For some reason, it gives me a NullPointerException to line 30, which is "backgroundThread.execute();". –  Jan 27 '15 at 19:30
  • Can you post code or logcat? Did you write backgroundThread = new Background Thread();backgroundThread.execute(); – sandeepmaaram Jan 27 '15 at 23:36
  • It shows me no error after this fix, thank you, however, it keeps telling me that the size of feedsList is 0, and no items appearing in the listview. Here's my code: http://pastebin.com/rQXJF0RB (only MainActivity.java) –  Jan 28 '15 at 17:53
  • You are passing list of objects to adapter so, use custom adapter instead of array adapter – sandeepmaaram Jan 29 '15 at 04:53
  • @MartinFrøhlich Full code is updated, please check it. It will work perfectly. – sandeepmaaram Jan 29 '15 at 05:37
  • Works perfectly! Thank you for your help! One last question. How can I retrieve the link from the feedsList? I mean, you set the "name" to the source of the list. What I'd like to do next is, when clicking the element of the list, the browser should open and navigate to the "link", retrieved from JSON. I will do it myself, just tell me how to get the link from the list. –  Jan 29 '15 at 09:21
  • Please, we can help only in some cases. Remaining part you have to learn and apply over there. I will give suggestion, in custom adapter set link as tag to name textview and gettag in onItemclick listener of listview and typecast to string and use that link wherever you use. – sandeepmaaram Jan 29 '15 at 09:39
-2

Most apps include several different activities that allow the user to perform different actions. Whether an activity is the main activity that's created when the user clicks your app icon or a different activity that your app starts in response to a user action, the system creates every new instance of Activity by calling its onCreate() method.

You must implement the onCreate() method to perform basic application startup logic that should happen only once for the entire life of the activity. For example, your implementation of onCreate() should define the user interface and possibly instantiate some class-scope variables.

For example, the following example of the onCreate() method shows some code that performs some fundamental setup for the activity, such as declaring the user interface (defined in an XML layout file), defining member variables, and configuring some of the UI.

You are basically mixing stuff left and right. First create your Interface in the onCreate() and do the logic in onStart(). You should read the android lifecycle. See here

Murat Karagöz
  • 35,401
  • 16
  • 78
  • 107