当Android OS杀死我的应用程序时,我得到Null Pointer Exception

时间:2016-01-22 22:23:12

标签: android android-fragments nullpointerexception fragment

我有一个简单的天气应用程序,使用片段显示当前,每小时和每日天气。我注意到,当我打开一个沉重的应用程序(游戏),然后我尝试打开我的应用程序时它崩溃与空指针异常,因为片段(可能所有3)都没有附加到片段管理器。我经历过多次这次事故,但没有找到解决问题的办法。我已经包含了一个if-else语句来检查片段是否已附加(请参阅日志)。如果您知道我为什么要获得NPE,请分享。提前谢谢!

这是我的日志:

Getting first location updates...
01-22 22:02:05.362 14082-14082/koemdzhiev.com.stormy V/MainActivity: Locality: Aberdeen, CountryName United Kingdom
01-22 22:02:05.749 14082-14115/koemdzhiev.com.stormy D/MainActivity: OnResponse_ scheduledFuture is CANCELED
01-22 22:02:05.757 14082-14082/koemdzhiev.com.stormy D/MainActivity: isSuccessful - run on UNI threth (update display)...
01-22 22:02:05.787 14082-14082/koemdzhiev.com.stormy D/MainActivity: mCurrent fragment is NOT attached!
01-22 22:02:05.788 14082-14082/koemdzhiev.com.stormy D/AndroidRuntime: Shutting down VM
01-22 22:02:05.789 14082-14082/koemdzhiev.com.stormy E/AndroidRuntime: FATAL EXCEPTION: main
                                                                   Process: koemdzhiev.com.stormy, PID: 14082
                                                                   java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference
                                                                       at android.widget.Toast.<init>(Toast.java:103)
                                                                       at android.widget.Toast.makeText(Toast.java:260)
                                                                       at koemdzhiev.com.stormy.ui.Hourly_forecast_fragment.setUpHourlyFragment(Hourly_forecast_fragment.java:128)
                                                                       at koemdzhiev.com.stormy.ui.MainActivity$3$3.run(MainActivity.java:247)
                                                                       at android.os.Handler.handleCallback(Handler.java:739)
                                                                       at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                       at android.os.Looper.loop(Looper.java:135)
                                                                       at android.app.ActivityThread.main(ActivityThread.java:5294)
                                                                       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:904)
                                                                       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699)

MainActivity中有问题的方法:

public void getForecast(double latitude, double longitude) {
    //scedule no response from the server task...
    mScheduledFuture = exec.schedule(mNotAbleToGetWeatherDataTask,12, TimeUnit.SECONDS);

    Log.d(TAG, "getForecast initiated...");
    String API_KEY = "API_KEY";
    String forecast = "https://api.forecast.io/forecast/" + API_KEY + "/" + latitude + "," + longitude + "?units=si";

    if (isNetworkAvailable()) {

        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                .url(forecast)
                .build();

        Call call = client.newCall(request);

        call.enqueue(new Callback() {
            @Override
            public void onFailure(Request request, IOException e) {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        toggleSwipeRefreshLayoutsOff();
                    }
                });
                //on response from the server cansel the noResponseFromServer task
//on response from the server cansel the noResponseFromServer task
                Log.d(TAG,"OnFailure_ scheduledFuture is CANCELED");
                mScheduledFuture.cancel(true);
                alertUserAboutError();
            }

            //when the call to the Okhttp library finishes, than calls this method:
            @Override
            public void onResponse(Response response) throws IOException {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        toggleSwipeRefreshLayoutsOff();
                    }
                });
                try {
                    String jsonData = response.body().string();
                    if (response.isSuccessful()) {
                        mForecast = parseForecastDetails(jsonData);
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                Log.d(TAG, "isSuccessful - run on UNI threth (update display)...");

                                if(mCurrent_forecast_fragment.isAdded()){
                                    Log.d(TAG, "mCurrent fragment is attached!");
                                    mCurrent_forecast_fragment.updateDisplay();
                                }else{
                                    Toast.makeText(MainActivity.this, "mCurrent is not attached!", Toast.LENGTH_SHORT).show();
                                    Log.d(TAG, "mCurrent fragment is NOT attached!");
                                  adapter = null;
                                    adapter = new ViewPagerAdapter(getSupportFragmentManager(), Titles, Numboftabs, mCurrent_forecast_fragment,
                                            mHourly_forecast_fragment, mDaily_forecast_fragment);
                                }

                                mHourly_forecast_fragment.setUpHourlyFragment();
                                mDaily_forecast_fragment.setUpDailyFragment();
                                toggleSwipeRefreshLayoutsOff();
                                //set the isFirstTime to true so that the next refresh wont get location
                                isFirstTimeLaunchingTheApp = false;

                            }
                        });


                    } else {
                        alertUserAboutError();
                    }
                } catch (IOException | JSONException e) {
                    Log.e(TAG, "Exception caught:", e);
                }
                //on response from the server cansel the noResponseFromServer task
                Log.d(TAG,"OnResponse_ scheduledFuture is CANCELED");
                mScheduledFuture.cancel(true);
            }
        });
    } else {
        toggleSwipeRefreshLayoutsOff();
        alertForNoInternet();
        Log.d(TAG, "Alert No Internet" + 220);
        //is there is no internet cancel the noResponseFromServer task
        Log.d(TAG, "No internet _ scheduledFuture is CANCELED");
        mScheduledFuture.cancel(true);
    }
}

