【问题标题】:Slower performance for onClickListener when set in a separate method在单独的方法中设置时 onClickListener 的性能较慢
【发布时间】:2020-07-16 05:36:09
【问题描述】:

我有一个带有许多按钮的片段。 有些按钮是唯一的,但许多按钮做同样的事情,它为片段事务设置一个 onClickListener。

代码如下所示:

    private Button mSetPresetBtn;
    private Button mGeneralBtn;
    private Button mSecurityBtn;
    [...]

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

        initViews();
        setOnClickListeners();
    }

    private void initViews() {
        mSetPresetBtn = requireView().findViewById(R.id.btn_set_preset);
        mGeneralBtn = requireView().findViewById(R.id.btn_open_general);
        mSecurityBtn = requireView().findViewById(R.id.btn_open_security);
        [...]
    }

    private void setOnClickListeners() {
        mSetPresetBtn.setOnClickListener(v -> {
            DialogPresetSelection presetSelectionDialog = new DialogPresetSelection();
            presetSelectionDialog.show(Objects.requireNonNull(getFragmentManager()), "DialogPresetSelection");
        });

        mGeneralBtn.setOnClickListener(v -> {
            FragmentTransaction transaction = Objects.requireNonNull(getFragmentManager()).beginTransaction();
            FragmentSettingsGeneral fragment = new FragmentSettingsGeneral();
            transaction.replace(R.id.fl_settings_detail, fragment, "FragmentSettingsGeneral");
            transaction.addToBackStack(null);
            transaction.commit();
        });

        mSecurityBtn.setOnClickListener(v -> {
            FragmentTransaction transaction = Objects.requireNonNull(getFragmentManager()).beginTransaction();
            FragmentSettingsSecurity fragment = new FragmentSettingsSecurity();
            transaction.replace(R.id.fl_settings_detail, fragment, "FragmentSettingsSecurity");
            transaction.addToBackStack(null);
            transaction.commit();
        });

        [...]
    }

我有很多这样的按钮,并且想减少冗余代码。 所以我改变了上面的方法,为相关的按钮和片段创建了一个对列表。

新代码如下所示:

    private Button mSetPresetBtn;
    private Button mGeneralBtn;
    private Button mSecurityBtn;
    [...]

    private List<Pair<Button, FragmentSettingsBase>> mBtnFragmentPairs = new ArrayList<>();

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

        initViews();
        createBtnFragmentPairs();
        setOnClickListeners();
    }

    private void initViews() {
        mSetPresetBtn = requireView().findViewById(R.id.btn_set_preset);
        mGeneralBtn = requireView().findViewById(R.id.btn_open_general);
        mSecurityBtn = requireView().findViewById(R.id.btn_open_security);
        [...]
    }

    private void createBtnFragmentPairs() {
        mBtnFragmentPairs.add(new Pair<>(mGeneralBtn, new FragmentSettingsGeneral()));
        mBtnFragmentPairs.add(new Pair<>(mSecurityBtn, new FragmentSettingsSecurity()));
        [...]
    }

    private void setOnClickListeners() {
        mSetPresetBtn.setOnClickListener(v -> {
            DialogPresetSelection presetSelectionDialog = new DialogPresetSelection();
            presetSelectionDialog.show(Objects.requireNonNull(getFragmentManager()), "DialogPresetSelection");
        });

        [...]

        for (Pair<Button, FragmentSettingsBase> pair : mBtnFragmentPairs) {
            Button button = Objects.requireNonNull(pair.first);
            FragmentSettingsBase fragment = Objects.requireNonNull(pair.second);
            setOnClickListenerForFragmentTransaction(button, fragment);
        }
    }

    private void setOnClickListenerForFragmentTransaction(Button button, FragmentSettingsBase fragment) {
        button.setOnClickListener(v -> {
            FragmentTransaction transaction = Objects.requireNonNull(getFragmentManager()).beginTransaction();
            transaction.replace(R.id.fl_settings_detail, fragment, fragment.getClass().getSimpleName());
            transaction.addToBackStack(null);
            transaction.commit();
        });
    }

在功能方面,它似乎工作正常。但是,片段事务的性能似乎变得慢得多。 如果在生命周期的onActivityCreated()部分设置了onClickListeners,并且每个按钮都是基础Fragment的成员变量,那么我无法想象为什么会出现性能下降。

是什么导致性能下降? 如何在不损失性能的情况下删除冗余代码?

【问题讨论】:

    标签: android performance onclicklistener android-lifecycle fragmenttransaction


    【解决方案1】:

    您正在创建片段实例

    private void createBtnFragmentPairs() { mBtnFragmentPairs.add(new Pair&lt;&gt;(mGeneralBtn, new FragmentSettingsGeneral())); mBtnFragmentPairs.add(new Pair&lt;&gt;(mSecurityBtn, new FragmentSettingsSecurity())); [...] }

    它们占用了大量内存,没有任何目的。

    我建议你创建和重用监听器而不是 Pair

    OnClickListener listener = new OnClickListener() {
            @Override
            public void onClick(View view) {
                // do logic here and reuse it on views.
            }
        };
    
        button.setOnClickListener(listener);
        button1.setOnClickListener(listener);
        ......
    
    

    【讨论】:

    • 感谢您的建议。如果我想像您建议的那样重用同一个侦听器,我将如何传递 .replace() 方法中使用的不同 FragmentSettingsBase 对象?
    • 只需在侦听器块内添加 FragmentSettingsBase 初始化,并仅在单击时创建它。
    猜你喜欢
    • 2023-04-05
    • 2023-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-09
    相关资源
    最近更新 更多