Android广播--官方文档(你确定完全懂了Broadcasts)

Broadcasts

Android apps can send or receive broadcast messages from the Android system and other Android apps, similar to the publish-subscribe design pattern. These broadcasts are sent when an event of interest occurs. For example, the Android system sends broadcasts when various system events occur, such as when the system boots up or the device starts charging. Apps can also send custom broadcasts, for example, to notify other apps of something that they might be interested in (for example, some new data has been downloaded).
Android应用可以从Android系统和其他Android应用发送或接收广播消息,类似于发布 - 订阅设计模式。当感兴趣的事件发生时,这些广播被发送。例如,当各种系统事件发生时,例如系统启动或设备开始充电时,Android系统发送广播。应用程序还可以发送自定义广播,例如,通知其他应用程序可能感兴趣的内容(例如,一些新数据已被下载)。

Apps can register to receive specific broadcasts. When a broadcast is sent, the system automatically routes broadcasts to apps that have subscribed to receive that particular type of broadcast.
应用程序可以注册以接收特定的广播。当发送广播时,系统自动将广播 路由到已订阅该类型的广播的应用。

Generally speaking, broadcasts can be used as a messaging system across apps and outside of the normal user flow. However, you must be careful not to abuse the opportunity to respond to broadcasts and run jobs in the background that can contribute to a slow system performance, as described in the following video.

System broadcasts

The system automatically sends broadcasts when various system events occur, such as when the system switches in and out of airplane mode. System broadcasts are sent to all apps that are subscribed to receive the event.
当系统发生各种系统事件时,系统会自动发送广播,例如系统切换到飞行模式时。系统广播将发送到已订阅该事件的所有应用程序。
The broadcast message itself is wrapped in an Intent object whose action string identifies the event that occurred (for example android.intent.action.AIRPLANE_MODE). The intent may also include additional information bundled into its extra field. For example, the airplane mode intent includes a boolean extra that indicates whether or not Airplane Mode is on.
广播消息本身被包装在Intent对象中,其action字符串标识发生的事件(例如android.intent.action.AIRPLANE_MODE)。Intent还可能包含捆绑到其额外字段中的附加信息。例如,飞行模式Intent包括一个布尔值,用来表示飞行模式是否打开。

For more information about how to read intents and get the action string from an intent, see Intents and Intent Filters.
有关如何读取intents并从intents获取操作字符串的更多信息,请参阅intents和intent filters。

For a complete list of system broadcast actions, see the BROADCAST_ACTIONS.TXT file in the Android SDK. Each broadcast action has a constant field associated with it. For example, the value of the constant ACTION_AIRPLANE_MODE_CHANGED is android.intent.action.AIRPLANE_MODE. Documentation for each broadcast action is available in its associated constant field.
有关系统广播操作的完整列表,请参阅Android SDK中的BROADCAST_ACTIONS.TXT文件。每个广播动作都有一个与之相关联的常量字段。例如,常量ACTION_AIRPLANE_MODE_CHANGED的值是android.intent.action.AIRPLANE_MODE。

Changes to system broadcasts

Android 7.0 and higher no longer sends the following system broadcasts. This optimization affects all apps, not only those targeting Android 7.0.
Android 7.0及更高版本不再发送以下系统广播。此优化会影响所有应用,而不仅仅是针对Android 7.0的应用。

注意8.0又支持了下面的两个广播了,不过必须使用动态注册。

ACTION_NEW_PICTURE
ACTION_NEW_VIDEO

