Android four major components: BroadcastReceiver Introduction

Introduction

BroadcastReceiver that is broadcast component, it is one of the four components of Android. And monitor for receiving a broadcast message, and respond . There are some applications:

  • Communication between the different components (different between applications or within applications).
  • Communication between multiple threads.
  • Communicate with the system under certain circumstances (e.g., when the incoming call, the network and available).

principle

Android uses a broadcast mechanism in the observer design pattern: based on dissemination of information, subscribe event model . Thus, the sender and receiver of the broadcast decoupled, so that easy integration system, easier to expand.

There are three role models:

  • Messaging subscriber (radio receiver)
  • Post Owner (broadcast sender)
  • Message Center ActivityManagerService( )

The entire model as follows:

  1. Radio receivers by Binder mechanism Sign up for broadcast in the AMS.
  2. Broadcast sender sends the broadcast to the AMS by Binder mechanisms.
  3. According to AMS broadcast sender requirements (IntentFilter, Permission), find a suitable recipient in the registered list.
  4. AMS will be broadcast to an appropriate broadcast message recipient corresponding circular queue.
  5. Broadcast receivers can get broadcast message loop, and the callback onReceive()method.

    Note: Executing a broadcast sender and receiver are asynchronous, the sender does not care whether the recipient receives, can not determine when the recipient receives.

use

Step 1: Custom broadcast receiver

BroadcastReceiver base class inheritance, replication and abstract methodsonReceive() . By default, broadcast receivers running in the main thread, and therefore onReceive()the method can not perform time-consuming operation, otherwise block the main thread cause ANR problems.

BroadcastReceiver a target only be invoked onReceive()only valid when the object is returned from the method BroadcastReceiver ended the life cycle . In the onReceive()method, and it did not recommend the use of threads to perform time-consuming operation, because when an asynchronous operation to get additional results are returned, BroadcastReceiver may have ended the life cycle. If you really need, you can call a goAsync()method, and then open a new thread to execute, but still not recommended to perform over 10 seconds task. For time-consuming operation, it is preferably used startService()to complete.

// 继承 BroadcastReceiver 基类
public class TestBroadcastReceiver extends BroadcastReceiver {
    private static final String TAG = "TestBroadcastReceiver";

    // 复写 onReceive() 方法,接收到广播后,自动调用该方法
    @Override
    public void onReceive(Context context, Intent intent) {
        final PendingResult pendingResult = goAsync();
        Task asyncTask = new Task(pendingResult, intent);
        asyncTask.execute();
    }

    private static class Task extends AsyncTask<String, Integer, String> {

        private final PendingResult pendingResult;
        private final Intent intent;

        private Task(PendingResult pendingResult, Intent intent) {
            this.pendingResult = pendingResult;
            this.intent = intent;
        }

        @Override
        protected String doInBackground(String... strings) {
            StringBuilder sb = new StringBuilder();
            sb.append("Action: " + intent.getAction() + "\n");
            sb.append("URI: " + intent.toUri(Intent.URI_INTENT_SCHEME).toString() + "\n");
            String log = sb.toString();
            Log.d(TAG, log);
            return log;
        }

        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
            // Must call finish() so the BroadcastReceiver can be recycled.
            pendingResult.finish();
        }
    }
}

Step 2: Register broadcast receiver

Sign up way broadcast receiver divided into two types: static registration and dynamic registration.

Static registration

Static registration will always listen to the broadcast, resident in the system, is not affected by any component of the life cycle, but also power consumption, accounting for memory and other shortcomings.

Static registration broadcast receiver responsible for PMS, when the application is installed, PMS is responsible in a certain order catalog, scan all applications installed in the phone, and the application manifest file information about registering broadcast resolution stored.

Therefore, the method is static registration by the list of documents in AndroidManifest <receiver>label statement elements :

<receiver android:name=".TestBroadcastReceiver"
          android:permission="android.permission.SEND_SMS">
    <intent-filter>
        <action android:name="android.intent.action.AIRPLANE_MODE"/>
    </intent-filter>
