Mike
Mike

Reputation: 6839

NullPointerException while using asyncTask, interface, and fragments

I have an async task that loads a list view of items. I am currently trying to set the onClick to load a new fragment with an "id" that is being retrieved from the list item that is clicked. I have no errors in my code that the Android Studio shows me.

When I run the app and click on the item in the list view I get this FC:

02-13 19:49:56.813  20334-20334/com.beerportfolio.beerportfoliopro E/AndroidRuntime﹕ FATAL EXCEPTION: main
    java.lang.NullPointerException
            at com.beerportfolio.beerportfoliopro.ReadJSONResult$1.onItemClick(ReadJSONResult.java:140)
            at android.widget.AdapterView.performItemClick(AdapterView.java:298)
            at android.widget.AbsListView.performItemClick(AbsListView.java:1237)
            at android.widget.ListView.performItemClick(ListView.java:4555)
            at android.widget.AbsListView$PerformClick.run(AbsListView.java:3037)
            at android.widget.AbsListView$1.run(AbsListView.java:3724)
            at android.os.Handler.handleCallback(Handler.java:730)
            at android.os.Handler.dispatchMessage(Handler.java:92)
            at android.os.Looper.loop(Looper.java:158)
            at android.app.ActivityThread.main(ActivityThread.java:5789)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:525)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1027)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:843)
            at dalvik.system.NativeStart.main(Native Method)
02-13 19:50:42.112  20864-20870/? E/jdwp﹕ Failed sending reply to debugger: Broken pipe

line 140 in ReadJSONResult is:

listenerBeer.onArticleSelected(idToSend);

That line is part of this whole onClick:

//set up clicks
                lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                    @Override
                    public void onItemClick(AdapterView<?> arg0, View arg1,
                                            int arg2, long arg3) {
                        BeerData beerInfo = beerList.get(arg2);

                        String idToSend = beerInfo.beerId;

                        //todo: launch beer fragment
                        listenerBeer.onArticleSelected(idToSend);




                    }
                });

All the code for ReadJSONResult is:

public class ReadJSONResult extends AsyncTask<String, Void, String> {

        Context c;
        private ProgressDialog Dialog;

        public ReadJSONResult(Context context)
        {
            c = context;
            Dialog = new ProgressDialog(c);
        }

        //code for on click
        OnArticleSelectedListener listenerBeer;
        public interface OnArticleSelectedListener{
            public void onArticleSelected(String myString);


        }
    public void setOnArticleSelectedListener(OnArticleSelectedListener listener){
        this.listenerBeer = listener;


    }
    //end code for onClick

        @Override
        protected String doInBackground(String... arg0) {
            // TODO Auto-generated method stub
            return readJSONFeed(arg0[0]);
        }

        protected void onPreExecute() {
            Dialog.setMessage("Searching Beer Cellar");

            Dialog.setTitle("Loading");
            Dialog.setCancelable(false);
            Dialog.show();
        }

