Stephanie Yang
Stephanie Yang

Reputation: 262

adapter worked in fragment onCreateView but not in Asynctask onPostExecute

I want to use asyncTask to get result from api and put it in a view. Now the code is like this:

public class GradeFragment extends Fragment {

private ListView lv;
private LinearLayout llLayout;
private String[] items;
ArrayAdapter<String> adapter;
TextView text;
private FragmentActivity faActivity;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    faActivity  = (FragmentActivity)super.getActivity();
    lv=(ListView)llLayout.findViewById(R.id.list_item);
    text = (TextView) llLayout.findViewById(R.id.text);

    new ReadWeatherJSONFeedTask().execute("http://api.androidhive.info/contacts/");
    //worked here
    items = new String[] { "Item 1",
            "Item 2",
            "Item 3",
            "Item 4",
            "Item 5"
    };
    adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, items);
    lv.setAdapter(adapter);
    return llLayout; 
}

private class ReadWeatherJSONFeedTask extends AsyncTask<String, Void, String> {
    protected String doInBackground(String... urls) {
        HttpClient httpclient = new DefaultHttpClient();
        HttpResponse response;
        String responseString = null;
        //text.setText(urls[0]);
        try {
            response = httpclient.execute(new HttpGet(urls[0]));
            StatusLine statusLine = response.getStatusLine();
            if(statusLine.getStatusCode() == HttpStatus.SC_OK){
                ByteArrayOutputStream out = new ByteArrayOutputStream();
                response.getEntity().writeTo(out);
                responseString = out.toString();
                out.close();

            } else{
                //Closes the connection.
                response.getEntity().getContent().close();
                text.setText("restapi failed");

                throw new IOException(statusLine.getReasonPhrase());
            }

        }
        catch (ClientProtocolException e) {
            e.printStackTrace();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
        return responseString;
    }

    @Override
    protected void onPostExecute(String result) {
        try {
              //do not work here
              items = new String[] { 
                  "Item 1",
                  "Item 2",
                  "Item 3",
                  "Item 4",
                  "Item 5"
            };
            lv=(ListView)llLayout.findViewById(R.id.list_item);

            adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, items);
            lv.setAdapter(adapter);

        } catch (Exception e) {
            e.printStackTrace();
            //Log.d("ReadWeatherJSONFeedTask", e.getLocalizedMessage());
        }
    }
}

/*    @Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_grade, menu);
    return true;
}*/

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}
}

When I comment out adapter in onPostExecute and left the one in onCreateView, it works fine. But when I comment out the adapter in onCreateViw and lfet the one in onPostExecute, the list do not show up. Dose anyone know why the adapter worked will in onCreateView but not in onPostExecute method? If I want to display the results in onPostExcute in the fragment, what should I do?

Upvotes: 0

Views: 732

Answers (2)

Simon Mokhele
Simon Mokhele

Reputation: 3993

How about you try a callback interface that you can use to call after post execute This is the sample code

private class ReadWeatherJSONFeedTask extends AsyncTask<String, Void, String> {
CallBack callback;

public ReadWeatherJSONFeedTask(CallBack callback){
    this.callback = callback;
}

protected String doInBackground(String... urls) {
    HttpClient httpclient = new DefaultHttpClient();
    HttpResponse response;
    String responseString = null;
    //text.setText(urls[0]);
    try {
        response = httpclient.execute(new HttpGet(urls[0]));
        StatusLine statusLine = response.getStatusLine();
        if(statusLine.getStatusCode() == HttpStatus.SC_OK){
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            response.getEntity().writeTo(out);
            responseString = out.toString();
            out.close();

        } else{
            //Closes the connection.
            response.getEntity().getContent().close();
            text.setText("restapi failed");

            throw new IOException(statusLine.getReasonPhrase());
        }

    }
    catch (ClientProtocolException e) {
        e.printStackTrace();
    }
    catch (IOException e) {
        e.printStackTrace();
    }
    return responseString;


@Override
protected void onPostExecute(String result) {
    callback.onCallBack();
}

Your new aysnc

public interface CallBack{

public void onCallBack();}

Then finally call it like

new ReadWeatherJSONFeedTask( new CallBack(){
public void onCallBack(){
    try {
          //do not work here
          items = new String[] { 
              "Item 1",
              "Item 2",
              "Item 3",
              "Item 4",
              "Item 5"
        };
        lv=(ListView)llLayout.findViewById(R.id.list_item);

        adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, items);
        lv.setAdapter(adapter);

    } catch (Exception e) {
        e.printStackTrace();
        //Log.d("ReadWeatherJSONFeedTask", e.getLocalizedMessage());
    }
}

}).execute("http://api.androidhive.info/contacts/");

Upvotes: 1

victorholo
victorholo

Reputation: 115

First you have to replace the old values with the new values in ur String[] items then you have to notifyDataSetChanged() to your adapter.

Instead of

    lv=(ListView)llLayout.findViewById(R.id.list_item);

    adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, items);
    lv.setAdapter(adapter);

you just have to have

adapter.notifyDataSetChanged();

Hope this helps you.

BTW: Your items is the same string array in both places, how do you know it works or not?

Upvotes: 0

Related Questions