OnResume() 在 MainActivity 中导致无限循环

OnResume() causing infinite loop in MainActivity

我最近将 OnResume 方法添加到我的 main activity,但是,在这样做之后,我的应用程序现在陷入了无限循环,因为 OnResume 被重复调用,但我不知道为什么。

知道导致重复调用 OnResume 方法的 MainActivity 代码是什么吗?或者在 Android Studio 中有什么方法可以追溯以查看呼叫的来源?

作为参考,我想在 OnResume 方法中调用 recreate 的原因是用户可以在另一个 activity 中更改活动主题,所以当我回到 MainActivity 时,我希望它能够拾取主题更改。

public class MainActivity extends AppCompatActivity {

    Toolbar toolbar;
    TabLayout tabLayout;
    static int errorDelay = 2000;
    ViewPager viewPager;
    PageAdapter pageAdapter;
    TabItem tabAveSpeed;
    TabItem tabDistance;
    TabItem tabTime;



    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            View v = getCurrentFocus();
            if (v instanceof EditText) {
                Rect outRect = new Rect();
                v.getGlobalVisibleRect(outRect);
                if (!outRect.contains((int) event.getRawX(), (int) event.getRawY())) {
                    v.clearFocus();
                    InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                    imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
                }
            }
        }
        return super.dispatchTouchEvent(event);
    }


    @Override
    protected void onCreate(Bundle savedInstanceState) {

        if (!PrefUtil.getBool(this, "usedBefore")) {
            PrefUtil.saveInt(this, "distanceSpinnerPref", 0);
            PrefUtil.saveBool(this, "usedBefore", true);
            PrefUtil.saveString(this, "activeThemeColour", "Grey");
        }

        String colour = PrefUtil.getString(this, "activeThemeColour");

        switch (colour) {
            case "Green":
                setTheme(R.style.AppTheme_Green);
                break;
            case "Grey":
                setTheme(R.style.AppTheme_Grey);
                break;
            default:
                setTheme(R.style.AppTheme_Grey);
                break;
        }


        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        toolbar = findViewById(R.id.toolbar);
        toolbar.setTitle(getResources().getString(R.string.app_name));
        setSupportActionBar(toolbar);

        tabLayout = findViewById(R.id.tabMenu);
        tabAveSpeed = findViewById(R.id.averageSpeedTab);
        tabDistance = findViewById(R.id.distanceTab);
        tabTime = findViewById(R.id.timeTab);
        viewPager = findViewById(R.id.viewPager);

        pageAdapter = new PageAdapter(getSupportFragmentManager(), tabLayout.getTabCount());
        viewPager.setAdapter(pageAdapter);
        viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));



        tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                viewPager.setCurrentItem(tab.getPosition());
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {

            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {

            }
        });
    }

    @Override
    protected void onResume(){
        super.onResume();
        recreate();
    }

    public void updateTabTitle (String newTitle){
        TabLayout tabLayout;
        tabLayout = findViewById(R.id.tabMenu);
        tabLayout.getTabAt(0).setText(newTitle);
    }
}

从这一行删除recreate();

@Override
protected void onResume(){
    super.onResume();
    //recreate();  - delete this line
}

您可以阅读 here in docs recreate() 的做法。

正如其他人所提到的,在您的 onResume() 方法中不加选择地调用 recreate() 会给您无限循环。

您可以做一些事情,例如在用户更改主题时向 SharedPreferences 写入一个值,然后在您的 onResume() 中检查该值,并且仅在主题发生时才调用 recreate()变了。

在您的另一个 activity 中,当用户更改主题时,执行此操作:

PreferencesManager.getDefaultSharedPreferences(context)
        .edit()
        .putBoolean("theme_changed", true)
        .apply();

然后在您的另一个 activity 中,在 onResume() 中,执​​行此操作:

SharedPreferences prefs = PreferencesManager.getDefaultSharedPreferences(this);

if (prefs.getBoolean("theme_changed", false)) {
    prefs.edit().remove("theme_changed").apply();
    recreate();
}

这样,您只会在有理由的情况下recreate(),而不会永远循环。