        protected void onPostExecute(String result){
            //decode json here
            try{

                JSONObject json = new JSONObject(result);

                //acces listview
                ListView lv = (ListView) ((Activity) c).findViewById(android.R.id.list);


                //make array list for beer
                final List<BeerData> beerList = new ArrayList<BeerData>();



                //get json items
                for(int i = 0; i < json.getJSONArray("data").length(); i++) {

                    String beerId = GetBeerDataFromJSON(i,"id", json);
                    String beerName = GetBeerDataFromJSON(i,"name", json);
                    String beerDescription = GetBeerDataFromJSON(i,"description" , json);
                    String beerAbv = GetBeerDataFromJSON(i,"abv" , json);
                    String beerIbu = GetBeerDataFromJSON(i,"ibu" , json);
                    String beerIcon = GetBeerIconsFromJSON(i, "icon",json );
                    String beerMediumIcon = GetBeerIconsFromJSON(i, "medium",json );
                    String beerLargeIcon = GetBeerIconsFromJSON(i, "large",json );
                    String beerGlass = GetBeerGlassFromJSON(i, json );
                    String beerStyle = GetBeerStyleFromJSON(i,"name", json );
                    String beerStyleDescription = GetBeerStyleFromJSON(i,"description", json );
                    String beerBreweryId = GetBeerBreweryInfoFromJSON(i, "id", json );
                    String beerBreweryName = GetBeerBreweryInfoFromJSON(i, "name", json );
                    String beerBreweryDescription = GetBeerBreweryInfoFromJSON(i, "description", json );
                    String beerBreweryWebsite = GetBeerBreweryInfoFromJSON(i, "website", json );

                    //get long and latt
                    String beerBreweryLat = GetBeerBreweryLocationJSON(i, "longitude", json );
                    String beerBreweryLong = GetBeerBreweryLocationJSON(i, "latitude", json );

                    String beerBreweryYear = GetBeerBreweryInfoFromJSON(i, "established", json );
                    String beerBreweryIcon = GetBeerBreweryIconsFromJSON(i,"large",json);



                    //create beer object
                    BeerData thisBeer = new BeerData(beerName, beerId, beerDescription, beerAbv, beerIbu, beerIcon,
                            beerMediumIcon,beerLargeIcon, beerGlass, beerStyle, beerStyleDescription, beerBreweryId, beerBreweryName,
                            beerBreweryDescription, beerBreweryYear, beerBreweryWebsite,beerBreweryIcon, beerBreweryLat, beerBreweryLong);

                    //add beer to list
                    beerList.add(thisBeer);


                }

                //update listview
                BeerSearchAdapter adapter1 = new BeerSearchAdapter(c ,R.layout.listview_item_row, beerList);
                lv.setAdapter(adapter1);

                //set up clicks
                lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                    @Override
                    public void onItemClick(AdapterView<?> arg0, View arg1,
                                            int arg2, long arg3) {
                        BeerData beerInfo = beerList.get(arg2);

                        String idToSend = beerInfo.beerId;

                        //todo: launch beer fragment
                        listenerBeer.onArticleSelected(idToSend);




                    }
                });




            }
            catch(Exception e){

            }

            Dialog.dismiss();

        }

        //todo: all the get functions go here
        private String GetBeerDataFromJSON(int position, String whatToGet, JSONObject json ) {
            String whatIsTheKeyYouAreLookFor = whatToGet;
            int whereInTheJSONArrayForLoopIsTheData = position;
            String holder = "";
            try{
                holder = json.getJSONArray("data").getJSONObject(whereInTheJSONArrayForLoopIsTheData).getString(whatIsTheKeyYouAreLookFor);

            } catch (JSONException e) {
                holder = "N/A";
            }



            return holder;
        }


        //get icons
        private String GetBeerBreweryIconsFromJSON(int position, String whatToGet, JSONObject json ) {
            String whatIsTheKeyYouAreLookFor = whatToGet;
            int whereInTheJSONArrayForLoopIsTheData = position;
            String holder = "";
            try{
                holder = json.getJSONArray("data").getJSONObject(whereInTheJSONArrayForLoopIsTheData).getJSONArray("breweries").getJSONObject(0).getJSONObject("images").getString(whatIsTheKeyYouAreLookFor);;
            } catch (JSONException e) {
                holder = "N/A";
            }



            return holder;
        }

        //get icons
        private String GetBeerIconsFromJSON(int position, String whatToGet, JSONObject json ) {
            String whatIsTheKeyYouAreLookFor = whatToGet;
            int whereInTheJSONArrayForLoopIsTheData = position;
            String holder = "";
            try{
                holder = json.getJSONArray("data").getJSONObject(whereInTheJSONArrayForLoopIsTheData).getJSONObject("labels").getString(whatIsTheKeyYouAreLookFor);

            } catch (JSONException e) {
                holder = "N/A";
            }



            return holder;
        }

        //get style information
        private String GetBeerStyleFromJSON(int position, String whatToGet, JSONObject json ) {
            String whatIsTheKeyYouAreLookFor = whatToGet;
            int whereInTheJSONArrayForLoopIsTheData = position;
            String holder = "";
            try{
                holder = json.getJSONArray("data").getJSONObject(whereInTheJSONArrayForLoopIsTheData).getJSONObject("style").getString(whatIsTheKeyYouAreLookFor);

            } catch (JSONException e) {
                holder = "N/A";
            }



            return holder;
        }

        //get location data
        private String GetBeerBreweryLocationJSON(int position, String whatToGet, JSONObject json ) {
            String whatIsTheKeyYouAreLookFor = whatToGet;
            int whereInTheJSONArrayForLoopIsTheData = position;
            String holder = "";
            try{
                holder = json.getJSONArray("data").getJSONObject(whereInTheJSONArrayForLoopIsTheData).getJSONArray("breweries").getJSONObject(0).getJSONArray("locations").getJSONObject(0).getString(whatIsTheKeyYouAreLookFor);

            } catch (JSONException e) {
                holder = "N/A";
            }



            return holder;
        }

        //get brewery information
        //get style information
        private String GetBeerBreweryInfoFromJSON(int position, String whatToGet, JSONObject json ) {
            String whatIsTheKeyYouAreLookFor = whatToGet;
            int whereInTheJSONArrayForLoopIsTheData = position;
            String holder = "";
            try{
                holder = json.getJSONArray("data").getJSONObject(whereInTheJSONArrayForLoopIsTheData).getJSONArray("breweries").getJSONObject(0).getString(whatIsTheKeyYouAreLookFor);

            } catch (JSONException e) {
                holder = "N/A";
            }



            return holder;
        }

        //get glass
        private String GetBeerGlassFromJSON(int position, JSONObject json ) {

            int whereInTheJSONArrayForLoopIsTheData = position;
            String holder = "";
            try{
                holder = json.getJSONArray("data").getJSONObject(whereInTheJSONArrayForLoopIsTheData).getJSONObject("glass").getString("name");

            } catch (JSONException e) {
                holder = "N/A";
            }



            return holder;
        }



        public String readJSONFeed(String URL) {
            StringBuilder stringBuilder = new StringBuilder();
            HttpClient httpClient = new DefaultHttpClient();
            HttpGet httpGet = new HttpGet(URL);
            try {
                HttpResponse response = httpClient.execute(httpGet);
                StatusLine statusLine = response.getStatusLine();
                int statusCode = statusLine.getStatusCode();
                if (statusCode == 200) {
                    HttpEntity entity = response.getEntity();
                    InputStream inputStream = entity.getContent();
                    BufferedReader reader = new BufferedReader(
                            new InputStreamReader(inputStream));
                    String line;
                    while ((line = reader.readLine()) != null) {
                        stringBuilder.append(line);
                    }
                    inputStream.close();
                } else {
                    Log.d("JSON", "Failed to download file");
                }
            } catch (Exception e) {
                Log.d("readJSONFeed", e.getLocalizedMessage());
            }
            return stringBuilder.toString();
        }

    }

