我有一个简单的天气应用程序,使用片段显示当前,每小时和每日天气。我注意到,当我打开一个沉重的应用程序(游戏),然后我尝试打开我的应用程序时它崩溃与空指针异常,因为片段(可能所有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();
}
}
}
答案 0 :(得分:1)
请在Toast(Line:128)中使用mActivity的实例而不是getActivity()。
`Toast.makeText(getActivity(),"Main Activity is null in Hourly Fragment",Toast.LENGTH_LONG).show();}`
至于额外检查,在制作Toast on mActivity之前提供空检查。