设置适配器中的上下文为空

时间:2017-01-30 11:40:29

标签: android nullpointerexception android-recyclerview android-adapter

我已经搜索了很多这个问题,对我来说没什么用。我正在尝试将预测数据设置为recyclerview,并希望通过适配器设置列表中的数据是我的适配器的一段代码......

public Adapter(Context context, List<ForecastCondition> data) {

    this.context = context;
    inflater = LayoutInflater.from(context);
    this.data = data;

}

我已经将我的适配器设置在一个片段中,并在postExecute的asynctask方法中设置适配器中的列表我正在使用此代码......

mAdapter = new Adapter(getContext(), datalist);
                    mRVFishPrice.setAdapter(mAdapter);
                    final LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
                    layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
                    mRVFishPrice.setLayoutManager(layoutManager);

我的logcat是

E/AndroidRuntime: FATAL EXCEPTION: main
                                                                         Process: com.example.om.weahterapp, PID: 19218                                                                             java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object android.content.Context.getSystemService(java.lang.String)' on a null object reference
                                                                               at android.view.LayoutInflater.from(LayoutInflater.java:219)
                                                                               at data.Adapter.<init>(Adapter.java:38)
                                                                               at Fragments.ForecastFragment$ForecastTask.onPostExecute(ForecastFragment.java:153)
                                                                               at Fragments.ForecastFragment$ForecastTask.onPostExecute(ForecastFragment.java:101)
                                                                               at android.os.AsyncTask.finish(AsyncTask.java:632)
                                                                               at android.os.AsyncTask.access$600(AsyncTask.java:177)
                                                                               at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
                                                                               at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                               at android.os.Looper.loop(Looper.java:135)
                                                                               at android.app.ActivityThread.main(ActivityThread.java:5253)
                                                                               at java.lang.reflect.Method.invoke(Native Method)
                                                                               at java.lang.reflect.Method.invoke(Method.java:372)
                                                                               at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
                                                                               at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

修改

我尝试过getActivity()以及FragmentActivity(),但它对我不起作用。

FRAGMENT

public class ForecastFragment extends Fragment {
private RecyclerView mRVFishPrice;
private Adapter mAdapter;
Context mContext;
List<ForecastCondition> datalist = new ArrayList<>();
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";

// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;

View view;

private OnFragmentInteractionListener mListener;

public ForecastFragment() {
    // Required empty public constructor
}

/**
 * Use this factory method to create a new instance of
 * this fragment using the provided parameters.
 *
 * @param param1 Parameter 1.
 * @param param2 Parameter 2.
 * @return A new instance of fragment ForecastFragment.
 */
// TODO: Rename and change types and number of parameters
public static ForecastFragment newInstance(String param1, String param2) {
    ForecastFragment fragment = new ForecastFragment();
    Bundle args = new Bundle();
    args.putString(ARG_PARAM1, param1);
    args.putString(ARG_PARAM2, param2);
    fragment.setArguments(args);
    return fragment;
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (getArguments() != null) {
        mParam1 = getArguments().getString(ARG_PARAM1);
        mParam2 = getArguments().getString(ARG_PARAM2);
    }
    mContext = getActivity();
    CityPreference cityPreference = new CityPreference(getActivity());

    renderForecastData(cityPreference.getCity());
}

public void renderForecastData(String city) {
    ForecastTask forecastTask = new ForecastTask();
    forecastTask.execute(new String[]{city});

}

private class ForecastTask extends AsyncTask<String, Void, String> {
    @Override
    protected String doInBackground(String... params) {
        try {

            String data = ((new ForecastHttpClient()).getForecast(params[0]));
            Log.v("doInBackground:" ,data);
            return data;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;

    }

    @Override
    protected void onPostExecute(String data) {
        super.onPostExecute(data);
        try {
            Log.v("postExecute:",data);
            JSONObject jObj = new JSONObject(data);
            JSONArray jArr = jObj.getJSONArray("list");

            for (int i = 0; i < jArr.length(); i++) {

                JSONObject jDayForecast = jArr.getJSONObject(i);
                ForecastCondition forecastCondition = new ForecastCondition();
                forecastCondition.lastupdateForecast = jDayForecast.getLong("dt");

                JSONObject tempObj = jDayForecast.getJSONObject("temp");
                forecastCondition.dayTempForecast = (float) tempObj.getDouble("day");
                forecastCondition.minTempForecast = (float) tempObj.getDouble("min");
                forecastCondition.maxTempForecast = (float) tempObj.getDouble("max");
                forecastCondition.nightTempForecast = (float) tempObj.getDouble("night");
                forecastCondition.eveTempForecast = (float) tempObj.getDouble("eve");
                forecastCondition.morningTempForecast = (float) tempObj.getDouble("morn");

                forecastCondition.pressureForecast = (float) jDayForecast.getDouble("pressure");
                forecastCondition.humidityForecast = (float) jDayForecast.getDouble("humidity");

                JSONArray weatherArray = jDayForecast.getJSONArray("weather");
                JSONObject jsonWeather = weatherArray.getJSONObject(0);
                forecastCondition.weatherIdForecast = jsonWeather.getInt("id");
                forecastCondition.conditionForecast = jsonWeather.getString("main");
                forecastCondition.descriptionForecast = jsonWeather.getString("description");
                forecastCondition.iconForecast = jsonWeather.getString("icon");

                datalist.add(forecastCondition);
            }


                mAdapter = new Adapter(mContext, datalist);
                mRVFishPrice.setAdapter(mAdapter);
                final LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
                layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
                mRVFishPrice.setLayoutManager(layoutManager);
                // mRVFishPrice.setLayoutManager(new LinearLayoutManager(getContext()));

        } catch (JSONException e) {
            e.printStackTrace();
        }

    }

}

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

