Java 尝试对空对象引用调用虚方法

Java 尝试对空对象引用调用虚方法,java,android,ios,serialization,nullpointerexception,Java,Android,Ios,Serialization,Nullpointerexception,这是我得到的错误: 03-11 08:27:48.513:E/AndroidRuntime(23647):java.lang.RuntimeException:无法启动活动组件信息{com.plan.yeahimin/com.plan.yeahimin.PlanDetailsActivity}:java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法“java.io.Serializable android.os.Bundle.getSerializable(

这是我得到的错误:

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

我理解这是由于变量有一个空值,但我不知道为什么。在
DetailsFragment
中的
getSerializable()
方法中,它看起来像是“额外的新计划”,但除此之外,我不知道。我是Android新手,所以请原谅我,如果这是显而易见的,但任何帮助都将不胜感激

这是我的
列表片段的代码

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

}

}
公共类PlanListFragment扩展了ListFragment{
公共最终静态字符串TAG=“com.plan.yeahimin.PlanListFragment”;
公共最终静态字符串EXTRA\u NEW\u PLAN=“com.PLAN.yeahimin.PLAN\u id”;
专用按钮mAddPlan;
私有数组列表mPlansList;
创建视图上的公共视图(LayoutFlater充气器、视图组父级、捆绑保存状态){
视图v=充气机。充气(R.layout.empty\u视图或列表视图,父视图,false);
ListView=(ListView)v.findViewById(android.R.id.list);
view.setEmptyView(v.findViewById(android.R.id.empty));
mAddPlan=(按钮)v.findViewById(R.id.add\u a\u plan);
mAddPlan.setOnClickListener(新视图.OnClickListener(){
@凌驾
公共void onClick(视图v){
Log.d(标记“单击添加计划”);
计划=新计划();
Log.d(标记“创建的新计划”);
PlanArrayList.get(getActivity()).addPlans(plan);
Log.d(标签,“添加到mPlansList的计划”);
Intent i=新的Intent(getActivity(),PlanDetailsActivity.class);
i、 putExtra(PlanDetailsFragment.EXTRA_NEW_PLAN,PLAN.getId());
星触觉(i);
返回;
}
});
返回v;
}
创建时的公共void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
设置选项菜单(真);
mPlansList=PlanArrayList.get(getActivity()).getPlans();
//ArrayList mPlansList=新的ArrayList();
PlanArrayAdapter paa=新的PlanArrayAdapter(mPlansList);
setListAdapter(paa);
}
公共类PlanArrayAdapter扩展了ArrayAdapter{
公共平面ArrayAdapter(ArrayList平面列表){
super(getActivity(),0,planList);
}
公共视图getView(int位置、视图转换视图、视图组父视图){
//获取此职位的计划项
计划=获取项目(位置);
//如果布局不存在,则将其充气
if(convertView==null){
convertView=LayoutInflater.from(getContext()).flate(R.layout.plan\u list\u片段,父项,false);
}
TextView plantile=(TextView)convertView.findViewById(R.id.plan\u title);
planTitle.setText(plan.getTitle());
TextView计划日期=(TextView)convertView.findViewById(R.id.plan\u日期);
planDate.setText(plan.getDate().toString());
返回视图;
}
}
}
这是我从add按钮打开的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);
    }
}

}
公共类PlanDetailsFragment扩展片段{
私有静态最终字符串TAG=“com.plan.yeahimin.PlanDetailsFragment”;
公共静态最终字符串EXTRA\u NEW\u PLAN=“com.PLAN.yeahimin.PLAN\u id”;
私有编辑文本mTitleField;
私有按钮mDateButton;
私有按钮mTimeButton;
私有编辑文本mLocationField;
私有编辑文本mAttendeesField;
私有EditText MDDescriptionField;
私人计划mPlan;
私有数组列表mPlansList;
公共静态计划详细信息片段新实例(UUID planId){
Bundle args=新Bundle();
args.putSerializable(额外的新计划,计划ID);
PlanDetailsFragment f=新的PlanDetailsFragment();
f、 设置参数(args);
Log.d(标记“newInstance created”);
返回f;
}
@凌驾
创建时的公共void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
设置选项菜单(真);
UUID planId=(UUID)getArguments().getSerializable(额外的新计划);
mPlan=PlanArrayList.get(getActivity()).getPlan(planId);
}
@凌驾
创建视图上的公共视图(LayoutFlater充气器、视图组父级、捆绑保存状态){
视图v=充气机。充气(R.layout.plan\u details\u片段,父项,false);
mTitleField=(EditText)v.findViewById(R.id.plan_title);
mLocationField=(EditText)v.findViewById(R.id.plan_位置);
mAttendeesField=(EditText)v.findViewById(R.id.plan_与会者);
mdDescriptionField=(EditText)v.findViewById(R.id.plan\u description);
mDateButton=(按钮)v.findViewById(R.id.plan\u日期);
mTimeButton=(按钮)v.findViewById(R.id.plan\u时间);
返回v;
}
@凌驾
创建选项菜单(菜单菜单,菜单充气机){
充气机。充气(右菜单。主菜单至菜单);
}
公共布尔值onOptionsItemSelected(菜单项项){
开关(item.getItemId()){
案例R.id.save_按钮:
Log.d(标记“按下保存按钮”);
返回true;
违约:
返回super.onOptionsItemSelected(项目);
}
}
}

您已将参数发送到活动(PlanDetailsActivity)

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

在PlainDetailsActivity中,您应该创建片段实例,如下所示:

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

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

事实上,向片段发送参数的正确方法如下:

在调用者中(通常是一个活动,但可能有另一个片段,如在您的示例中,它也会工作,我不能说)
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);