LocalBroadcastManager 现已弃用,如何将数据从服务发送到活动?

lok*_*oki 10 java android broadcastreceiver android-service localbroadcastmanager

我有一项服务需要通知主要活动。我用过LocalBroadcastManager,效果很好,但是LocalBroadcastManager已被弃用。

这是我在服务中的实际代码:

public void onTokenRefresh() {
      
    /* build the intent */
    Intent intent = new Intent(ACTION_TOKENREFRESHED);
    intent.putExtra("token", "xxx");
    
    /* send the data to registered receivers */
    try{
      LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
    } catch (Throwable e){
      //no exception handling
    }  
  
  }
Run Code Online (Sandbox Code Playgroud)

在主要活动中,我收到如下通知:

context.registerReceiver(broadcastReceiver, intentFilter);
Run Code Online (Sandbox Code Playgroud)

我现在可以使用什么来删除已弃用的警告?我发现的有关从服务向活动发送数据的所有示例都使用 LocalBroadcastManager。有人可以给我一个可行的模型来迁移现有代码吗?

笔记

在我的示例中, TheonTokenRefresh是从 a 内部调用的background thread。这非常重要,因为这意味着我可以同时接收多个 onTokenRefresh,并且我必须将所有这些令牌转发到该活动。大多数提供的解决方案都使用实时数据,但做出如下声明:

public static final MutableLiveData<String> tokenLiveData = new MutableLiveData<>();

Background Thread1:
tokenLiveData.postValue(Token1);

Background Thread2 (at same time):
tokenLiveData.postValue(Token2);
Run Code Online (Sandbox Code Playgroud)

是否会将同时收到的所有代币转发到观察代币LiveData 的主要活动?主 Activity 一定会收到 token1 和 token2 吗?

Squ*_*uti 5

创建一个service类并定义 aLiveData来替换LocalBroadcastManager职责,如下所示:

//This service sends an example token ten times to its observers
public class MyService extends Service {
    //Define a LiveData to observe in activity
    public static final MutableLiveData<String> tokenLiveData = new MutableLiveData<>();

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        //You need a separate thread if you don not use IntentService

        Thread thread1 = new Thread() {
            public void run() {
                for (int i = 0; i < 10; i++) {
                    //send random strings az an example token ten times.
                    //You can remove this loop and replace it with your logic
                    String token1 = UUID.randomUUID().toString();
                    new Handler(Looper.getMainLooper()).post(() -> sendTokenToObserver("Thread1: " + token1));

                }
            }
        };
        thread1.start();

        Thread thread2 = new Thread() {
            public void run() {
                for (int i = 0; i < 10; i++) {
                    String token2 = UUID.randomUUID().toString();
                    new Handler(Looper.getMainLooper()).post(() -> sendTokenToObserver("Thread2: " + token2));
                }
            }
        };
        thread2.start();
        return START_STICKY;
    }

    //Post token to observers
    public void sendTokenToObserver(String token) {
        tokenLiveData.setValue(token);

    }
}
Run Code Online (Sandbox Code Playgroud)

然后启动serviceactivity观察LiveData如下所示:

public class MainActivity extends AppCompatActivity {

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

        //You can observe the emitted token here and do what you want(Show in view or notification). 
        //I've just logged it to the console.
        startService(new Intent(this,MyService.class));
        MyService.tokenLiveData.observe(this, token -> Log.d("token", token));
    }
}
Run Code Online (Sandbox Code Playgroud)

您还可以在中观察start它;serviceanother activityMainActivity

  • 静态数据很容易出错,尤其是对于测试而言。如果您使用“静态”数据,最好将其移至您的应用程序类。 (2认同)
  • 您听说过 Kotlin 和 Flows 吗? (2认同)