    view = inflater.inflate(R.layout.fragment_forecast, container, false);
    mRVFishPrice = (RecyclerView) view.findViewById(R.id.fishPriceList);

    // Inflate the layout for this fragment
    return view;
}

// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
    if (mListener != null) {
        mListener.onFragmentInteraction(uri);
    }
}

@Override
public void onAttach(Context context) {
    super.onAttach(context);
    if (context instanceof OnFragmentInteractionListener) {
        mListener = (OnFragmentInteractionListener) context;
    } else {
        throw new RuntimeException(context.toString()
                + " must implement OnFragmentInteractionListener");
    }
}

@Override
public void onDetach() {
    super.onDetach();
    mListener = null;
}


public interface OnFragmentInteractionListener {
    // TODO: Update argument type and name
    void onFragmentInteraction(Uri uri);
}

}

每当我从MainActivity调用此行时,我的应用程序都会崩溃

new ForecastFragment().renderForecastData(newCity);

6 个答案:

答案 0 :(得分:1)

如果你在其他地方调用构造函数而不是oncreate或onviewcreated,那么你需要在片段onviewcreated或oncreateview中保存上下文:

Context mContext = getActivity();

并且使用mContext,如果你使用的是碎片,那就是这样。

如果在调用构造函数之前调用ondetached导致, 看起来这是你编辑的答案,但是发布完整的片段以确定。

<强>更新

经过进一步调查后,似乎在这种情况下片段中的oncreate不起作用,请参阅此图片https://www.tutorialspoint.com/android/images/fragment.jpg oncreate仍然具有null getactivity,getactivity需要on ontatach onviewcreated或oncreateview

您需要将此代码添加到您的片段中:

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        mContext = getActivity();
    }

执行此操作后,请不要再使用getactivity或getcontext,仅使用 mContext

答案 1 :(得分:0)

使用getApplicationContext()YourActivityName.this代替getContext()

答案 2 :(得分:0)

对于活动 - &gt;使用Activity.this 对于片段 - &gt;使用getActivity()而不是使用getContext(

答案 3 :(得分:0)

试试这样:

private Activity context;


public Adapter(Activity context, List<ForecastCondition> data) {

   this.context = context;
   inflater = LayoutInflater.from(context);
   this.data = data;
}

并设置适配器:

mAdapter = new Adapter(getActivity(), datalist);
mRVFishPrice.setAdapter(mAdapter);

答案 4 :(得分:0)

尝试使用getContext()而不是getConctivity()

 mAdapter = new Adapter(getActivity(), datalist);
                mRVFishPrice.setAdapter(mAdapter);
                final LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
                layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
                mRVFishPrice.setLayoutManager(layoutManager);

答案 5 :(得分:0)

首先设置布局管理器,然后设置适配器

mRVFishPrice.setLayoutManager(new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false));
mAdapter = new Adapter(getActivity(), datalist);
mRVFishPrice.setAdapter(mAdapter);