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
?不需要ResultReceiver
、CREATOR
等(如果你看一下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:exported 需要为 <service> 显式指定。面向 Android 12 的应用