Android Service为IntentService扩展ResultReceiver,CREATOR如何实现?

Posted

技术标签:

【中文标题】Android Service为IntentService扩展ResultReceiver,CREATOR如何实现?【英文标题】:Android Service extends ResultReceiver for IntentService, how to implement CREATOR? 【发布时间】:2016-02-26 15:11:16 【问题描述】:

我的应用依赖Service,它在后台与外部硬件保持同步。因为服务在 main 线程上运行,所以它使用 IntentService 异步执行任何繁重的工作。这是解释控制流的代码的最小化示例:

public class MyService extends Service 
  private final Handler handler = new Handler();

  void someMethodDoesCallBarAsynchronously()
    Intent i = new Intent(this, MyIntentService.class);
    i.putAction(ACTION_FOO);
    i.putExtra(EXTRA_RECEIVER, new MyResultReceiver(handler));
    startService(toGetScannerStatus);
  

  void receivedFooResult(String bar)
    //...
  

  public class MyResultReceiver extends ResultReceiver

    public MyResultReceiver(Handler handler)
      super(handler);
    

    @Override
    protected void onReceiveResult(int resultCode, Bundle resultData) 
      super.onReceiveResult(resultCode, resultData);

      switch(resultCode)
        case RESULT_CODE_FOO:
          receivedFooResult(resultData.getString(FOO_RESULT));
        break;
      
    
  


public class MyIntentService extends IntentService 

  public MyIntentService()super("MyIntentService");

  @Override
  protected void onHandleIntent(Intent intent) 
    switch (intent.getAction()) 
      case ACTION_FOO:
        ResultReceiver receiver = intent.getParcelableExtra(EXTRA_RECEIVER);
        Bundle bundle = new Bundle()
        bundle.putString(FOO_RESULT, foo());
        receiver.send(RESULT_CODE_FOO, b);
      break;
  

现在,经过半年和一些更新,android Studio 抱怨MyResultReceiver 实现了 Parcelable 但没有提供 CREATOR 字段。问题一,MyResultReceiver 是一个内部类,所以我必须把它放到一个自己的类中。我无法将其设为static,因为它必须包含对 MyService 的引用。这仍然很容易:

public class MyService extends Service 
  private final Handler handler = new Handler();

  void someMethodDoesCallBarAsynchronously()
    Intent i = new Intent(this, MyIntentService.class);
    i.putAction(ACTION_FOO);
    i.putExtra(EXTRA_RECEIVER, new MyResultReceiver(this, handler));
    startService(toGetScannerStatus);
  

  void receivedFooResult(String bar)
    //...
  


public class MyResultReceiver extends ResultReceiver
  private final MyService myService;

  public MyResultReceiver(MyService s, Handler handler)
    super(handler);
    this.myService = myService;
  

  @Override
  protected void onReceiveResult(int resultCode, Bundle resultData) 
    super.onReceiveResult(resultCode, resultData);

    switch(resultCode)
      case RESULT_CODE_FOO:
        myService.receivedFooResult(resultData.getString(FOO_RESULT));
      break;
    
  

现在我可以添加一个公共静态字段。但是如何正确实现CREATOR?

public class MyResultReceiver extends ResultReceiver 

  public static final Parcelable.Creator<MyResultReceiver> CREATOR
    = new Parcelable.Creator<MyResultReceiver>() 
        public MyResultReceiver[] newArray(int size) 
          return new MyResultReceiver[size];
        
        public MyResultReceiver createFromParcel(Parcel in) 
          // ???
        
      ;

如果您想:为什么需要这样做?它将用于什么?

【问题讨论】:

为什么?你需要MyIntentService 做什么?为什么不在HandlerThread 里面MyService 里面做一个heavy work?不需要ResultReceiverCREATOR 等(如果你看一下IntentService,你会发现它里面只有HandlerThread 为什么?因为这是我让所有事情按照我想要的方式工作的第一种方式。这是工作应用程序的现有设计,它是大型、经过测试和生产的,并且不能轻易更改。 (上面sn-p只是为了演示控制流。)Android框架提供了IntentService类和ResultReceiver。所以问题是如何以合理的方式使用它们。我以为我已经理解了,见上文,但新要求不适合。那么,如果服务想要将工作加载到 IntentService 并通过 ResultsReceiver 接收结果,那么设计的意图是什么? 尝试@SuppressLint("ParcelCreator") class MyResultReceiver extends ResultReceiver ...,但认真考虑简化架构(没有两个服务) @psklink 也许你会回答这个问题? 【参考方案1】:

恕我直言,您当前的架构太复杂了:您可以轻松地在一个 Service 中做到这一点,但是当涉及到您的问题时,这取决于您:您不需要创建任何 CREATOR是一个 lint 警告,只需像这样添加 SuppressLint 注释:

@SuppressLint("ParcelCreator")
public class MyResultReceiver extends ResultReceiver 

【讨论】:

以上是关于Android Service为IntentService扩展ResultReceiver,CREATOR如何实现?的主要内容,如果未能解决你的问题,请参考以下文章

FirebaseMessagingService 无法转换为 android.app.Service

Android基础:Service —— 默默为你服务

android:exported 需要为 <service> 显式指定。面向 Android 12 的应用

Android学习笔记之Service

Android Service为IntentService扩展ResultReceiver,CREATOR如何实现?

Android----service