zoukankan      html  css  js  c++  java
  • BroadcastReceiver 翻译

    1. 动态注册与退出

      If registering a receiver in your Activity.onResume() implementation, you should unregister it in Activity.onPause(). (You won't receive

    intents when paused, and this will cut down on unnecessary system overhead). Do not unregister in Activity.onSaveInstanceState(), because

    this won't be called if the user moves back in the history stack.

    2. 广播 Intent

      Although the Intent class is used for sending and receiving these broadcasts, the Intent broadcast mechanism here is completely

    separate from Intents that are used to start Activities with Context.startActivity(). There is no way for a BroadcastReceiver to see or

    capture Intents used with startActivity(); likewise, when you broadcast an Intent, you will never find or start an Activity.

      These two operations are semantically very different: starting an Activity with an Intent is a foreground operation that modifies what

    the user is currently interacting with; broadcasting an Intent is a background operation that the user is not normally aware of.

      虽然 Intent 是用来发送和接收Broadcast的,但这里的机制与用来启动Activity 的Intent 的机制 是不同的。 BroadcastReceiver无法捕捉

     Intent用于调用 startActivity() 的 .  类似的,当你广播 Intent , 你将永远不会启动一个Actitity.

      这个操作在语义上是完全不同的:用Intent 启动 一个Activity 是修改与 当前交互界面 的 前台操作,而广播一个Intent 是用户不会无法意识到的后台

    操作。

    3. Receiver Lifecycle

      A BroadcastReceiver object is only valid for the duration of the call to onReceive(Context, Intent). Once your code returns from this

    function, the system considers the object to be finished and no longer active.

      This has important repercussions to what you can do in an onReceive(Context, Intent) implementation: anything that requires

    asynchronous operation is not available, because you will need to return from the function to handle the asynchronous operation,

    but at that point the BroadcastReceiver is no longer active and thus the system is free to kill its process before the asynchronous

    operation completes. 

      In particular, you may not show a dialog or bind to a service from within a BroadcastReceiver. For the former, you should instead

    use the NotificationManager API. For the latter, you can use Context.startService() to send a command to the service.

      特别是,您可能无法从一个BroadcastReceiver中显示一个对话框或绑定一个服务。对于前者,你反而应该使用NotificationManager的API。对于后者,

    你可以使用Context.startService()来发送一个命令给服务。

    4. Process Lifecycle

      A process that is currently executing a BroadcastReceiver (that is, currently running the code in its onReceive(Context, Intent) method)

    is considered to be a foreground process and will be kept running by the system except under cases of extreme memory pressure.

      Once you return from onReceive(), the BroadcastReceiver is no longer active, and its hosting process is only as important as any other

    application components that are running in it. This is especially important because if that process was only hosting the BroadcastReceiver

    (a common case for applications that the user has never or not recently interacted with), then upon returning from onReceive() the system

    will consider its process to be empty and aggressively kill it so that resources are available for other more important processes.

      This means that for longer-running operations you will often use a Service in conjunction with a BroadcastReceiver to keep the

    containing process active for the entire time of your operation.

       

      一旦从OnReceive()返回,则BroadcastReceiver不再active, 它的宿主线程和其他运行的应用组件一样重要。这是特别重要的,因为如果该进程只是承载

    BroadcastReceiver的(一种常见的情况为该用户从未或最近没有交互的应用程序),然后从返回的OnReceive(),系统会认为它的进程是空的,

    积极(   )杀死它,使资源可用于其他更重要的进程。

      这意味着,对于长时间运行的操作,你经常会联合使用一个Service 与一个BroadcastReceiver,以保持进程在操作的整个时间段内是活动的。

    五。两种注册方式的区别

    1.在AndroidManifest.xml中注册

       

            <receiver android:name=".MyReceiver">
                <intent-filter >
                    <action android:name="myaction"/>
                </intent-filter>
            </receiver>

    2.在Activity中注册

             MyReceiver receiver = new MyReceiver();
             IntentFilter filter = new IntentFilter();
             filter.addAction("myaction");
             registerReceiver(receiver, filter);

    两种注册BroadcastReceiver方法的比较:

      i. 第一种注册的方法可以保证在应用程序安装之后,BroadcastReceiver始终处于活动状态,通常用于监听系统状态的改变,比如说手机的电量,

    wifi网卡的状态(当然,监视这些东西也是取决于软件的需求)。对于这样的BroadcastReceiver,通常是在产生某个特定的系统事件之后,进行

    相应的操作,比如说wifi网卡打开时,给用户一个提示;

      ii. 第二种注册方法相对第一种要灵活的多,这样注册的BroadcastReceiver通常用于更新UI的状态。一般来说,都是在一个Activity启动的时候使

    用这样的方法注册BroadcastReceiver,一旦接收到广播的事件,就可以在onReceive方法当中更新当前的这个Activity当中的控件。但是需要注

    意的是如果这个Activity不可见了,就应该调用unregisterReceiver方法来解除注册;

    public abstract Intent registerReceiver (BroadcastReceiver receiver, IntentFilter filter)

      Register a BroadcastReceiver to be run in the main activity thread. The receiver will be called with any broadcast Intent that

    matches filter, in the main application thread.

      The system may broadcast Intents that are "sticky" -- these stay around after the broadcast as finished, to be sent to any

    later registrations. If your IntentFilter matches one of these sticky Intents, that Intent will be returned by this function and sent

    to your receiver as if it had just been broadcast.

      There may be multiple sticky Intents that match filter, in which case each of these will be sent to receiver. In this case, only

    one of these can be returned directly by the function; which of these that is returned is arbitrarily decided by the system.

      If you know the Intent your are registering for is sticky, you can supply null for your receiver. In this case, no receiver is

    registered -- the function simply returns the sticky Intent that matches filter. In the case of multiple matches, the same rules as

    described above apply.

    //sticky形式的intent,接收者可以为空。接收者为空时,通常是获取最后一个保存广播的intent,从而获取intent里的值,如获取电池的电量:
    
    //因为BatteryManager发送的是sticky形式的intent,所以接收者可以为空 
    Intent batteryStatus = registerReceiver(null, ifilter); 
    
    //得到电池当前的状态(共有5种,包括unkonwn、charging、discharging、not charging、full) 
    int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1); 
    //是否处于充电状态 
    boolean isCharging =  BatteryManager.BATTERY_STATUS_CHARGING ;

      As of ICE_CREAM_SANDWICH, receivers registered with this method will correctly respect the setPackage(String) specified for an Intent

    being broadcast. Prior to that, it would be ignored and delivered to all matching registered receivers. Be careful if using this for security.

      Note: this method cannot be called from a BroadcastReceiver component; that is, from a BroadcastReceiver that is declared in an

    application's manifest. It is okay, however, to call this method from another BroadcastReceiver that has itself been registered at run time

    with registerReceiver(BroadcastReceiver, IntentFilter), since the lifetime of such a registered BroadcastReceiver is tied to the object that

    registered it.

    六。怎么用好 BroadcastReceiver 

      如果需要完成一项比较耗时的工作 , 应该通过发送 Intent 给 Service 来完成 。这里不能使用子线程来解决 , 因为 BroadcastReceiver 

    的生命周期很短 , 子线程可能还没有结束,BroadcastReceiver 就先结束了 。BroadcastReceiver 一旦结束 , 此时 BroadcastReceiver 的

    所在进程很容易在系统需要内存时被杀死 , 因为它属于空进程 ( 没有任何活动组件的进程 )。如果它的宿主进程被杀死 , 那么正在工作的子线程

    也会被杀死。

    七。广播类型

    sendBroadcast(Intent intent)

    • Broadcast the given intent to all interested BroadcastReceivers. This call is asynchronous; it returns immediately, and you will continue executing

    while the receivers are run. No results are propagated from receivers and receivers can not abort the broadcast. If you want to allow receivers to

    propagate results or abort the broadcast, you must send an ordered broadcast using sendOrderedBroadcast(Intent, String).

    sendOrderedBroadcast(Intent intent, String receiverPermission)

    • Broadcast the given intent to all interested BroadcastReceivers, delivering them one at a time to allow more preferred receivers to consume

    the broadcast before it is delivered to less preferred receivers. This call is asynchronous; it returns immediately, and you will continue executing while the

    receivers are run.

    sendStickyBroadcast(Intent intent)

    • Perform a sendBroadcast(Intent) that is "sticky," meaning the Intent you are sending stays around after the broadcast is complete, so that others

    can quickly retrieve that data through the return value ofregisterReceiver(BroadcastReceiver, IntentFilter). In all other ways, this behaves the same as

     sendBroadcast(Intent).

    八。删除

     removeStickyBroadcast (Intent intent)

    • Remove the data previously sent with sendStickyBroadcast(Intent), so that it is as if the sticky broadcast had never happened.

    九。实例

    public class MainActivity extends Activity {  
       
     private Button mSendBroadcast;  
     private Button mSendStickyBroadcast;  
     private Button mNextActivity;  
     private Context mContext;  
       
     private int mStickyBrcCount;  
        
        @Override  
        public void onCreate(Bundle savedInstanceState) {  
            super.onCreate(savedInstanceState);  
            setContentView(R.layout.main);  
            mContext = getApplicationContext();  
            mSendBroadcast = (Button)findViewById(R.id.broadcast);  
            mSendStickyBroadcast = (Button)findViewById(R.id.sticky_broadcast);  
            mNextActivity = (Button)findViewById(R.id.next_activity);  
              
            mSendBroadcast.setOnClickListener(new OnClickListener() {  
               @Override  
               public void onClick(View v) {  
                    Intent intent = new Intent("com.android.action.broadcast");  
                    mContext.sendBroadcast(intent);  
               }  
              });  
              
            mSendStickyBroadcast.setOnClickListener(new OnClickListener() {  
               @Override  
               public void onClick(View v) {  
                    mStickyBrcCount++;  
                    Intent intent = new Intent("com.android.action.sticky.broadcast");  
                    intent.putExtra("sent_count", mStickyBrcCount);  
                    mContext.sendStickyBroadcast(intent);  
               }  
              });    
            mNextActivity.setOnClickListener(new OnClickListener() {  
                   @Override  
                   public void onClick(View v) {  
                        Intent intent = new Intent(MainActivity.this, ReceiverActivity.class);  
                        startActivity(intent);     
                   }  
              });  
        }  
      
         @Override  
         protected void onResume() {  
              super.onResume();  
              Log.d("main", "------------------onResume");
              mStickyBrcCount = 0;  
         }  
         
    }  

    2.接收类

    public class ReceiverActivity extends Activity {  
          
         private IntentFilter mIntentFilter;  
         private final static String TAG = "ReceiverActivity";  
         
            @Override  
            public void onCreate(Bundle savedInstanceState) {  
                super.onCreate(savedInstanceState);  
                setContentView(R.layout.sub);  
                  
                mIntentFilter = new IntentFilter();     
                mIntentFilter.addAction("com.android.action.broadcast");     
                mIntentFilter.addAction("com.android.action.sticky.broadcast");     
          
            }  
               
          
         @Override  
         protected void onPause() {  
           super.onPause();  
           unregisterReceiver(mReceiver);     
          
         }   
          
         @Override  
         protected void onResume() {  
           super.onResume();  
           registerReceiver(mReceiver, mIntentFilter);   
         }  
         
         private BroadcastReceiver  mReceiver = new BroadcastReceiver () {  
              @Override  
              public void onReceive(Context context, Intent intent) {  
                   final String action = intent.getAction();  
                   int count = intent.getIntExtra("sent_count", -1);  
                   Log.d(TAG, "-------   action = " + action + "and count = " + count);  
                   removeStickyBroadcast(intent);   
              }  
         };  
             
    }  
  • 相关阅读:
    ACdream 1114(莫比乌斯反演)
    ACdream 1148(莫比乌斯反演+分块)
    bzoj2301(莫比乌斯反演+分块)
    hdu1695(莫比乌斯反演)
    hdu4908(中位数)
    bzoj1497(最小割)
    hdu3605(最大流+状态压缩)
    【Leetcode】Add Two Numbers
    【Leetcode】Add Binary
    【Leetcode】Single Number II
  • 原文地址:https://www.cnblogs.com/yuyutianxia/p/3514214.html
Copyright © 2011-2022 走看看