在片段中注册和注销BroadcastReceiver


69

我的应用程序有一个带有3个片段选项卡的操作栏。在第二个片段中,我注册和注销了BroadcastReceiver。我注销在接收onPause和登记它onCreateViewonResume

getActivity().registerReceiver(this.batteryInfoReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));

getActivity().unregisterReceiver(batteryInfoReceiver);

1)是否可以在onCreateView和onResume中两次注册相同的接收者?(是否无害?)

2)仅在onResume中注册接收者就足够了吗?


在片段上尝试时出现注销错误。我面临的问题是-我试图注销两次。一次on onDestroy()和一次on onPause()。我也确实在onCreate()和onResume()上注册了一次。稍后,在查看片段的生命周期时,我发现我只需要在onResume()上注册而在onPause()上取消注册。这足以在片段上注册和注销。希望这可以帮助某人进行片段广播。:)
Dinesh

Answers:


142

看看生命周期Fragments

onCreateView(): 系统在片段第一次绘制其用户界面时调用此方法。要为片段绘制UI,必须从此方法返回一个View,它是片段布局的根。如果该片段不提供UI,则可以返回null。

onResume(): 该片段在运行的活动中可见

onPause(): 通常在此处应提交应保留在当前用户会话之后的所有更改(因为用户可能不会回来)。

结论:

因此最好 只在内部注册接收者,onResume()然后在内部取消注册,onPause()因为onCreateView()只处理视图层次结构。它与接收器无关。因此它不是有害的,但肯定是没有用的。

希望对您有所帮助!


15

这是对我有用的代码:

内部布局:

<Button
    android:id="@+id/button2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:onClick="sendInternalBroadcast"
    android:text="Broadcast"/>

片段布局:

    <?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:gravity="center">

    <TextView
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:text="Fragment One"
        android:id="@+id/fragmentoneTextView1"/>

</LinearLayout>

内部主要活动:

    public void sendInternalBroadcast(View view)
{
    Intent intent = new Intent();
intent.setAction("com.codingbadly.stefanronnkvist.simplebroadcastreceiver.setup");
    intent.putExtra("From", "sendInternalBroadcast");
    sendBroadcast(intent);
}

分段:

import android.app.*;
import android.content.*;
import android.os.*;
import android.view.*;
import android.widget.*;

public class FragmentOne extends Fragment
{
    View view;
    Context _context;
    PendingIntent pi;
    BroadcastReceiver br;
    AlarmManager am;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        view = inflater.inflate(R.layout.fragmentone, container, false);
        setup();
        return view;
    }

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

    @Override
    public void onDestroyView()
    {
        super.onDestroyView();
        _context.unregisterReceiver(br);
    }


    private void setup()
    {
        br = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent i)
            {
                TextView tv = (TextView)view.findViewById(R.id.fragmentoneTextView1);
                tv.setText("onReceive");
            }
        };
        _context.registerReceiver(br, new IntentFilter("com.codingbadly.stefanronnkvist.simplebroadcastreceiver.setup"));
        pi = PendingIntent.getBroadcast(_context, 0, new Intent("com.codingbadly.stefanronnkvist.simplebroadcastreceiver.setup"), 0);
        am = (AlarmManager)(_context.getSystemService(Context.ALARM_SERVICE));
    }
}

祝你好运.. Stefan Ronnkvist


1
您的解决方案很棒!拜托,请更正您的个人资料。user1579736并不酷,但是你很酷!
DmitryBoyko '17


0

使用Fragment,Receiver not registered在某些情况下,就像我的情况一样,您最终将获得异常。

为了解决这个问题,我使用了

 LocalBroadcastManager.getInstance(ctx).registerReceiver(myReceiver,IntentFilter(...))

代替

 activity.registerReceiver(paxAmountReceiver,IntentFilter(...))

与注销类似,在中使用onDestroyView()(例如)

LocalBroadcastManager.getInstance(ctx).unregister(myReceiver)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.