【问题标题】:Fragment Crashing whenbtrying to receive an object from an activity尝试从活动接收对象时发生片段崩溃
【发布时间】:2016-02-08 07:17:28
【问题描述】:

大家好,

我有一个问题,我的活动正在进行网络调用,当网络调用完成时,它使用从调用接收到的 JSON 对象中的数据对活动进行一些更改,然后将对象向下传递到同一活动中的片段。这些片段位于 TabLayout 中。

我遇到的问题是,如果我放一个 System.out.println() 它会打印出正确的数据。在我想设置一个 TextView 的那一刻,我在 Fragment 中收到的数据会导致应用程序因 Nullpointer 崩溃。当我在 Android Studio 中使用 Debug 进行调试时,由于某种原因,我设置的 TextView 始终为空。

执行初始网络调用的活动代码:

  @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());
}

}

Activity和Presenter的接口:

public interface ItemPresenter {

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

void doToolbarBackgroundImageCall(TradeItem aTradeItem);

}

实现 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);
  }

Activity中处理的方法

  @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
}

接收数据的Fragment:

    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.
  }
}

编辑:对不起,我忘记了 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)

我的想法是,我尝试设置的视图在接收数据时不是“活动”(如果这是正确的话),因为当我在方法处使用断点运行调试器时接收到 Fragment 中的数据时,mOverViewHeading TextView id 为 null,即使我在 onCreate 中有 findViewById,也尝试将其放在 onCreateView() 中,但两次都失败了。我还尝试将 findViewById 放在响应成功时调用的相同方法中,但在我尝试在 TextView 上设置 setText() 之前。

谢谢

【问题讨论】:

    标签: java android android-fragments


    【解决方案1】:

    您不能在片段 onCreate() 中调用 findViewById。那时还没有 UI。尝试在 onCreateView() 中调用 findViewById。此外,您必须在片段内的视图上使用 findViewById()。您不能为此使用 Activity。

    像这样:

    @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;
    }
    

    【讨论】:

    • 只需接受答案就足够了。它也将帮助其他有同样问题的人。 :D
    • 我以为您在问题中说过您已经尝试过了?很高兴你找到了答案。
    • 他确实尝试过使用 getActivity()。这就是它不断崩溃的原因。必须使用视图。
    • 奇怪的是,即使在我做出改变之后,这种情况又发生了,它工作了大约一个小时,然后就停止了,不确定发生了什么?它在做同样的事情??有什么想法吗?
    • 由于这个问题的必要答案已经被接受,你应该用一切必要的东西提出另一个问题。我认为这不会是同一个问题。 Exception 可能相同,但 Cause 可能不同。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-05-18
    • 2015-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多