这是mCurrent片段代码(第247行是这段代码: mHourly_forecast_fragment.setUpHourlyFragment( in main activity);

public class Current_forecast_fragment extends Fragment {
private static final String TAG = "MainActivity";
private MainActivity mActivity;
TextView mTimeLabel;
TextView mTemperatureLabel;
TextView mHumidityValue;
TextView mPrecipValue;
TextView mSummaryLabel;
TextView mLocationLabel;
TextView mWindSpeedValue;
TextView mFeelsLike;
ImageView mIconImageView;
ImageView mDegreeImageView;
public SwipeRefreshLayout mSwipeRefreshLayout;

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

    mActivity = ((MainActivity) getActivity());
//        Log.d(mActivity.getClass().getSimpleName(),"OnCreateFragment");
}


@Override
public void onResume() {
    super.onResume();
    Log.d(TAG, "OnResume - Current Fragment called");
    mActivity = ((MainActivity) getActivity());
}

@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.current_forefast_fragment, container, false);
    mTimeLabel = (TextView)v.findViewById(R.id.timeLabel);
    mTemperatureLabel = (TextView)v.findViewById(R.id.temperatureLabel);
    mHumidityValue = (TextView)v.findViewById(R.id.humidityValue);
    mPrecipValue = (TextView)v.findViewById(R.id.precipValue);
    mSummaryLabel = (TextView)v.findViewById(R.id.summaryLabel);
    mLocationLabel = (TextView)v.findViewById(R.id.locationLabel);
    mWindSpeedValue = (TextView)v.findViewById(R.id.windSpeedValue);
    mFeelsLike = (TextView)v.findViewById(R.id.feels_like_label);
    mIconImageView = (ImageView)v.findViewById(R.id.iconImageView);
    mDegreeImageView = (ImageView)v.findViewById(R.id.degreeImageView);
    mSwipeRefreshLayout = (SwipeRefreshLayout)v.findViewById(R.id.current_swipe_refresh_layout);
    mSwipeRefreshLayout.setColorSchemeResources(R.color.orange, R.color.blue, R.color.green);
    mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
        @Override
        public void onRefresh() {
            Log.d("TAG", "Swiping in current!");
            //if there is internet and if the mSwipeRefreshLayout in the Hourly and daily fragments are not already running...
            if (mActivity.isNetworkAvailable()) {
                if (!mActivity.mHourly_forecast_fragment.mSwipeRefreshLayout.isRefreshing() && !mActivity.mDaily_forecast_fragment.mSwipeRefreshLayout.isRefreshing()) {
                    if (mActivity.isLocationServicesEnabled()) {
                        if (mActivity.latitude != 0.0 && mActivity.longitude != 0.0) {
                            mActivity.getForecast(mActivity.latitude, mActivity.longitude);
                        } else {
                            mActivity.getLocation();
                        }
                    }else{
                        mActivity.alertForNoLocationEnabled();
                    }
                }else{
                    mSwipeRefreshLayout.setRefreshing(false);
                    Toast.makeText(mActivity, "currently refreshing...", Toast.LENGTH_SHORT).show();
                }
            } else {
                Toast.makeText(mActivity, "No Internet Connection!", Toast.LENGTH_LONG).show();
                mSwipeRefreshLayout.setRefreshing(false);
            }
        }
    });
    //Start the swipe refresh layout on start up is internet available
    if(mActivity.isNetworkAvailable())
        mSwipeRefreshLayout.post(new Runnable() {
            @Override
            public void run() {
                mSwipeRefreshLayout.setRefreshing(true);
                Log.d("TAG","running swiping...");
        }
    });

    return v;
}

