0

Good day all,

I have an issue where my activity is making a network call and when the network call is completed, it makes some changes in the activity using the data from the JSON object received from the call, it then passes the object down to the fragments in the same activity. These fragments are in a TabLayout.

The issue I have is that if I put a System.out.println() it prints out the correct data. The minute I want to set say a TextView with the data I receive in the Fragment the app Crashes with Nullpointer. When I debug it with the Debug in Android studio, the TextView I'm setting is always null for some reason.

Activity Code that does the initial Network call:

  @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_listings);
ButterKnife.bind(this);
setSupportActionBar(toolbar);
handleIntent(getIntent());

}


private void handleIntent(Intent aIntent) {
if (aIntent != null) {

  String tradeType = aIntent.getStringExtra("itemType");
  String tradeId = aIntent.getStringExtra("itemId");

  presenter = new ItemPresenterImpl(this, ItemBuyNowActivity.this);   
  presenter.doListingServiceCall(tradeId); // <------- This is the where I send the Trade Id so I can do the network call.
} else {
  System.out.println("Intent is null in " + ItemBuyNowActivity.class.getSimpleName());
}

}

Interface between Activity and Presenter:

public interface ItemPresenter {

void doListingServiceCall(String itemId);  //<------- Comes to this Interface

void doToolbarBackgroundImageCall(TradeItem aTradeItem);

}

Class the implements the Presenter:

@Override
  public void doListingServiceCall(String aItemId) {  // <------- This is where the network call starts
    String homeURL = BobeApplication.getInstance().getWsURL() + mContext.getString(R.string.ws_url_item) + aItemId;
    BobeJSONRequest jsObjRequest = new BobeJSONRequest(Request.Method.GET, homeURL, null, this, this);
    VolleySingleton.getInstance().addToRequestQueue(jsObjRequest, "ListingRequest");
  }

  @Override
  public void doToolbarBackgroundImageCall(TradeItem aTradeItem) {
    ImageRequest request = new ImageRequest(aTradeItem.getItem().getImageUrl(),
            new Response.Listener<Bitmap>() {
              @Override
              public void onResponse(Bitmap bitmap) {
                Drawable drawable = new BitmapDrawable(mContext.getResources(), bitmap);
                mItemView.loadBackgroundImage(drawable);
              }
            }, 0, 0, null,
            new Response.ErrorListener() {
              public void onErrorResponse(VolleyError error) {
                mItemView.displayErrorMessage(VolleyErrorHelper.getErrorType(error, mContext) + " occurred downloading background image");
              }
            });
    VolleySingleton.getInstance().addToRequestQueue(request, "ListItemToolbarBackgroundImageRequest");
  }

  @Override
  public void onResponse(Object response) { 
    Gson gson = new Gson();
    TradeItem tradeItem = gson.fromJson(response.toString(), TradeItem.class);
    mItemView.populateListViews(tradeItem); // <------- This is the where I send the Object so the views in the activity can be manipulated
    doToolbarBackgroundImageCall(tradeItem);
  }

Method in the Activity that handles

  @Override
public void populateListViews(TradeItem aTradeItem) {
  mOverviewPresenter = new OverviewPresenterImpl(new OverviewListItemFragment(), aTradeItem);
  OverviewListItemFragment.setData(aTradeItem);  //<------- This is the where I send the Object to the fragment so i can manipulate the views in the fragment
}

The Fragment that receives the data:

    public class OverviewListItemFragment extends Fragment implements OverviewView {

  private static TextView mOverViewHeading;

  public OverviewListItemFragment() {
  }

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mOverViewHeading = (TextView) getActivity().findViewById(R.id.frag_overview_heading_textview);


  }

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

    return inflater.inflate(R.layout.overview_list_item_fragment, container, false);

  }

  @Override
  public void populateOverviewViews(final TradeItem aTradeItem) {
    System.out.println("Overview Trade Object title is:" + aTradeItem.getItem().getTradeTitle());  // <------- This is print statement works 100% but when I try setting mOverViewHeading to the text in aTradeItem.getItem().getTradeTitle() I get a Null pointer Exception.

  }

  public static void setData(TradeItem aTradeItem) {
    System.out.println("Overview Trade Object title is:" + aTradeItem.getItem().getTradeTitle());  // <------- This is print statement works 100% but when I try setting mOverViewHeading to the text in aTradeItem.getItem().getTradeTitle() I get a Null pointer Exception.
    mOverViewHeading.setText(aTradeItem.getItem().getTradeTitle());// <------- This is where it crashes and mOverViewHeading is still null at this point.
  }
}

EDIT: Sorry I forgot the LogCat:

02-05 17:08:21.554 30512-30512/com.example.app E/AndroidRuntime: FATAL EXCEPTION: main
                                                              java.lang.NullPointerException
                                                                  at com.example.app.ui.fragments.OverviewListItemFragment.setData(OverviewListItemFragment.java:46)
                                                                  at com.example.app.ui.activities.ItemBuyNowActivity.populateListViews(ItemBuyNowActivity.java:95)
                                                                  at com.example.app.listing.ItemPresenterImpl.onResponse(ItemPresenterImpl.java:62)
                                                                  at com.android.volley.toolbox.JsonRequest.deliverResponse(JsonRequest.java:65)
                                                                  at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:99)
                                                                  at android.os.Handler.handleCallback(Handler.java:725)
                                                                  at android.os.Handler.dispatchMessage(Handler.java:92)
                                                                  at android.os.Looper.loop(Looper.java:137)
                                                                  at android.app.ActivityThread.main(ActivityThread.java:5041)
                                                                  at java.lang.reflect.Method.invokeNative(Native Method)
                                                                  at java.lang.reflect.Method.invoke(Method.java:511)
                                                                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
                                                                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
                                                                  at dalvik.system.NativeStart.main(Native Method)

My thinking is that the view I'm trying to set isn't "Active" (if thats the right word) at the time it receives the data, because when I run the debugger with a break point at the method that receives the data in the Fragment, the mOverViewHeading TextView id is null, even though I have the findViewById in the onCreate, also tried placing it in the onCreateView() but both times failed. I also tried placing the findViewById in the same method that gets called when the response is successful but before I try setting the setText() on the TextView.

Thank you

Stillie
  • 2,647
  • 6
  • 28
  • 50

1 Answers1

2

You can't call findViewById in fragment onCreate(). There is no UI at that time. Try calling findViewById in onCreateView(). Also, you have to use findViewById() on View inside fragment. You can't use Activity for this.

Like this :

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
  View view = inflater.inflate(R.layout.overview_list_item_fragment, container, false);
  mOverViewHeading = (TextView) view.findViewById(R.id.frag_overview_heading_textview);
  return view;
}
Hein
  • 2,675
  • 22
  • 32
  • Simply accepting answer would be suffice. It will also help other with same problem. :D – Hein Feb 08 '16 at 07:32
  • 1
    I thought you said in your question that you tried this already? glad you found your answer. – rothloup Feb 08 '16 at 07:33
  • He did try with getActivity(). That's why it keep crashing. Have to use view. – Hein Feb 08 '16 at 07:34
  • The weird thing is this is happening again even after the change i made, it worked for about an hour then just stopped and not sure wtf happened?? Its doing the exact same thing?? any ideas? – Stillie Feb 08 '16 at 10:25
  • Since the necessary answer for this question is already accepted, you should made another question with everything necessary. I don't think it will be the same issue. `Exception` might be the same but `Cause` may be not. – Hein Feb 08 '16 at 10:36