BeerSearchAdapter is:

public class BeerSearchAdapter extends ArrayAdapter<BeerData> {

    Context context;
    int layoutResourceId;
    List<BeerData> data = null;

    public BeerSearchAdapter(Context context, int layoutResourceId, List<BeerData> data) {
        super(context, layoutResourceId, data);
        this.layoutResourceId = layoutResourceId;
        this.context = context;
        this.data = data;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View row = convertView;
        beerHolder holder = null;

        if(row == null)
        {
            LayoutInflater inflater = ((Activity)context).getLayoutInflater();
            row = inflater.inflate(layoutResourceId, parent, false);

            holder = new beerHolder();
            holder.txtBrewery = (TextView)row.findViewById(R.id.beerBreweryNameList);
            holder.txtTitle = (TextView)row.findViewById(R.id.beerNameList);

            row.setTag(holder);
        }
        else
        {
            holder = (beerHolder)row.getTag();
        }

        BeerData beer = data.get(position);
        holder.txtTitle.setText(beer.beerName);
        holder.txtBrewery.setText(beer.beerBreweryName);

        return row;
    }

    static class beerHolder
    {
        TextView txtBrewery;
        TextView txtTitle;
    }
}

My Search.java where the interface comes form is here:

public class Search extends Fragment implements SearchView.OnQueryTextListener, ReadJSONResult.OnArticleSelectedListener {