@Override
public void onDestroyView() {
    super.onDestroyView();

    Log.d(TAG, "OnDestroyView - Current Fragment called");
}

@Override
public void onDestroy() {
    super.onDestroy();

    Log.d(TAG, "OnDestroy - Current Fragment called");
}



public void updateDisplay() {
    if(mActivity != null) {
        Current current = mActivity.mForecast.getCurrent();
        //setting the current weather details to the ui
        mTemperatureLabel.setText(current.getTemperature() + "");
        mTimeLabel.setText("At " + current.getFormattedTime() + " it is");
        mHumidityValue.setText(current.getHumidity() + "%");
        mPrecipValue.setText(current.getPrecipChange() + "%");
        mSummaryLabel.setText(current.getSummery());
        mWindSpeedValue.setText(current.getWindSpeed() + "");
        mFeelsLike.setText("Feels like: " + current.getFeelsLike());
        mLocationLabel.setText(mActivity.locationName);
        Drawable drawable = ContextCompat.getDrawable(mActivity, current.getIconId());
        mIconImageView.setImageDrawable(drawable);

    }else{
        Toast.makeText(getActivity(),"Could not update data at this time! Please, try again.",Toast.LENGTH_LONG).show();
    }

}

@Override
public void onSaveInstanceState(Bundle outState) {

}
}

每小时活动第128行:

  public void setUpHourlyFragment(){
    if (mActivity != null) {
//            Toast.makeText(mActivity, getString(R.string.network_unavailable_message), Toast.LENGTH_LONG).show();
        //set to null to reset the old one and set a new adapter bellow...
        mListView.setAdapter(null);
        Hour[] hourlyForecast = mActivity.mForecast.getHourlyForecast();
        mHours = Arrays.copyOf(hourlyForecast, hourlyForecast.length, Hour[].class);

        HourListAdapter adapter = new HourListAdapter(mActivity, mHours);
        mListView.setEmptyView(mEmptyTextView);
        mListView.setAdapter(adapter);
        mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
                Hour h = mHours[position];
                String time = h.getHour();
                String temperature = h.getTemperature()+"";
                String summary = h.getSummary();
                String message = String.format("At %s it will be %s and %s",time,temperature,summary);
                Toast.makeText(mActivity, message, Toast.LENGTH_LONG).show();
                //play animations
                YoYo.with(Techniques.Shake).duration(200).playOn(view);
            }
        });
    }else{
//LINE 128 bellow...
Toast.makeText(getActivity(),"Main Activity is null in Hourly Fragment",Toast.LENGTH_LONG).show();
    }
}
}

1 个答案:

答案 0 :(得分:1)

请在Toast(Line:128)中使用mActivity的实例而不是getActivity()。

`Toast.makeText(getActivity(),"Main Activity is null in Hourly Fragment",Toast.LENGTH_LONG).show();}`

至于额外检查,在制作Toast on mActivity之前提供空检查。