Android_ basic components _BroadcastReceiver

I. Overview

BroadcastReceiver a broadcast receiver to receive broadcast information sent from a system or application and the corresponding processing logic.

Custom BroadcastReceiver just inherited android.content.BroadcastReceiver, and rewrite onReceive () method on it.

public class StaticBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        //TODO
    }
}

 

Second, the basic usage

1.BroadcastReceiver registration:

BroadcastReceiver There are two registration methods, static registration and dynamic registration, the following were explained.

(1) Static registration

By <receiver> tag register the broadcast, that is, registered in AndroidManifest.xml static. After the broadcast static registration, after the system starts, it has been resident in system memory, receiving broadcast information in line, regardless of whether the application is running.

So its advantages are permanent system, run time, without affecting applications and other components of the life cycle; drawback is the permanent memory consumption. More suitable for real-time monitoring of the scene.

/ * 
Android: Meaning attributes exported with other components of the same, if there is false, other components not accepted the broadcast, receiving the broadcast locally applied only
* /
<receiver android:name=".StaticBroadcastReceiver"
            android:enabled="true"
            android:exported="true">
    <intent-filter>
        <action android:name="com.flx.testBroadcastReceiver.TEST_BROADCAST_RECEIVER"></action>
    </intent-filter>
</receiver>

Sign up broadcast reception class static broadcast.

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;

public class StaticBroadcastReceiver extends BroadcastReceiver {
    final private static String TAG = "StaticBroadcastReceiver";
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.d(TAG, "onReceive: "+intent.getStringExtra("testkey"));
    }
}

Send broadcast:

Button sendBroadcastBtn = findViewById(R.id.send_broadcast_btn);
sendBroadcastBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("StaticBroadcastReceiver", "click");
Intent broadcastIntent = new Intent();
broadcastIntent.setAction("com.flx.testBroadcastReceiver.TEST_BROADCAST_RECEIVER");
broadcastIntent.putExtra("testkey", "testval");
sendBroadcast(broadcastIntent);
}
});

But  by log and found that the receiver does not receive broadcast StaticBroadcastReceiver, this is how it happened? Look log, being given as follows:

2019-07-31 03:17:50.978 883-922/system_process W/BroadcastQueue: Background execution not allowed: receiving Intent 
{ act=com.flx.testBroadcastReceiver.TEST_BROADCAST_RECEIVER flg=0x10 (has extras) } to com.flx.testBroadcastReceiver/.StaticBroadcastReceiver

Because the debugging on P, O system after implicit broadcast (broadcast receiving not specified components) have been restricted, it can not receive. There are some online about how to get around this limitation can make static registration received implicit broadcast, but did not find particularly good, if not necessary, nor do they need to do so. Custom assembly of the broadcast information is generally known target receiver or the like, and the dynamic register (talk later) is not restricted to this .

官网上说明:
Android 8.0 Beginning with Android 8.0 (API level 26), the system imposes additional restrictions on manifest-declared receivers. If your app targets Android 8.0 or higher, you cannot use the manifest to declare a receiver for most implicit broadcasts
(broadcasts that don't target your app specifically). You can still use a context-registered receiver when the user is actively using your app.

Implicit here is not a broadcast transmission can be received.

        Button sendBroadcastBtn = findViewById(R.id.send_broadcast_btn);
        sendBroadcastBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.d("StaticBroadcastReceiver", "click");
                Intent broadcastIntent = new Intent();
                broadcastIntent.setAction("com.flx.testBroadcastReceiver.TEST_BROADCAST_RECEIVER");
                broadcastIntent.putExtra("testkey", "testval");
            broadcastIntent.setPackage("com.flx.testBroadcastReceiver");
                sendBroadcast(broadcastIntent);
            }
        });
31/07/2019 03: 46: 21336-21336 24 810 / com.flx.testBroadcastReceiver D / StaticBroadcastReceiver: click 
31/07/2019 03: 46: 21336-21336 24 857 / com.flx.testBroadcastReceiver D / StaticBroadcastReceiver: OnReceive: testVal

(2) dynamically register

Dynamic registration, needs to be registered by registerReceiver (BroadcastReceiver receiver, IntentFilter filter) in the code. Only after the broadcast receiver () registered by registerReceiver, can receive broadcast processing.

Dynamic registration without restriction implicit broadcast.

Dynamic registration broadcast by unregisterReceiver (BroadcastReceiver receiver) to destroy, otherwise it will error.

Dynamic non-resident registration system, the affected component life cycle for listening broadcast at a particular time scene.

Dynamic Broadcast Receiver

public class DanymicBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.d("flx_broadcast", "DanymicBroadcastReceiver onReceive: " + intent.getStringExtra("testkey"));
    }
}

Dynamic registration and destruction

import android.app.Activity;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;

public class MainActivity extends Activity {
final private String TEST_ACTION = "com.flx.testBroadcastReceiver.TEST_BROADCAST_RECEIVER";
private DanymicBroadcastReceiver mDanymicBroadcastReceiver = new DanymicBroadcastReceiver();

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

Button sendBroadcastBtn = findViewById(R.id.send_broadcast_btn);
sendBroadcastBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("flx_broadcast", "click");
Intent broadcastIntent = new Intent();
broadcastIntent.setAction(TEST_ACTION);
broadcastIntent.putExtra("testkey", "testval");
// broadcastIntent.setPackage("com.flx.testBroadcastReceiver");
sendBroadcast(broadcastIntent);
}
});

IntentFilter intentFilter = new IntentFilter(TEST_ACTION);
registerReceiver(mDanymicBroadcastReceiver, intentFilter);
}

@Override
protected void onDestroy() {
unregisterReceiver(mDanymicBroadcastReceiver);
super.onDestroy();
}
}

 2. Other Precautions

Broadcasting also has a limited time of ANR, 10s . In the 10s onReceive () If you still have not been processed, will be reported ANR. So for the time-consuming operation, you can start other components or services are processed through intent.

 

Third, an orderly broadcast

The above mentioned basic usage is common in broadcasting. Certain scenarios, the need to use broadcast orderly, and orderly broadcast can set a good precedence, followed by treatment. Can pass parameters may interrupt handling operation subsequent broadcast receiver.

important point:

1. Priority setting: static registration by <intent-filter android: priority = ""> set, dynamic registration by intentFilter1.setPriority (100). Priority values ​​range from -1000 to 1000.

setPriority
Added in API level 1
fun setPriority(priority: Int): Unit
Modify priority of this filter. This only affects receiver filters. The priority of activity filters are set in XML and cannot be changed programmatically. 
The default priority is 0. Positive values will be before the default, lower values will be after it. Applications should use a value that
is larger than SYSTEM_LOW_PRIORITY and smaller than SYSTEM_HIGH_PRIORITY . SYSTEM_LOW_PRIORITY Value: -1000 SYSTEM_HIGH_PRIORITY Value: 1000

2. Ordered broadcast data can be transferred to the low-priority broadcast receiver may also terminate propagation. The following examples are related operations.

The main code is as follows:

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;

public class MainActivity extends Activity {
    final private String TEST_ACTION = "com.flx.testBroadcastReceiver.TEST_BROADCAST_RECEIVER";
    private MyBroadcast1 mMyBroadcast1  =  new MyBroadcast1();
    private MyBroadcast2 mMyBroadcast2  =  new MyBroadcast2();
    private MyBroadcast3 mMyBroadcast3  =  new MyBroadcast3();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button sendBroadcastBtn = findViewById(R.id.send_broadcast_btn);
        sendBroadcastBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.d("flx_broadcast", "click");
                Intent broadcastIntent = new Intent();
                broadcastIntent.setAction(TEST_ACTION);
                broadcastIntent.putExtra("testkey", "testval");
//                broadcastIntent.setPackage("com.flx.testBroadcastReceiver");
//                sendBroadcast(broadcastIntent);
                sendOrderedBroadcast(broadcastIntent, null);
            }
        });

        IntentFilter intentFilter1 = new IntentFilter(TEST_ACTION);
        intentFilter1.setPriority ( 100 ); 
        receiver register (mMyBroadcast1, intentFilter1); 

        Intent Filter intentFilter2 = new Intent filter (TEST_ACTION); 
        intentFilter2.setPriority ( 200 ); 
        receiver register (mMyBroadcast2, intentFilter2); 

        Intent Filter intentFilter3 = new Intent filter (TEST_ACTION); 
        intentFilter3.setPriority ( 300 ); 
        receiver register (mMyBroadcast3, intentFilter3); 
    } 

    @Override 
    protected  void onde troy () { 
        unregisterReceiver (mMyBroadcast1);
        unregisterReceiver(mMyBroadcast2);
        unregisterReceiver(mMyBroadcast3);
        super.onDestroy();
    }

    public class MyBroadcast1 extends BroadcastReceiver{
        @Override
        public void onReceive(Context context, Intent intent) {
            Log.d("flx_broadcast", "MyBroadcast1 onReceive:" );
        }
    }

    public class MyBroadcast2 extends BroadcastReceiver{
        @Override
        public void onReceive(Context context, Intent intent) {
            Log.d("flx_broadcast", "MyBroadcast2 onReceive:"+getResultData());
            abortBroadcast();
        }
    }

    public class MyBroadcast3 extends BroadcastReceiver{
        @Override
        public void onReceive(Context context, Intent intent) {
            setResultData("MyBroadcast3 set string is aaaa");
            Log.d("flx_broadcast", "MyBroadcast3 onReceive:" );
        }
    }
}

Click here to print out the log as follows:

2019-07-31 05:17:27.459 26243-26243/com.flx.testBroadcastReceiver D/flx_broadcast: click
2019-07-31 05:17:27.486 26243-26243/com.flx.testBroadcastReceiver D/flx_broadcast: MyBroadcast3 onReceive:
2019-07-31 05:17:27.495 26243-26243/com.flx.testBroadcastReceiver D/flx_broadcast: MyBroadcast2 onReceive:MyBroadcast3 set string is aaaa

300 MyBroadcast3 set the highest priority, followed by MyBroadcast2 200, MyBroadcast1 100. Since MyBroadcast3 by setResultData () spread data is provided MyBroadcast2, MyBroadcast2 in abortBroadcast () to stop the spread. So log above.

 

The setResultData () and abortBroadcast () later commented , completely in accordance with the priority has performed. log below.

2019-07-31 05:23:15.840 26634-26634/com.flx.testBroadcastReceiver D/flx_broadcast: click
2019-07-31 05:23:15.872 26634-26634/com.flx.testBroadcastReceiver D/flx_broadcast: MyBroadcast3 onReceive:
2019-07-31 05:23:15.889 26634-26634/com.flx.testBroadcastReceiver D/flx_broadcast: MyBroadcast2 onReceive:null
2019-07-31 05:23:15.897 26634-26634/com.flx.testBroadcastReceiver D/flx_broadcast: MyBroadcast1 onReceive:

 

Guess you like

Origin www.cnblogs.com/fanglongxiang/p/11281466.html