Java 上下文空引用问题

Java 上下文空引用问题,java,android,nullpointerexception,adaptor,Java,Android,Nullpointerexception,Adaptor,很难解释 这是我在报告中遇到的错误: Attempt to invoke virtual method 'java.lang.Object android.content.Context.getSystemService(java.lang.String)' on a null object reference 当你进出片段时,这似乎是断断续续的。错误似乎发生在适配器中 这就是所谓的: @Nullable @Override public View onCreateVi

很难解释

这是我在报告中遇到的错误:

Attempt to invoke virtual method 'java.lang.Object android.content.Context.getSystemService(java.lang.String)' on a null object reference
当你进出片段时,这似乎是断断续续的。错误似乎发生在适配器中

这就是所谓的:

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
        getActivity().setTitle("Shipments");

        myView = inflater.inflate(R.layout.shipments_out_layout, container, false);

        listView = myView.findViewById(R.id.listView);

        fetchShipments();

        return myView;
    }

    /**
     * Fetch shipments
     */
    public void fetchShipments()
    {
        shipmentsService.fetchFromServer(getActivity());
    }

    /**
     * Show shipments
     */
    public void showShipments(){
        RealmResults<Shipment> savedShipments = shipmentsService.all();

        ShipmentsAdaptor adaptor = new ShipmentsAdaptor(savedShipments, this.getContext());

        listView.setAdapter(adaptor);
    }
这就是适配器中的错误所在:

public class ShipmentsAdaptor extends ArrayAdapter<Shipment> {

private RealmResults<Shipment> dataSet;
Context mContext;

// View lookup cache
private static class ViewHolder {
    TextView stockItemId;
    TextView technicianName;
    TextView shipmentDate;
}

public ShipmentsAdaptor(RealmResults<Shipment> data, Context context){
    super(context, R.layout.shipments_out_row_item, data);
    this.dataSet = data;
    this.mContext = context;
}
具体是这一行:超级上下文,R.layout.shippings\u out\u row\u项目,数据

我认为这可能与我们将上下文插入适配器,然后在页面完成之前更改页面的方式有关,但这被证明是不确定的

带适配器的粘贴箱:

FragmentgetContext可为空。当片段与活动分离时,此方法返回null。应用程序崩溃是因为您在未附加片段的情况下创建了适配器,这将导致传递给构造函数的null

仅当片段附加到活动时,才应调用ShowShippings方法。onAttach和onDetach都有回调,可以帮助您检测状态。isAdded还返回一个布尔值,说明片段是否已附加。选择对你方便的


祝你好运

尝试使用BaseAdapter重构适配器,如下所示

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

public class ShipmentsAdaptor extends BaseAdapter {

    private RealmResults<Shipment> dataSet;
    private Context mContext;

    // View lookup cache
    private static class ViewHolder {
        TextView stockItemId;
        TextView technicianName;
        TextView shipmentDate;
    }

    public ShipmentsAdaptor(RealmResults<Shipment> dataSet, Context context) {
        this.dataSet = dataSet;
        this.mContext = context;
    }

    @Override
    public int getCount() {
        return dataSet.size();
    }

    @Override
    public Object getItem(int position) {
        return dataSet.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        // Get the data item for this position
        Shipment shipment = (Shipment) getItem(position);
        // Check if an existing view is being reused, otherwise inflate the view
        ViewHolder viewHolder; // view lookup cache stored in tag

        final View result;

        if (convertView == null) {

            viewHolder = new ViewHolder();
            LayoutInflater inflater = LayoutInflater.from(mContext);
            convertView = inflater.inflate(R.layout.shipments_out_row_item, parent, false);
            viewHolder.stockItemId = convertView.findViewById(R.id.stockItemId);
            viewHolder.technicianName = convertView.findViewById(R.id.technicianName);
            viewHolder.shipmentDate = convertView.findViewById(R.id.shipmentDate);

            result = convertView;

            convertView.setTag(viewHolder);

        } else {
            viewHolder = (ViewHolder) convertView.getTag();
            result=convertView;
        }

        lastPosition = position; //use getItemId() instead

        if(shipment != null){
            viewHolder.stockItemId.setText(String.valueOf(shipment.id));
            if(shipment.technician != null){
                viewHolder.technicianName.setText(shipment.technician.name);
            }
            viewHolder.shipmentDate.setText(shipment.shippingDate);
        }

        // Return the completed view to render on screen
        return convertView;
    }
}

您可以在适配器安装过程中检查null以避免出现这种情况。在一个片段中,getActivity可以在过程中的不同点上运行。例如,在ShowShippings中

您还可以检查isAdded,如果为false,则可以从getActivity获取null


也可以考虑将调用从OnCeCaleVIEW移动到OnActuviTeo,而

看起来像是调用取货;在片段布局视图myView返回之前,因此当适配器被实例化时它是空的

尝试:


搬运货物;从onCreateView将其置于onResume或override onStart中,然后从那里调用它

与问题无关,但。。。它应该是适配器,而不是适配器:把您的所有日志错误。请!添加了完整的错误,谢谢。但是把你的全适配器也放进去。请!添加了一个带有AdapterTanks的pastebin,这很有意义,将使用上面的代码查看worksonAttach是否是一个可以在片段中重写的方法,我是否在错误的位置执行此操作这不会以任何方式更改我的答案:但感谢添加更多信息。解决方案很简单-只需确保传递给适配器的上下文永远不为空。我可以直接从适配器访问上下文吗?要停止传递上下文,Hanks会马上尝试一下
Activity a = getActivity();
if( a == null || a.isFinishing() ) {
    // Not in a valid state to show things anyway, so just stop and exit
    return;
}
ShipmentsAdaptor adaptor = new ShipmentsAdaptor(savedShipments, a);