Apps targeting Android 7.0 (API level 24) and higher must register the following broadcasts with [registerReceiver(BroadcastReceiver, IntentFilter)](https://developer.android.com/reference/android/content/Context.html#registerReceiver(android.content.BroadcastReceiver, android.content.IntentFilter)). Declaring a receiver in the manifest does not work.
针对Android 7.0(API级别24)或更高版本的应用程序必须使用registerReceiver(BroadcastReceiver,IntentFilter)注册以下广播。在清单中声明的receiver 将不起作用。
CONNECTIVITY_ACTION

Beginning with Android 8.0 (API level 26), the system imposes additional restrictions on manifest-declared receivers. If your app targets API level 26 or higher, you cannot use the manifest to declare a receiver for most implicit broadcasts (broadcasts that do not target your app specifically).
从Android 8.0(API 26级)开始,系统对在清单文件中声明的接收器有了额外的限制。如果您的应用程序的目标API为26级或更高版本,则无法在清单文件中为绝大多数隐式广播(不针对你应用的本地广播)声明接收者。

Receiving broadcasts

Apps can receive broadcasts in two ways: through manifest-declared receivers and context-registered receivers.
应用有两种方式接收广播:静态注册和动态注册。

Manifest-declared receivers

If you declare a broadcast receiver in your manifest, the system launches your app (if the app is not already running) when the broadcast is sent.
如果你是静态注册,当接收到广播的时候,系统会唤醒你的应用。

Note: If your app targets API level 26 or higher, you cannot use the manifest to declare a receiver for implicit broadcasts (broadcasts that do not target your app specifically), except for a few implicit broadcasts that are exempted from that restriction. In most cases, you can use scheduled jobs instead.
如果您的应用程序针对26级或更高级别的API,则无法使用清单声明隐式广播的接收者(不针对本地广播),除了几个免除该限制的隐式广播。在大多数情况下,您可以使用scheduled jobs。

To declare a broadcast receiver in the manifest, perform the following steps:

  1. Specify the <receiver> element in your app's manifest.
<receiver android:name=".MyBroadcastReceiver"  android:exported="true">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED"/>
        <action android:name="android.intent.action.INPUT_METHOD_CHANGED" />
    </intent-filter>
</receiver>

The intent filters specify the broadcast actions your receiver subscribes to.

  1. Subclass BroadcastReceiver and implement [onReceive(Context, Intent)](https://developer.android.com/reference/android/content/BroadcastReceiver.html#onReceive(android.content.Context, android.content.Intent)). The broadcast receiver in the following example logs and displays the contents of the broadcast:
    一个继承BroadcastReceiver并且重写onReceive(Context, Intent).方法的子类。
public class MyBroadcastReceiver extends BroadcastReceiver {
    private static final String TAG = "MyBroadcastReceiver";
    @Override
    public void onReceive(Context context, Intent intent) {
        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);
        Toast.makeText(context, log, Toast.LENGTH_LONG).show();
    }
}

The system package manager registers the receiver when the app is installed. The receiver then becomes a separate entry point into your app which means that the system can start the app and deliver the broadcast if the app is not currently running.
当应用程序安装成功后系统软件包管理器就会注册接收器。然后,接收器将成为您的应用程序的单独入口点,这意味着即使应用程序当前没有处于运行状态,系统也可以启动应用程序并传送广播。

The system creates a new BroadcastReceiver component object to handle each broadcast that it receives. This object is valid only for the duration of the call to [onReceive(Context, Intent)](https://developer.android.com/reference/android/content/BroadcastReceiver.html#onReceive(android.content.Context, android.content.Intent)). Once your code returns from this method, the system considers the component no longer active.
系统会创建一个新的BroadcastReceiver组件对象来处理它接收的每个广播。此对象仅在调用onReceive(Context,Intent)的持续时间内有效。一旦您的代码从此方法返回,系统将认为该组件对象不再有效。

Context-registered receivers

  1. To register a receiver with a context, perform the following steps:
    Create an instance of BroadcastReceiver.
    BroadcastReceiver br = new MyBroadcastReceiver();
    创建一个BroadcastReceiver实例。
  2. Create an IntentFilter and register the receiver by calling [registerReceiver(BroadcastReceiver, IntentFilter)](https://developer.android.com/reference/android/content/Context.html#registerReceiver(android.content.BroadcastReceiver, android.content.IntentFilter)):
IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
intentFilter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
this.registerReceiver(br, filter);

Note: To register for local broadcasts, call [LocalBroadcastManager.registerReceiver(BroadcastReceiver, IntentFilter)](https://developer.android.com/reference/android/support/v4/content/LocalBroadcastManager.html#registerReceiver(android.content.BroadcastReceiver, android.content.IntentFilter)) instead.
注意:请使用LocalBroadcastManager.registerReceiver(BroadcastReceiver, IntentFilter)方法注册本地广播。

Context-registered receivers receive broadcasts as long as their registering context is valid. For an example, if you register within an Activity context, you receive broadcasts as long as the activity is not destroyed. If you register with the Application context, you receive broadcasts as long as the app is running.

只要其注册时的context 有效就会一直接收广播。例如,如果您在Activity中注册,只要Activity未被销毁,就能接收广播。如果您使用应用程序上下文注册,只要应用程序正在运行,您就一直能接收到广播。

  1. To stop receiving broadcasts, call unregisterReceiver(android.content.BroadcastReceiver). Be sure to unregister the receiver when you no longer need it or the context is no longer valid.
    调用[unregisterReceiver(android.content.BroadcastReceiver)]停止接收广播。(https://developer.android.com/reference/android/content/Context.html#unregisterReceiver(android.content.BroadcastReceiver))。当您不再需要它或context不再有效时,请务必注销接收器。
    Be mindful of where you register and unregister the receiver, for example, if you register a receiver in onCreate(Bundle) using the activity's context, you should unregister it in onDestroy() to prevent leaking the receiver out of the activity context. If you register a receiver in onResume(), you should unregister it in onPause() to prevent registering it multiple times (If you don't want to receive broadcasts when paused, and this can cut down on unnecessary system overhead). Do not unregister in onSaveInstanceState(Bundle), because this isn't called if the user moves back in the history stack.
    注意注册和注销接收者的时机,例如,如果您使用Activity作为上下文,在onCreate(Bundle)中注册了一个接收者,那么您应该在onDestroy()中注销它,以防止将接收者从Activity上下文中泄漏。如果您在onResume()中注册了一个接收器,您应该在onPause()中注销它,以防多次注册(如果您不想在onPause时接收广播,这样还可以减少不必要的系统开销)。不要在onSaveInstanceState(Bundle)中取消注册,因为该方法不一定会被回调。

Effects on process state

The state of your BroadcastReceiver (whether it is running or not) affects the state of its containing process, which can in turn affect its likelihood of being killed by the system. For example, when a process executes a receiver (that is, currently running the code in its onReceive() method), it is considered to be a foreground process. The system keeps the process running except under cases of extreme memory pressure.
BroadcastReceiver的状态(无论是否运行)会影响其所在进程的状态,从而影响该进程被系统杀死的可能性。例如,某个进程执行一个receiver 操作(onReceive()方法中的代码)时,它被认为是一个前台进程。系统保持进程运行,除非是内存极端吃紧的情况下,不然该进程是不会被杀死的。
However, once your code returns from onReceive(), the BroadcastReceiver is no longer active. The receiver's host process becomes only as important as the other app components that are running in it. If that process hosts only a manifest-declared receiver (a common case for apps that the user has never or not recently interacted with), then upon returning from onReceive(), the system considers its process to be a low-priority process and may kill it to make resources available for other more important processes.
然而,一旦你的代码从onReceive()返回,BroadcastReceiver就不再活跃了。其所在的进程的等级就和app中其他组件的等级一样了。如果该进程仅托管清单文件中声明的接收者(尤其是那些用户有一段时间没有使用的App),则在从onReceive()返回时,系统将该进程视为低优先级进程,并且可能杀死它以使资源可用于其他更重要的进程。

For this reason, you should not start long running background threads from a broadcast receiver. After onReceive(), the system can kill the process at any time to reclaim memory, and in doing so, it terminates the spawned thread running in the process. To avoid this, you should either call goAsync() (if you want a little more time to process the broadcast in a background thread) or schedule a JobService from the receiver using the JobScheduler, so the system knows that the process continues to perform active work. For more information, see Processes and Application Life Cycle.
因此,您不应该在广播接收器中启动长时间运行的后台线程。在onReceive()之后,系统可以随时杀死进程以回收内存,这样做会终止在进程中生成并正在运行的线程。为避免这种情况,您应该调用goAsync()(如果您希望在后台线程中多一些时间来处理广播)或使用JobScheduler从接收方调度JobService,则系统会知道该进程需要继续进行运行。有关更多信息,请参阅Processes and Application Life Cycle。

The following snippet shows a BroadcastReceiver that uses goAsync() to flag that it needs more time to finish after onReceive() is complete. This is especially useful if the work you want to complete in your onReceive() is long enough to cause the UI thread to miss a frame (>16ms), making it better suited for a background thread.
以下片段显示了BroadcastReceiver,它使用goAsync()来标记在onReceive()完成后需要更多时间来完成工作。如果您要在onReceive()中完成的工作足够长,导致UI线程错过了一帧(> 16ms),这种情况更适合使用后台线程,这一点尤其有用。

public class MyBroadcastReceiver extends BroadcastReceiver {
    private static final String TAG = "MyBroadcastReceiver";

    @Override
    public void onReceive(final Context context, final Intent intent) {
        final PendingResult pendingResult = goAsync();
        AsyncTask<String, Integer, String> asyncTask = new AsyncTask<String, Integer, String>() {
            @Override
            protected String doInBackground(String... params) {
                StringBuilder sb = new StringBuilder();
                sb.append("Action: " + intent.getAction() + "\n");
                sb.append("URI: " + intent.toUri(Intent.URI_INTENT_SCHEME).toString() + "\n");
                Log.d(TAG, log);
                // Must call finish() so the BroadcastReceiver can be recycled.
                pendingResult.finish();
                return data;
            }
        };
        asyncTask.execute();
    }
}

Sending broadcasts

Android provides three ways for apps to send broadcast:
Android为应用发送广播提供了三种方式:

  • The [sendOrderedBroadcast(Intent, String)](https://developer.android.com/reference/android/content/Context.html#sendOrderedBroadcast(android.content.Intent, java.lang.String)) method sends broadcasts to one receiver at a time. As each receiver executes in turn, it can propagate a result to the next receiver, or it can completely abort the broadcast so that it won't be passed to other receivers. The order receivers run in can be controlled with the android:priority attribute of the matching intent-filter; receivers with the same priority will be run in an arbitrary order.

sendOrderedBroadcast(Intent,String)方法 每次向一个接收方发送广播。随着每个接收机依次执行,它可以将结果传播到下一个接收器,或者它可以完全中止广播,使得它不会被传递到其他接收器。接收器的运行顺序可以通过设置ntent-filter中的android:priority属性进行控制;具有相同优先级的接收器将以任意顺序运行。

  • The endBroadcast(Intent) method sends broadcasts to all receivers in an undefined order. This is called a Normal Broadcast. This is more efficient, but means that receivers cannot read results from other receivers, propagate data received from the broadcast, or abort the broadcast.
    sendBroadcast(Intent)方法以未定义的顺序向所有接收者发送广播。这被称为普通广播。这更有效率,但是意味着一个接收器不能从另一个接收器读取结果,传递从广播接收的数据,或者中止广播
  • The LocalBroadcastManager.sendBroadcast method sends broadcasts to receivers that are in the same app as the sender. If you don't need to send broadcasts across apps, use local broadcasts. The implementation is much more efficient (no interprocess communication needed) and you don't need to worry about any security issues related to other apps being able to receive or send your broadcasts.The following code snippet demonstrates how to send a broadcast by creating an Intent and calling sendBroadcast(Intent).

LocalBroadcastManager.sendBroadcast方法将广播发送到与发送方在同一个应用程序中的接收者。如果您不需要跨应用发送广播,请使用本地广播。实施效率更高(无需进行进程间通信),您无需担心接收到其他应用程序的广播或者发送广播到其他应用程序之类的安全问题。

Intent intent = new Intent();
intent.setAction("com.example.broadcast.MY_NOTIFICATION");
intent.putExtra("data","Notice me senpai!");
sendBroadcast(intent);

The broadcast message is wrapped in an Intent object. The intent's action string must provide the app's Java package name syntax and uniquely identify the broadcast event. You can attach additional information to the intent with putExtra(String, Bundle). You can also limit a broadcast to a set of apps in the same organization by calling setPackage(String) on the intent.
广播消息包装在Intent对象中。Intent的action字段必须设置为应用程序的Java全包名称,来标识广播事件的唯一性。您可以使用putExtra(String,Bundle)添加附加信息到Intent。您还可以通过对Intent对象调用setPackage(String)将广播限制在同一organization 中的一组应用程序。

Note: Although intents are used for both sending broadcasts and starting activities with startActivity(Intent), these actions are completely unrelated. Broadcast receivers can't see or capture intents used to start an activity; likewise, when you broadcast an intent, you can't find or start an activity.
注意:虽然internts即可以作为发送广播的参数也可以作为启动Activity的参数(使用startActivity(Intent)),但这些操作是完全不相关的。广播接收者无法查看或捕获用于start Activity的Intent;同样地,当您广播Intent时,您无法通过该intent找到或启动一个Activity

Restricting broadcasts with permissions

Permissions allow you to restrict broadcasts to the set of apps that hold certain permissions. You can enforce restrictions on either the sender or receiver of a broadcast.
权限允许您将广播限制在拥有某些权限的一组应用程序。您可以对广播的发送者或接收者强制执行限制

Sending with permissions

When you call [sendBroadcast(Intent, String)](https://developer.android.com/reference/android/content/Context.html#sendBroadcast(android.content.Intent, java.lang.String)) or [sendOrderedBroadcast(Intent, String, BroadcastReceiver, Handler, int, String, Bundle)](https://developer.android.com/reference/android/content/Context.html#sendOrderedBroadcast(android.content.Intent, java.lang.String, android.content.BroadcastReceiver, android.os.Handler, int, java.lang.String, android.os.Bundle)), you can specify a permission parameter. Only receivers who have requested that permission with the tag in their manifest (and subsequently been granted the permission if it is dangerous) can receive the broadcast. For example, the following code sends a broadcast:
当您调用sendBroadcast(Intent,String)或sendOrderedBroadcast(Intent,String,BroadcastReceiver,Handler,int,String,Bundle)时,可以指定权限参数。只有接收者已经在其清单中请求了该权限(并且随后被许可,如果它是危险的权限)才可以接收广播。例如,以下代码发送广播:
sendBroadcast(new Intent("com.example.NOTIFY"),Manifest.permission.SEND_SMS);
To receive the broadcast, the receiving app must request the permission as shown below:
要接收广播,接收应用程序必须如下所示请求权限:
<uses-permission android:name="android.permission.SEND_SMS"/>
You can specify either an existing system permission like SEND_SMS or define a custom permission with the <permission> element. For information on permissions and security in general, see the System Permissions.
您可以指定现有系统权限(如SEND_SMS)或使用<permission>元素定义自定义权限。有关权限和安全性的信息,请参阅系统权限。

Note: Custom permissions are registered when the app is installed. The app that defines the custom permission must be installed before the app that uses it.

Receiving with permissions

If you specify a permission parameter when registering a broadcast receiver (either with [registerReceiver(BroadcastReceiver, IntentFilter, String, Handler)](https://developer.android.com/reference/android/content/Context.html#registerReceiver(android.content.BroadcastReceiver, android.content.IntentFilter, java.lang.String, android.os.Handler)) or in <receiver> tag in your manifest), then only broadcasters who have requested the permission with the<uses-permission>tag in their manifest (and subsequently been granted the permission if it is dangerous) can send an Intent to the receiver.
如果在注册广播接收者(或者通过registerReceiver(BroadcastReceiver,IntentFilter,String,Handler)或者清单中的<receiver>标签)中指定权限参数时,则只有使用<uses-permission>标签在其清单中请求了(并且随后被许可,如果权限属于危险权限)的broadcasters 才可以向接收者发送意图。

For example, assume your receiving app has a manifest-declared receiver as shown below:

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

Or your receiving app has a context-registered receiver as shown below:
或者你的应用使用以下方式进行了动态注册。

IntentFilter filter = new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED);
registerReceiver(receiver, filter, Manifest.permission.SEND_SMS, null );

Then, to be able to send broadcasts to those receivers, the sending app must request the permission as shown below:
然后,为了能够向这些接收者发送广播,发送应用程序必须如下所示请求许可:
<uses-permission android:name="android.permission.SEND_SMS"/>

Security considerations and best practices

Here are some security considerations and best practices for sending and receiving broadcasts:
以下是发送和接收广播的一些安全注意事项和最佳做法:

  • If you don't need to send broadcasts to components outside of your app, then send and receive local broadcasts with the LocalBroadcastManager which is available in the Support Library. The LocalBroadcastManager is much more efficient (no interprocess communication needed) and allows you to avoid thinking about any security issues related to other apps being able to receive or send your broadcasts. Local Broadcasts can be used as a general purpose pub/sub event bus in your app without any overheads of system wide broadcasts.
    如果您不需要将广播发送到应用程序之外的组件,则可以通过支持库中提供的LocalBroadcastManager发送和接收本地广播。 LocalBroadcastManager效率更高(无需进行进程间通信),并允许您避免考虑与其他可以接收或发送广播的应用程序相关的任何安全问题。本地广播可以用作应用程序中的通用发布/接收事件总线,而无需系统广播的任何开销。
  • If many apps have registered to receive the same broadcast in their manifest, it can cause the system to launch a lot of apps, causing a substantial impact on both device performance and user experience. To avoid this, prefer using context registration over manifest declaration. Sometimes, the Android system itself enforces the use of context-registered receivers. For example, the CONNECTIVITY_ACTION broadcast is delivered only to context-registered receivers.
    如果许多应用程序已注册在其清单中接收相同的广播,则可能导致系统启动大量应用程序,从而对设备性能和用户体验产生重大影响。为了避免这种情况,优先使用动态注册。有时,Android系统本身强制使用动态。例如,CONNECTIVITY_ACTION广播仅传递给动态注册的接收者。
  • Do not broadcast sensitive information using an implicit intent. The information can be read by any app that registers to receive the broadcast. There are three ways to control who can receive your broadcasts:
    不要使用隐含意图广播敏感信息。任何注册接收广播的应用都可以读取信息。有三种方法可以控制谁可以接收您的广播:
    • You can specify a permission when sending a broadcast.
      您可以在发送广播时指定权限。
    • In Android 4.0 and higher, you can specify a package with setPackage(String) when sending a broadcast. The system restricts the broadcast to the set of apps that match the package.
      在Android 4.0及更高版本中,您可以在发送广播时使用setPackage(String)指定包。系统将广播限制到与包相匹配的一组应用程序。
    • You can send local broadcasts with LocalBroadcastManager.
      使用本地广播
  • When you register a receiver, any app can send potentially malicious broadcasts to your app's receiver. There are three ways to limit the broadcasts that your app receives:
    当您注册接收者时,任何应用都可能会将恶意广播发送到您的应用的接收者。有三种方法来限制您的应用收到的广播:
    • You can specify a permission when registering a broadcast receiver.
      注册广播接收者时可以指定一个权限。
    • For manifest-declared receivers, you can set the android:exported attribute to "false" in the manifest. The receiver does not receive broadcasts from sources outside of the app.
      对于清单声明的接收器,您可以在清单中将android:exports属性设置为“false”。接收器不会从应用程序之外的来源接收广播。
    • You can limit yourself to only local broadcasts with LocalBroadcastManager.
      可以限制自己只使用本地广播。
  • The namespace for broadcast actions is global. Make sure that action names and other strings are written in a namespace you own, or else you may inadvertently conflict with other apps.
    广播动作的命名空间是全局的。确保操作名称和其他字符串写在您拥有的命名空间中,否则您可能会无意中与其他应用程序冲突。
  • Because a receiver's onReceive(Context, Intent) method runs on the main thread, it should execute and return quickly. If you need to perform long running work, be careful about spawning threads or starting background services because the system can kill the entire process after onReceive() returns. For more information, see Effect on process state To perform long running work, we recommend:
    因为接收者的onReceive(Context,Intent)方法在主线程上运行,所以它应该快速执行并返回。如果您需要执行长时间的工作,请注意生成线程或启动后台服务,因为系统可以在onReceive()返回后终止整个进程。有关详细信息,请参阅对Effect on process state来执行一个长时间任务,我们建议:
    • Calling goAsync() in your receiver's onReceive() method and passing the BroadcastReceiver.PendingResult to a background thread. This keeps the broadcast active after returning from onReceive(). However, even with this approach the system expects you to finish with the broadcast very quickly (under 10 seconds). It does allow you to move work to another thread to avoid glitching the main thread.
      在接收器的onReceive()方法中调用goAsync(),并将BroadcastReceiver.PendingResult传递给后台线程。这样可以在从onReceive()返回后保持广播有效。然而,即使使用这种方法,系统也希望您可以快速完成播放(10秒以下)。它允许您将工作移动到另一个线程,以避免阻塞主线程。
    • Scheduling a job with the JobScheduler. For more information, see Intelligent Job Scheduling.
      使用JobScheduler来调度一个job。有关详细信息,请参阅Intelligent Job Scheduling。
  • Do not start activities from broadcast receivers because the user experience is jarring; especially if there is more than one receiver. Instead, consider displaying a notification.
    不要从广播接收机开始活动,特别是如果有多个接收器的情况下,用户体验会很震撼。相反,请考虑显示一个通知。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容

  • 1.广播的分类 (1)按照发送的方式分类 标准广播是一种异步的方式来进行传播的,广播发出去之后,所有的广播接收者几...
    曹丰斌阅读 33,936评论 0 22
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,566评论 25 707
  • 本人初学Android,最近做了一个实现安卓简单音乐播放功能的播放器,收获不少,于是便记录下来自己的思路与知识总结...
    落日柳风阅读 18,802评论 2 41
  • 诸多无奈,最近在改一个项目的bug的时候,脑子老是一片空白,可能是最近脑子不够用,总之,好多东西忘了,阅读一些别人...
    狗子王1948阅读 7,626评论 6 53
  • 有万千思绪却不足以表达,从学校的无知到社会的无奈,从那时无话不说到此时不安忐忑, 第一次恋爱是在初二时,她是那...
    A不负勇往阅读 269评论 0 8