尝试在空对象引用上调用虚方法

时间:2015-03-11 08:44:35

标签: java android ios serialization nullpointerexception

这是我得到的错误:

  

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)'

我理解它是由于变量具有空值但我无法解释为什么。在getSerializable()的{​​{1}}方法中看起来像'EXTRA_NEW_PLAN',但我不知道。我是Android的新手,请原谅我,如果它很明显,但任何帮助都会非常感激。

以下是DetailsFragment;

的代码
ListFragment

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

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

}

}

2 个答案:

答案 0 :(得分:2)

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

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

在调用者中(通常它是一个Activity,但也许是另一个片段,就像你的例子一样,它也可以工作,我不能肯定地说):

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方法的调用也可能需要一些改变。另一个片段。这只是一个整体描述。

我的回答适用于两个片段都在一个活动中的情况。你对意图的使用让我对此有所怀疑,但我并不完全理解它。

答案 1 :(得分:0)

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

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

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

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