【问题标题】:Attempt to invoke virtual method on a null object reference尝试在空对象引用上调用虚拟方法
【发布时间】:2015-03-11 08:44:34
【问题描述】:

这是我得到的错误:

03-11 08:27:48.513:E/AndroidRuntime(23647):java.lang.RuntimeException:无法启动活动 ComponentInfo{com.plan.yeahimin/com.plan.yeahimin.PlanDetailsActivity}:java.lang。 NullPointerException:尝试在空对象引用上调用虚拟方法“java.io.Serializable android.os.Bundle.getSerializable(java.lang.String)”

我理解这是由于变量具有空值,但我无法确定原因。看起来它是DetailsFragmentgetSerializable() 方法中的'EXTRA_NEW_PLAN',但除此之外我不知道。我是 Android 新手,如果很明显,请原谅我,但我们将不胜感激。

这是我的ListFragment 代码;

public class PlanListFragment extends ListFragment {

public final static String TAG = "com.plan.yeahimin.PlanListFragment";
public final static String EXTRA_NEW_PLAN = "com.plan.yeahimin.plan_id";

private Button mAddPlan;
private ArrayList<Plan> mPlansList;


public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState){
    View v = inflater.inflate(R.layout.empty_view_or_list_view, parent, false);
    ListView view = (ListView) v.findViewById(android.R.id.list);
    view.setEmptyView(v.findViewById(android.R.id.empty));

    mAddPlan = (Button) v.findViewById(R.id.add_a_plan);

    mAddPlan.setOnClickListener(new View.OnClickListener(){

        @Override
        public void onClick(View v) {
            Log.d(TAG, "add plan clicked");
            Plan plan = new Plan();
            Log.d(TAG, "new plan created");
            PlanArrayList.get(getActivity()).addPlans(plan);
            Log.d(TAG, "plan added to mPlansList");
            Intent i = new Intent(getActivity(), PlanDetailsActivity.class);
            i.putExtra(PlanDetailsFragment.EXTRA_NEW_PLAN, plan.getId());
            startActivity(i);
            return;
        }

    });
    return v;
}

public void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    setHasOptionsMenu(true);

    mPlansList = PlanArrayList.get(getActivity()).getPlans();
    //ArrayList<Plan> mPlansList = new ArrayList<Plan>();
    PlanArrayAdapter paa = new PlanArrayAdapter(mPlansList);
    setListAdapter(paa);

}

public class PlanArrayAdapter extends ArrayAdapter<Plan>{


    public PlanArrayAdapter(ArrayList<Plan> planList){ 
        super(getActivity(), 0, planList);

    }

    public View getView(int position, View convertView, ViewGroup parent){

    // Get the plan item for this position
    Plan plan = getItem(position);

    //If layout doesnt exist, inflate one
    if(convertView == null){
        convertView = LayoutInflater.from(getContext()).inflate(R.layout.plan_list_fragment, parent, false);

    }

    TextView planTitle = (TextView) convertView.findViewById(R.id.plan_title);
    planTitle.setText(plan.getTitle());
    TextView planDate = (TextView) convertView.findViewById(R.id.plan_date);
    planDate.setText(plan.getDate().toString());

        return convertView;
    }

}

}

这是我从添加按钮打开的 DetailsFragment 代码;

public class PlanDetailsFragment extends Fragment {

private static final String TAG = "com.plan.yeahimin.PlanDetailsFragment";
public static final String EXTRA_NEW_PLAN = "com.plan.yeahimin.plan_id";

private EditText mTitleField;
private Button mDateButton;
private Button mTimeButton;
private EditText mLocationField;
private EditText mAttendeesField;
private EditText mDescriptionField;
private Plan mPlan;
private ArrayList<Plan> mPlansList;

public static PlanDetailsFragment newInstance(UUID planId){


    Bundle args = new Bundle();
    args.putSerializable(EXTRA_NEW_PLAN, planId);
    PlanDetailsFragment f = new PlanDetailsFragment();
    f.setArguments(args);
    Log.d(TAG, "newInstance created");
    return f;

}

@Override
public void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    setHasOptionsMenu(true);

    UUID planId = (UUID)getArguments().getSerializable(EXTRA_NEW_PLAN);
    mPlan = PlanArrayList.get(getActivity()).getPlan(planId);
}

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

    View v = inflater.inflate(R.layout.plan_details_fragment, parent, false);

    mTitleField = (EditText)v.findViewById(R.id.plan_title);

    mLocationField = (EditText)v.findViewById(R.id.plan_location);
    mAttendeesField = (EditText)v.findViewById(R.id.plan_attendees);
    mDescriptionField = (EditText)v.findViewById(R.id.plan_description);
    mDateButton = (Button)v.findViewById(R.id.plan_date);
    mTimeButton = (Button)v.findViewById(R.id.plan_time);


    return v;
}

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater){
    inflater.inflate(R.menu.main_to_do, menu);

}

public boolean onOptionsItemSelected(MenuItem item){
    switch(item.getItemId()){

    case R.id.save_button:

        Log.d(TAG, "save button pressed");
        return true;
    default:
        return super.onOptionsItemSelected(item);
    }
}

}

【问题讨论】:

  • args.putSerializable(EXTRA_NEW_PLAN, planId) 的问题;为什么你使用 UUID ,还要显示你在哪里调用 newInstance(UUID)
  • 您的问题在PlanDetailsActivity。你介意张贴吗?

标签: java android ios serialization nullpointerexception


【解决方案1】:

我认为您不能使用 .newInstance() 向您的 Fragment 发送任何参数,因为根据文档,此方法不接受任何参数。因此,即使您重载了 .newInstance(UUID),系统也会调用 .newInstance()(如果有调用,我有一些疑问)。另请注意,您使用 .putExtra() 将参数放入 Intent,但不要从 Intent 中调用它。

实际上向 Fragment 发送参数的正确方法如下:

在调用者中(通常它是一个 Activity,但可能与另一个 Fragment 一起使用,就像在您的示例中一样,它也可以工作,我不能肯定地说):

PlanDetailsFragment fragment = new PlanDetailsFragment();
Bundle args = new Bundle();
args.putSerializable(PlanDetailsFragment.TAG_NEW_PLAN, plan.getID());
fragment.setArguments(args);
getFragmentManager().beginTransaction().add(fragment, TAG_DETAILS_FRAGMENT).commit();

在片段中:

Bundle args = getArguments();
UUID planID = (UUID) args.getSerializable(TAG_NEW_PLAN);

它不是一个现成的代码,你应该适应你的类和变量名称,你的标签所在的位置等等。如果你喜欢从那里工作,Activity 方法的调用也可能需要一些改变另一个片段。这只是一个总体描述。

我的回答适用于两个片段都在一个活动中的情况。你对 Intents 的使用让我对此产生了怀疑,但我并不完全理解。

【讨论】:

    【解决方案2】:

    您将参数发送到 Activity(PlanDetailsActivity)。

    您应该通过 newInstance() 方法将参数发送到 Fragment。

    在您的 PlainDetailsActivity 中,您应该像这样创建片段实例:

    UUID uuid = getIntent().getSerializableExtra(PlanDetailsFragment.EXTRA_NEW_PLAN);
    PlanDetailsFragment f = PlanDetailsFragment.newInstance(uuid);
    

    【讨论】:

      猜你喜欢
      • 2023-03-13
      • 1970-01-01
      • 2019-01-10
      • 2019-05-10
      • 2015-06-26
      • 2017-01-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多