遇到麻烦了,当一个由startActivityForResult启动的活动在我在“设置”中更改语言时,然后在返回该活动后我按下了“后退”按钮-MainActivity崩溃,因此我的代码在这里:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE) {
retryButton.setVisibility(View.GONE);
page = 0;
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(MainActivity.this);
SharedPreferences.Editor editor = sp.edit();
if (resultCode == RESULT_OK) {
editor.remove("savedURL");
editor.remove("isLocation");
editor.apply();
filterButton.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.filter_selected));
adapter.getHeaderButton().setVisibility(View.VISIBLE);
headerLogo.setVisibility(View.GONE);
emptyRequest.setVisibility(View.GONE);
String filtersPrice = sp.getString("price_saved", "");
String filtersStuff = sp.getString("finder", "");
cityName = sp.getString("cityID", "");
if (!TextUtils.isEmpty(filtersPrice) || !TextUtils.isEmpty(filtersStuff)) {
text = cityName + "<font color=#B5B5B5>, " + spanWithRoubleTypeface(filtersPrice + "\u200A\u20BD/сутки" + filtersStuff) + "</font>";
}
if (TextUtils.isEmpty(filtersPrice) && TextUtils.isEmpty(filtersStuff)) {
headerTextLogo.setText(cityName);
textViewFilters.setText(", цена, комнаты");
cancelButton.setVisibility(View.GONE);
} else if (TextUtils.isEmpty(filtersPrice)) {
Log.d("FILTER", filtersStuff);
headerTextLogo.setText(cityName);
textViewFilters.setText(filtersStuff);
cancelButton.setVisibility(View.VISIBLE);
} else {
headerTextLogo.setText(cityName);
textViewFilters.setText(spanWithRoubleTypeface(", " + filtersPrice + "\u200A\u20BD/сутки" + filtersStuff));
cancelButton.setVisibility(View.VISIBLE);
}
adapter.updateLogo();
FilterData filterData = data.getParcelableExtra("FILTER");
String rooms = filterData.getRooms();
String type = filterData.getType();
if (TextUtils.isEmpty(type)) {
type = "";
}
String price = filterData.getPrice();
if ("&price=50\u200A000".equals(price)) {
price = "";
} else {
price = "&price=" + filterData.getPrice();
}
Log.e("PRICE", price);
cityID = filterData.getCity();
cityName = filterData.getCityName();
String lat = data.getStringExtra("lat");
String lng = data.getStringExtra("lng");
String filtered = data.getStringExtra("filtered");
String findText = data.getStringExtra("textFilter");
if (TextUtils.isEmpty(filtered)) {
filtered = "";
}
CityDatabase cd = new CityDatabase(MainActivity.this);
cityID = cd.getCityIdByName(cityName);
currencyID = cd.getCurrencyIdByName(cityName);
currencyID = "643";
filter = "";
String locationURL = "";
cityList.clear();
adapter.notifyDataSetChanged();
if (data.hasExtra("location")) {
if (TextUtils.isEmpty(lat) || TextUtils.isEmpty(lng)) {
locationURL = data.getStringExtra("location");
locationURL = locationURL.replace("null", "0.0");
editor.putString("isLocation", "false");
editor.apply();
emptyRequest.setVisibility(View.VISIBLE);
emptyRequest.setText(getResources().getString(R.string.emptyRequest));
Log.e("filter3", locationURL);
} else {
locationURL = data.getStringExtra("location");
filter = "type=" + rooms + "&sleeping_places=" + type + price
+ filtered + locationURL;
Log.e("filter1", filter);
filter = filter.replace(" ", "");
url = Api.BASE_URL + "/city/" + cityID + "/flats/";
editor.putString("filterURL", filter);
editor.apply();
loadFromUrl();
}
} else {
filter = "type=" + rooms + "&sleeping_places=" + type + price
+ filtered;
filter = filter.replace(" ", "");
Log.e("filter2", filter);
url = Api.BASE_URL + "/city/" + cityID + "/flats/";
editor.putString("filterURL", filter);
editor.apply();
loadFromUrl();
}
} else if (resultCode == RESULT_CANCELED) {
String filtersPrice = sp.getString("price_saved", "");
String filtersStuff = sp.getString("finder", "");
page = 0;
adapter.getHeaderButton().setVisibility(View.VISIBLE);
headerLogo.setVisibility(View.GONE);
emptyRequest.setVisibility(View.GONE);
if (!TextUtils.isEmpty(filtersPrice) || !TextUtils.isEmpty(filtersStuff)) {
text = cityName + "<font color=#B5B5B5>, " + spanWithRoubleTypeface(filtersPrice + "\u200A\u20BD/сутки" + filtersStuff) + "</font>";
}
if (TextUtils.isEmpty(filtersPrice) && TextUtils.isEmpty(filtersStuff)) {
headerTextLogo.setText(cityName);
textViewFilters.setText(", цена, комнаты");
cancelButton.setVisibility(View.GONE);
} else if (TextUtils.isEmpty(filtersPrice)) {
Log.d("FILTER", filtersStuff);
headerTextLogo.setText(cityName);
textViewFilters.setText(filtersStuff);
cancelButton.setVisibility(View.VISIBLE);
} else {
headerTextLogo.setText(cityName);
textViewFilters.setText(spanWithRoubleTypeface(", " + filtersPrice + "\u200A\u20BD/сутки" + filtersStuff));
cancelButton.setVisibility(View.VISIBLE);
}
adapter.updateLogo();
cityList.clear();
adapter.notifyDataSetChanged();
loadFromUrl();
}
}
}
这是错误日志
java.lang.RuntimeException: Unable to resume activity {ru.kvartirka.android_new/ru.kvartirka.android_new.MainActivity}: java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1, result=0, data=null} to activity {ru.kvartirka.android_new/ru.kvartirka.android_new.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.view.View.setVisibility(int)' on a null object reference
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3346)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3377)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2728)
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4356)
at android.app.ActivityThread.access$1000(ActivityThread.java:172)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1428)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:5832)
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:1399)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
Caused by: java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1, result=0, data=null} to activity {ru.kvartirka.android_new/ru.kvartirka.android_new.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.view.View.setVisibility(int)' on a null object reference
at android.app.ActivityThread.deliverResults(ActivityThread.java:3974)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3332)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3377)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2728)
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4356)
at android.app.ActivityThread.access$1000(ActivityThread.java:172)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1428)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:5832)
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:1399)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.view.View.setVisibility(int)' on a null object reference
at ru.kvartirka.android_new.MainActivity.onActivityResult(MainActivity.java:747)
at android.app.Activity.dispatchActivityResult(Activity.java:6475)
at android.app.ActivityThread.deliverResults(ActivityThread.java:3970)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3332)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3377)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2728)
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4356)
at android.app.ActivityThread.access$1000(ActivityThread.java:172)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1428)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:5832)
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:1399)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
一个导致NPE的行是这样的:
adapter.getHeaderButton()。setVisibility(View.VISIBLE);
我尝试添加
onConfigurationChanged
,但并没有太大帮助。我在适配器中分配这样的按钮:
@Override
public OffersAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, final int viewType) {
View itemLayoutView;
ViewHolder viewHolder;
if (viewType == 0 && !TextUtils.isEmpty(text)) {
itemLayoutView = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.logo_layout, viewGroup, false);
viewHolder = new ViewHolder(itemLayoutView, viewType);
} else {
itemLayoutView = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.offers_singleitem, viewGroup, false);
viewHolder = new ViewHolder(itemLayoutView, viewType);
}
return viewHolder;
}
public View getHeaderButton() {
return headerLogo;
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
if (position > 0) {
roomNumbers = (TextView) itemView.findViewById(R.id.roomNumbers);
address = (TextView) itemView.findViewById(R.id.addressTextView);
description = (TextView) itemView.findViewById(R.id.conditionsTextView);
metro = (TextView) itemView.findViewById(R.id.metroTextView);
offerImage = (ImageView) itemView.findViewById(R.id.imageView);
prices = (TextView) itemView.findViewById(R.id.priceTV);
cottageImage = (ImageView) itemView.findViewById(R.id.cottageImage);
roomsImage = (ImageView) itemView.findViewById(R.id.roomsImage);
metroImageView = (ImageView) itemView.findViewById(R.id.metroImageView);
noImage = (ImageView) itemView.findViewById(R.id.noImage);
roomsTV = (TextView) itemView.findViewById(R.id.roomsTV);
itemView.setOnClickListener(this);
} else {
headerLogo = (RelativeLayout) itemView.findViewById(R.id.headerLogo);
ImageView clickableView = (ImageView) itemView.findViewById(R.id.clickableView);
filterButton = (ImageView) itemView.findViewById(R.id.filterButton);
cancelButton = (ImageView) itemView.findViewById(R.id.cancelButton);
headerTextLogo = (TextView) itemView.findViewById(R.id.headerTextLogo);
textViewFilters = (TextView) itemView.findViewById(R.id.textViewFilters);
还有我的onCreate,onResume和onPause方法
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mMaxScrollPosition = (int) getResources().getDimension(R.dimen.scrolled);
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP) {
Window window = this.getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
window.setStatusBarColor(getResources().getColor(R.color.statusBar));
}
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
screenWidth = size.x;
swipeRefresh = (SwipeRefreshLayout) findViewById(R.id.swipeRefresh);
emptyRequest = (TextView) findViewById(R.id.emptyRequest);
sp = PreferenceManager.getDefaultSharedPreferences(MainActivity.this);
cityName = sp.getString("cityID", null);
CityDatabase cd = new CityDatabase(MainActivity.this);
currencyID = cd.getCurrencyIdByName(cityName);
currencyID = "643";
cityID = cd.getCityIdByName(cityName);
retryButton = (Button) findViewById(R.id.retryButton);
if ("804".equals(currencyID)) {
currencyID = "980";
}
text = cityName + "<font color=#B5B5B5>, " + "цена, "
+ "комнаты" + "</font>";
}
@Override
protected void onResume() {
super.onResume();
intent = getIntent();
Bundle extras = intent.getExtras();
if (extras != null) {
if (extras.containsKey("userID")) {
url = Api.BASE_URL + "/city/" + cityID + "/flats/";
setContentView(R.layout.alloffers_activity);
userID = extras.getString("userID");
String ownerName = extras.getString("ownerName");
filter += "user_id=" + userID;
Log.d("userID", userID);
adapter = new OffersAdapter(MainActivity.this, cityList, "", currencyID, false);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolBar);
if (toolbar != null) {
setSupportActionBar(toolbar);
getSupportActionBar().setTitle(ownerName);
toolbar.setNavigationIcon(R.drawable.back_shadow);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onBackPressed();
finish();
}
});
}
} else if (extras.containsKey("FILTER")) {
FilterData filterData = getIntent().getParcelableExtra("FILTER");
String rooms = filterData.getRooms();
String type = filterData.getType();
String price = filterData.getPrice();
cityID = filterData.getCity();
cityName = filterData.getCityName();
String filtered = intent.getStringExtra("filtered");
text = cityName + "<font color=#777777>, " + price
+ " ₽/сутки" + "</font>";
button.setText(Html.fromHtml(text));
url = Api.BASE_URL + Api.CITY_URL + cityID + "/flats/";
filter = "type=" + rooms + "&sleeping_places=" + type + "&price=" + price
+ filtered;
adapter = new OffersAdapter(MainActivity.this, cityList, text, currencyID, true);
}
} else {
url = Api.BASE_URL + "/city/" + cityID + "/flats/";
adapter = new OffersAdapter(MainActivity.this, cityList, text, currencyID, true);
}
if (TextUtils.isEmpty(sp.getString("isLocation", ""))) {
loadFromUrl();
} else {
emptyRequest.setText(getResources().getString(R.string.emptyRequest));
emptyRequest.setVisibility(View.VISIBLE);
}
String filtersPrice = sp.getString("price_saved", "");
String filtersStuff = sp.getString("finder", "");
if (!TextUtils.isEmpty(filtersPrice) || !TextUtils.isEmpty(filtersStuff)) {
text = cityName + "<font color=#B5B5B5>, " + spanWithRoubleTypeface(filtersPrice + "\u200A\u20BD/сутки" + filtersStuff) + "</font>";
}
CharSequence spannedPriceHint = spanWithRoubleTypeface(text);
headerLogo = (RelativeLayout) findViewById(R.id.headerLogo);
headerTextLogo = (TextView) findViewById(R.id.headerTextLogo);
textViewFilters = (TextView) findViewById(R.id.textViewFilters);
cancelButton = (ImageView) findViewById(R.id.cancelButton);
filterButton = (ImageView) findViewById(R.id.filterButton);
if (TextUtils.isEmpty(filtersPrice) && TextUtils.isEmpty(filtersStuff)) {
headerTextLogo.setText(cityName);
textViewFilters.setText(", цена, комнаты");
filterButton.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.filter));
} else if (TextUtils.isEmpty(filtersPrice)) {
Log.d("FILTER", filtersStuff);
headerTextLogo.setText(cityName);
textViewFilters.setText(filtersStuff);
cancelButton.setVisibility(View.VISIBLE);
filterButton.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.filter_selected));
} else {
headerTextLogo.setText(cityName);
textViewFilters.setText(spanWithRoubleTypeface(", " + filtersPrice + "\u200A\u20BD/сутки" + filtersStuff));
cancelButton.setVisibility(View.VISIBLE);
filterButton.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.filter_selected));
}
final String finalCityName = cityName;
filterButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, FilterActivity.class);
intent.putExtra("cityID", finalCityName);
startActivityForResult(intent, REQUEST_CODE);
overridePendingTransition(android.R.anim.slide_in_left, android.R.anim.slide_out_right);
}
});
cancelButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, FilterActivity.class);
String[] parts = text.split("<");
String city = parts[0];
SharedPreferences.Editor editor = sp.edit();
editor.remove("isLocation");
editor.apply();
intent.putExtra("currencyID", currencyID);
intent.putExtra("cityID", city);
intent.putExtra("reset", true);
startActivityForResult(intent, REQUEST_CODE);
}
});
headerLogo.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, MapFilterActivity.class);
intent.putExtra("cityID", finalCityName);
startActivityForResult(intent, REQUEST_MAP);
}
});
swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
cityList.clear();
adapter.notifyDataSetChanged();
page = 0;
loadFromUrl();
emptyRequest.setVisibility(View.GONE);
retryButton.setVisibility(View.GONE);
swipeRefresh.setRefreshing(true);
adapter.getHeaderButton().setVisibility(View.VISIBLE);
headerLogo.setVisibility(View.GONE);
}
});
swipeRefresh.setColorSchemeResources(R.color.blueAppBar);
ObservableRecyclerView cityListRecyclerview = (ObservableRecyclerView) findViewById(R.id.recyclerView);
cityListRecyclerview.setScrollViewCallbacks(this);
mLayoutManager = new LinearLayoutManager(this);
cityListRecyclerview.setLayoutManager(mLayoutManager);
cityListRecyclerview.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (swipeRefresh.isRefreshing()) {
swipeRefresh.setRefreshing(false);
}
return false;
}
});
cityListRecyclerview.setAdapter(adapter);
cityListRecyclerview.setOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
visibleItemCount = mLayoutManager.getChildCount();
totalItemCount = mLayoutManager.getItemCount();
pastVisiblesItems = mLayoutManager.findFirstVisibleItemPosition();
if (loading && !fromCache) {
if ((visibleItemCount + pastVisiblesItems) >= totalItemCount) {
loading = false;
page += 20;
if (TextUtils.isEmpty(userID)) {
loadFromUrl();
}
}
}
}
});
}
@Override
protected void onPause() {
super.onPause();
retryButton.setVisibility(View.GONE);
}
最佳答案
因此,分析您的LogCat输出:
它告诉你:
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.view.View.setVisibility(int)' on a null object reference
at ru.kvartirka.android_new.MainActivity.onActivityResult(MainActivity.java:747)
这意味着:离开设置后,无论什么原因,headerButton都将设置为null,并在onActivityResult中导致NullPointerException的访问。
通常,headerButton应该在onCreate或onCreateView中设置一次(如果您要使用片段)。
显然,您在其他地方创建了它。
离开设置对话框后,将调用onPause和onStop。一旦返回onStart和onResume。
(在此处补充您的知识:http://developer.android.com/training/basics/activity-lifecycle/index.html)
因此,在onPause / onStop / onStart / onResume中的某个位置(实际上是按此顺序),您可以将适配器设置为null和/或创建一个新的适配器实例,还删除headerHeader引用,或者立即销毁对该引用的引用。
请提供有关在何处创建和保留对headerButton的引用的更多信息(最好是代码)。