android-fragments Android,如何更正BroadcastReceiver的句柄意图

g6ll5ycj  于 2022-11-13  发布在  Android
关注(0)|答案(1)|浏览(124)

我有一个活动和两个在这个活动中打开的片段(例如FragmentFirst,FragmentSecond)。在我的活动中,我注册了BroadcastReceiver。当我接收到任何事件(在onReceive中)时,我需要在第二个片段的TextView中显示接收到的文本。
我可以在第二个片段中注册BroadcastReceiver,但是,当第二个片段打开时,事件可能会出现,然后我没有时间注册BroadcastReceiver,我会丢失事件。
所以我在活动的onReceive中的代码看起来像这样:

@Override
        public void onReceive(Context context, Intent intent) {
            String receivedMessage = intent.getStringExtra(MY_MESSAGE);
            Fragment currentFragment = getSupportFragmentManager().findFragmentById(R.id.container);
            if (currentFragment instanceof FragmentSecond) {
                ((FragmentSecond) currentFragment).initMessage(receivedMessage);
            }
        }

现在我有一个问题,会不会有这样一种情况,当前片段是FragmentSecond,但是这个片段的视图还没有创建,这种情况下,我调用我的FragmentSecond的一个initMessage,为TextView设置receivedMessage,就可以得到一个NPE。
如果这真的是可能的,那么我将不得不在initMessage中添加某种检查:

public void initMessage(String receivedMessage) {
    if (isViewCreated) { // flag to detect when view was created
        tvMessage.setText(receivedMessage);
        savedMessage = "";
    } else {
        savedMessage = receivedMessage; // save message to display it when view will be created
    }
}

在实践中,我无法重现这种情况,但在我看来,这是可能的。请告诉我,这是否可能?
P.S.我感觉onReceive控制着生命周期,并且在创建片段视图时被调用。因为我试图在创建FragmentSecond视图之前发送广播,但是直到我的FragmentSecondonViewCreated被调用,onReceive才被调用。然而,我可能是错的

vof42yt1

vof42yt11#

您可以将消息存储在“活动”中,并在片段准备就绪时使用它.

活动

String message = null; 

    @Override
    public void onReceive(Context context, Intent intent) {
        message = intent.getStringExtra(MY_MESSAGE);
    }

你可以在onAttach(context)方法中“触摸”Activity的片段。

片段

private String message = null;

    void onAttach(Context: context) {
        super.onAttach(context)
        if (context instanceof MainActivity) {
            MainActivity mainActivity = (MainActivity) context;
            message = mainActivity.message;
        }
    }

用于获取最新值。
由于您是在Java中操作,所以它有点冗长,但是对于更新,您可以使用Observer模式(创建片段将实现的侦听器接口,并将其自身注册到活动)。

interface MessageObserver {
    void onMessageChange(String message);
}

为Activity使用WeakReference,这样它就不会泄漏上下文。

片段

private WeakReference<MainActivity> mWeakRefActivity;

    @Override
    public void onAttach(@NonNull Context context) {
        super.onAttach(context);
        if (context instanceof MainActivity) {
            MainActivity mainActivity = (MainActivity) context;
            mWeakRefActivity = new WeakReference<MainActivity>(mainActivity);
            mainActivity.addObserver(this);
        }
    }

    @Override
    public void onDetach() {
        // Clean up after yourself
        mWeakRefActivity.get().removeObserver(this);
        super.onDetach();
    }

活动

ArrayList<MessageObserver> mObservers = new ArrayList<MessageObserver>();

    void addObserver(MessageObserver observer) {
        mObservers.add(observer);
    }

    void removeObserver(MessageObserver observer) {
        mObservers.remove(observer);
    }

    public void onReceive(Context context, Intent intent) {
        message = intent.getStringExtra(MY_MESSAGE);
        for (MessageObserver observer : mObservers) {
            observer.onMessageChange(message);
        }
    }

相关问题