</receiver>

Note: Because the system is installed in accordance with the application manifest file registration statements receivers, so the static registration of radio receivers, even if the application is not running, you can receive the broadcast.

However, Android 3.1 (API 12) start the two parameters in the system increases Intent Flag associated with the broadcast, to identify whether the packet contains stopped. No matter what type of broadcasting system, by default added value FLAG_EXCLUDE_STOPPED_PACKAGESFlag, and said they did not contain stop running packages.

Direct broadcast system is a system issue, you can not change this Flag value, even if the cause is still registered broadcast receivers, if they are in the process has exited, the same can not receive broadcasts.

The custom broadcast, you can modify this Flag is FLAG_INCLUDE_STOPPED_PACKAGESso static registration broadcast receivers, when the application is stopped can also receive broadcast and will start the application process.

Dynamic registration

Dynamic registration by AMS is in charge of, registered a more flexible way, you can follow the life cycle of components changes, you can listen to the broadcast at a particular period of time. Use is to call registerReceiver()method to register a broadcast receiver to listen, call the unregisterReceiver()method logout :

TestBroadcastReceiver testBroadcastReceiver = null;

@Override
protected void onResume() {
    super.onResume();

    // 1. 实例化 BroadcastReceiver 子类
    testBroadcastReceiver = new TestBroadcastReceiver();

    // 2. 实例化 IntentFilter,设置接收广播的类型
    IntentFilter intentFilter = new IntentFilter();
    intentFilter.addAction(android.net.conn.CONNECTIVITY_CHANGE);

    // 3. 动态注册:调用 Context的registerReceiver() 方法
    registerReceiver(testBroadcastReceiver, intentFilter);
}

@Override
protected void onPause() {
    super.onPause();

    // 注销在 onResume() 中注册的广播
    unregisterReceiver(testBroadcastReceiver);
}

Note: because they do not log out after dynamic broadcast registration lead to memory leaks, so the best way in the Activity life cycle in a few pairs of registration and deregistration. Activity is recommended onResume(), registered onPausein the write-off, as this may not be displayed in the foreground when Activity, stop listening, to reduce the overhead to run.

Note: If you use the latest version for Android, you need to pay attention to the behavior of the system broadcast several changes:

Android 7.0 (API 24) or higher , the system does not transmit ACTION_NEW_PICTUREand ACTION_NEW_VIDEObroadcast, and only dynamically registered broadcast receiver can receive CONNECTIVITY_ACTIONthe broadcast.

Android 8.0 (API 26) or later , the system still registered receivers imposes additional restrictions, not for the most implicit statement broadcast receiver, but can use the dynamic registration receiver.

Android 9 (API 28) or later , NETWORK_STATE_CHANGED_ACTIONthe broadcast will not receive information about the user's location or personally identifiable data. Since the broadcast system does not comprise Wi-Fi SSID, BSSID, connection information, or scans.

Step 3: broadcasting sender sends a broadcast to the AMS

Broadcast by the sender sendBroadcast()to send the package to the AMS broadcast Intent object method. Broadcast general is divided into the following five categories:

  • Normal Broadcast General broadcast
  • System Broadcast Broadcasting system
  • Ordered Broadcast Ordered Broadcast
  • Sticky Broadcast Sticky broadcast
  • Local Broadcast Local Broadcast

Normal broadcasting (Normal Broadcast)

Developers custom global broadcast of Intent. If the broadcast transmission requires the appropriate permissions, the broadcast receiver also requires the appropriate permissions. Transmitting broadcast as follows:

Intent intent = new Intent();
// 对应 BroadcastReceiver 中 IntentFilter 定义的 Action
intent.setAction(TEST_BROADCAST_ACTION);
sendBroadcast(intent);

Broadcasting System (System Broadcast)

Android system defines a number of built-in broadcasting, involves the basic operations of the mobile phone (e.g., power, network status change, pictures, etc.), the system will send a corresponding broadcast.

