语言改变后onActivityResult崩溃

时间:2015-08-31 14:07:04

标签: java android

遇到麻烦,当一个由startActivityForResult启动的Activity我在设置中更改语言 - 然后在该活动中返回后我回击按钮 - 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);
}

1 个答案:

答案 0 :(得分:2)

分析你的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和/或创建新的适配器实例,同时删除headerButton引用,或者立即销毁对它的引用。

请在您创建的位置提供更多信息(首选代码)并保留对headerButton的引用。