    private ListView lv;
    View v;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        //set layout here
        v = inflater.inflate(R.layout.activity_search, container, false);
        setHasOptionsMenu(true);
        getActivity().setTitle("Search");


        //get user information
        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
        String userName = prefs.getString("userName", null);
        String userID = prefs.getString("userID", null);


        //todo: code body goes here





        // Inflate the layout for this fragment
        return v;


}


    @Override
    public void onCreateOptionsMenu (Menu menu, MenuInflater inflater) {
        // Inflate the menu; this adds items to the action bar if it is present.

        super.onCreateOptionsMenu(menu, inflater);

        Log.d("click", "inside the on create");

        //inflater.inflate(R.menu.main, menu);
        SearchView searchView = (SearchView) menu.findItem(R.id.menu_search2).getActionView();
        searchView.setIconified(false);
        searchView.setOnQueryTextListener(this);
    }




    public boolean onQueryTextSubmit (String query) {

        //toast query

        //make json variables to fill

        // url to make request
        String url = "myURL";



        try {
            query = URLEncoder.encode(query, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }


        String jsonUrl = url + query;



        //todo: get json
        new ReadJSONResult(getActivity()).execute(jsonUrl);

        return false;
    }





    @Override
    public boolean onQueryTextChange(String newText) {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public void onArticleSelected(String b){

        //code to execute on click
        Fragment Fragment_one;
        FragmentManager man= getFragmentManager();
        FragmentTransaction tran = man.beginTransaction();

        //todo: set to beer fragment
        Fragment_one = new StylePage2();
        final Bundle bundle = new Bundle();
        bundle.putString("beerIDSent", b);
        Fragment_one.setArguments(bundle);
        tran.replace(R.id.main, Fragment_one);//tran.
        tran.addToBackStack(null);
        tran.commit();

    }



}

Let me know if you need any other code, I am stomped on this and could use a second pair of eyes. Thanks.

Upvotes: 1

Views: 725

Answers (2)

J Steven Perry
J Steven Perry

Reputation: 1751

From the error message, it is obvious that listenerBeer reference is null.

I see this code:

public void setOnArticleSelectedListener(OnArticleSelectedListener listener){
    this.listenerBeer = listener;
}

But I don't see any code that calls it. Unless there is code you have not included that sets the listenerBeer reference, that would explain why it is null.

Somewhere in your code you will have to do something like this:

. . .
setOnArticleSelectedListener(new OnArticleSelectedListener() {
  public void onArticleSelected(String myArticle) {
    // Do something here....
  }
});
. . .

HTH

Upvotes: 5

Atul O Holic
Atul O Holic

Reputation: 6792

You have got it correct that at the below call to onArticleSelected your listenerBeer is null.

listenerBeer.onArticleSelected(idToSend);

The only possible reason behind it is that it is not initiallized before making this call. As visible from your code the only place you are doing the initialization is in the below method.

 public void setOnArticleSelectedListener(OnArticleSelectedListener listener){
    this.listenerBeer = listener;
 }

But, I cannot see any implementation of this. Can you do a null check before listenerBeer.onArticleSelected(idToSend); and verify if listenerBeer is initialized like

if (null != listenerBeer){
    listenerBeer.onArticleSelected(idToSend);
}else{
    Log.d("Null Check", "ListenereBeer is " + String.valueOf(listenerBeer));
}

Upvotes: 1

Related Questions