Each has a specific IntentFilter broadcast, when the broadcast system is used, only needs to, does not need to manually register the broadcast statement IntentFilter conditions associated with the receiver transmits a broadcast, the broadcast system will automatically performing related operations.

Ordered Broadcasting (Ordered Broadcast)

The broadcast receiver receives a broadcast in a certain order rules, to the broadcast receiver receiving a broadcast may be modified or truncated, then other received broadcast receiver, broadcast or terminated. Order rules are as follows:

  1. Descending order according to the priority attribute values.
  2. The priority attribute values ​​are the same, the broadcast receiver dynamically registered preference to static register.
  3. Static register the same priority receivers, high-scanned first priority.
  4. Dynamic registration of the receiver of the same priority, a high priority register.

    Note: Priority is also valid for disorderly broadcast, for disorderly broadcast: Dynamic registration priority higher than the static registration (ignoring priority). Registration same way high-priority attribute big priority. Under the same priority property values, high static scan register first priority, high dynamic registration to register priority.

And orderly broadcast transmitting general broadcast, but use the sendOrderedBroadcast()method of transmitting a broadcast in onReceive()by the setResultExtras()transfer to the next priority data receiver, by getResultExtras()extracted on a priority of data transmitted to the receiver by abortBroadcast()transmitting broadcast truncation.

By sendOrderedBroadcast()specifies the ending broadcast receiver ResultReceiver method. If it is higher than the priority of the broadcast receiver is not terminated, the final receiver receives the broadcast twice: the first time, according to the standard priority receive, the second, the broadcast receiving end. If it is higher than the priority of the receiver to terminate the broadcast, then it's just to receive a final broadcast.

Broadcast viscosity (Sticky Broadcast)

In Android 5.0 (API 21) or a later version has expired.

Local broadcast (Local Broadcast)

Because Android is broadcast across applications communicate directly, it may cause the following two questions:

  • Other applications IntentFilter issue with the current application that matches the broadcast, resulting in current applications continue to be received and processed some useless or even malicious broadcast.
  • Other applications currently registered with the consistent application of IntentFilter for receiving broadcast, resulting in the current application can intercept specific information broadcast, there are security issues.

Use local broadcast can effectively solve the above problems, improve safety and efficiency. There are two ways to use local broadcast:

The global broadcast to local broadcast
  1. When the broadcast receiver register exported property set to false, so that the broadcast receiving only the current issued by the application.
  2. When transmitting and receiving the broadcast, additional corresponding custom permission authority, authority for authentication.
  3. In Android 4.0 and later, when transmitting broadcast by the Intent setPackage()designated Method package name, the broadcast packet only to the designated matching broadcast receiver.
Use LocalBroadcastManager class

Similarly with the global broadcast use, is to use the difference between singleton LocalBroadcastManager to call registerReceiver()and unregisterReceiverto register and unregister broadcast receiver, calls sendBroadcast()transmitted broadcast.

// 注册应用内广播接收器
testBroadcastReceiver = new TestBroadcastReceiver(); 
IntentFilter intentFilter = new IntentFilter(); 
intentFilter.addAction(android.net.conn.CONNECTIVITY_CHANGE);
LocalBroadcastManager.getInstance(this).registerReceiver(testBroadcastReceiver, intentFilter);

// 注销应用内广播接收器
LocalBroadcastManager.getInstance(this).unregisterReceiver(testBroadcastReceiver);

// 发送应用内广播
Intent intent = new Intent();
intent.setAction(TEST_BROADCAST_ACTION);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);

other

For broadcast receiver different ways of registration, the callback onReceive(Context context, Intent intent)return value of the context is not the same:

  • Static Registration : context returns ReceiverRestrictedContext.
  • Dynamic registration of global broadcast : context returns Activity Context.
  • Dynamic registration of local broadcast : context returns Activity Context.
  • Dynamic registration of local broadcast (LocalBroadcastManager) : returns the context Application Context.

Guess you like

Origin www.cnblogs.com/theo/p/11414399.html