简体   繁体   English

Android 广播接收器在 ViewPager 中使用时注册多个侦听器

[英]Android Broadcast Reciver Registering Multiple Listeners When used in a ViewPager

I have a ViewPager that builds a tabbed view with Fragments.我有一个 ViewPager,它使用 Fragments 构建一个选项卡式视图。 In the Fragments I am registering aa Broadcast receiver for that Fragments DataSet (the data gets updated from a RESTApi.)在片段中,我正在为该片段数据集注册一个广播接收器(数据从 RESTApi 更新。)

there are 4 tabs but it seems to be registering a new listener each time a tab is brought into view by the user which cant be good.有 4 个选项卡,但每次用户将选项卡带入视图时,它似乎都在注册一个新的侦听器,这不是很好。

I register it in OnViewCreated() method我在 OnViewCreated() 方法中注册它

Should It be in create()?它应该在 create() 中吗?

My Fragment Class我的片段 Class

public class DynamicFragment extends Fragment {

private static final String ARG_SECTION_NUMBER = "section_number";
private static final String ARG_TITLE = "title";
//.......
//.......

private Context context;
RecyclerView cardRecyclerView;
View view;
PresentationAdapter presentationAdapter;

public DynamicFragment() {
    // Required empty public constructor
    SyncApplication.getContext().registerReceiver(mReceiver, new IntentFilter(Sync.BROADCAST_FILTER));
}

@Override
public void onAttach(Context context) {
    super.onAttach(context);
    this.context = context;

}

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

    sectionNumber = getArguments() != null ? getArguments().getInt(ARG_SECTION_NUMBER) : 1;
    title = getArguments() != null ? getArguments().getString(ARG_TITLE) : "Search";
}

@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    if (title.equals("Search")){
        Search search = new Search(inflater, container, savedInstanceState);
        return search.setView();
    }
    else{
        view = inflater.inflate(R.layout.fragment_dynamic, container, false);
        cardRecyclerView = view.findViewById(R.id.presentation_cards_recycler);
        presentationAdapter = new PresentationAdapter(context, getPresentationListByCategory());
        cardRecyclerView.setLayoutManager(new GridLayoutManager(context, 2));
        cardRecyclerView.setItemAnimator(new DefaultItemAnimator());
        cardRecyclerView.setAdapter(presentationAdapter);

        // Inflate the layout for this fragment
    }
    return view;
}

public void updateCardView() {
    if (presentationList != null && presentationList.size() > 0) {
        if (presentationAdapter != null) {
            presentationAdapter.setPresentationList(getPresentationListByCategory());
            presentationAdapter.notifyDataSetChanged();
        }
    }
}

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    if (context != null) {
        context.registerReceiver(mReceiver, new IntentFilter(Sync.BROADCAST_FILTER));
    }
}

public ArrayList<Presentation> getPresentationListByCategory() {
    dbManager = new DbManager(context);
    presentationList = dbManager.getAllPresentations();
    ArrayList<Presentation> presentationsByCategory = new ArrayList();

    for (Presentation presentation : presentationList) {
        if (presentation.getCategory_name().equals(title)) {
            presentationsByCategory.add(presentation);
        }
    }
    return presentationsByCategory;
}

public static DynamicFragment newInstance(String val) {
    DynamicFragment fragment = new DynamicFragment();
    Bundle args = new Bundle();
    args.putString("title", val);
    fragment.setArguments(args);
    return fragment;
}

BroadcastReceiver mReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        // Do what you need in here
        String message = intent.getStringExtra("syncMessage");
        Log.d("Fragment Reciever", message);
        if (message.equals("DownloadComplete")) {
            updateCardView();
        }
    }
};

} }

There are two places where you register a BroadcastReceiver in your Fragment :您在Fragment有两个地方注册BroadcastReceiver

public DynamicFragment() {
    // Required empty public constructor
    SyncApplication.getContext().registerReceiver(mReceiver, new IntentFilter(Sync.BROADCAST_FILTER));
}

and

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    if (context != null) {
        context.registerReceiver(mReceiver, new IntentFilter(Sync.BROADCAST_FILTER));
    }
}

Since they both use the same IntentFilter , this is already one too many.由于他们都使用相同的IntentFilter ,这已经是太多了。 In addition to that, you do not unregister any of the registered BroadcastReceiver s, so they remain active.除此之外,您不会取消注册任何已注册的BroadcastReceiver ,因此它们仍然处于活动状态。

You should register a BroadcastReceiver eg in onResume() and unregister it in onPause() .您应该在onResume()中注册一个BroadcastReceiver并在onPause()中取消注册。 See also the Broadcasts Overview另请参阅广播概述

You can register the receiver in the activity instead of in the fragment.您可以在活动中而不是在片段中注册接收器。

Once you receive the broadcast in the activity, you can get the current instance of the fragment displayed in view pager and then call the updateCardView() method for that fragment.在活动中接收到广播后,您可以获取在视图寻呼机中显示的片段的当前实例,然后为该片段调用 updateCardView() 方法。

This way you only register for the receiver once in activity.这样,您只需在活动中注册一次接收器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM