Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Broadcasts are delayed

We use broadcasts to communicate state changes between a remote services and our UI. Doing this, we discovered a very strange behaviour: Sometimes (I can not find any clues why) these broadcasts are delayed around 8s.

How we send them (pretty basic, mState is just a enum) (Remote process in service):

Intent intent = new Intent();
intent.setAction(ACTION_STATE_CHANGED);
intent.putExtra(EXTRA_STATE, mState);

Service.get().sendBroadcast(intent, null);

How the static receiver is registered (App):

<receiver android:name=".ServiceStateReceiver">
    <intent-filter>
        <action android:name="service.intent.action.STATE_CHANGE" />
    </intent-filter>
</receiver>

The receiver class (App):

public class ServiceStateReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.v("State", "State via static received");
    }
}

This is now sometimes delayed (always for the same states)

State enum:

public enum State {
    DISCONNECTED,
    BT_DISABLED,
    BT_SCANNING,
    BT_TIMEOUT,
    BT_FAILURE,
    BT_LOCATION_NEEDED,
    CONNECTING,
    ACTIVATION_FAILURE,
    VIN_NEEDED,
    CAR_MODEL_NEEDED,
    MILEAGE_NEEDED,
    READY,
    IGNITION_OFF,
    IGNITION_ON;

    @Override
    public String toString() {
        return name();
    }
}

Now comes the strange part: If I register a dynamic receiver we always receive ALL broadcasts immediately there. The static one still has that huge delay. If I send the broadcast via sendOrderedBroadcast BOTH (static & dynamic) have this delay.

Dynamic receiver:

registerReceiver(new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                Log.i("State", "State via dynamic received");
            }
        }, new IntentFilter(State.ACTION_STATE_CHANGED));

What I tried so far:

  • send the broadcast from the main thread/a worker thread (nothing changed)
  • played with the permission attribute (nothing changed)
  • send the broadcast multiple times in a row (not changing anything, just getting multiple delayed broadcasts now)

Also: No output from logcat which seems related. Tried on different devices (OnePlus 3 7.1.1, Z3 6.0.1, S7 Edge 7.1.1), all show the same behaviour

I think this may be related: Android network state change detection takes time

like image 517
Mike Kasperlik Avatar asked Jun 13 '17 08:06

Mike Kasperlik


1 Answers

After searching for a answer for hours, I found the? solution after posting this.

It seems like that adding the FLAG_RECEIVER_FOREGROUND flag to the intent completly removes this delay. Would be still nice to know why this happens and if this is a good "fix" or if I destroy something else with this.

This does the trick:

    intent.setFlags(FLAG_RECEIVER_FOREGROUND);

If set, when sending a broadcast the recipient is allowed to run at foreground priority, with a shorter timeout interval. During normal broadcasts the receivers are not automatically hoisted out of the background priority class.

Source: https://developer.android.com/reference/android/content/Intent.html#FLAG_RECEIVER_FOREGROUND

like image 161
Mike Kasperlik Avatar answered Sep 21 '22 20:09

Mike Kasperlik