gpt4 book ai didi

android - Context.startForegroundService 然后没有调用 Service.startForeground : Alternative solution

转载 作者:行者123 更新时间:2023-12-04 23:45:30 26 4
gpt4 key购买 nike

注意:这个问题假设您知道将服务绑定(bind)到上下文。

制作中的每个人都知道这个问题,甚至一些拥有 Android Oreo 或 Pie 设备的用户都知道。异常如下所示:

Fatal Exception: android.app.RemoteServiceException: Context.startForegroundService() did not then call Service.startForeground()
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1792)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6523)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:857)

当您调用 Context.startForegroundService(Intent)您还必须调用 Service.startForeground(int, Notification) 5秒内 (即使您的手机甚至可能无法启动您的服务,但由于某种原因它成为您的错)或者您的应用程序将卡住或从 Android 框架抛出异常。经过进一步思考,我制定了一个解决方案。

由于 Context.startForegroundService(Intent)不保证该服务将在 5 秒内创建并且是一个异步操作,我认为这样会发生一些事情:
// Starts service.
public static void startService(Context context)
{
// If the context is null, bail.
if (context == null)
return;

// This is the same as checking Build.VERSION.SDK_INT >= Build.VERSION_CODES_O
if (Utilities.ATLEAST_OREO)
{
Log.w(TAG, "startForegroundService");

// Create the service connection.
ServiceConnection connection = new ServiceConnection()
{
@Override
public void onServiceConnected(ComponentName name, IBinder service)
{
// The binder of the service that
// returns the instance that is created.
MyService.LocalBinder binder = (MyService.LocalBinder) service;

// The getter method to acquire the service.
MyService myService = binder.getService();

// getServiceIntent(context) returns the relative service intent.
context.startForegroundService(getServiceIntent(context));

// This is the key: Without waiting Android Framework
// to call this method inside Service.onCreate(),
// immediately call here to post the notification.
// MyService.createNotification(context) is static
// for other purposes.
myService.startForeground(19982, MyService.createNotification(context));

// Release the connection to prevent leaks.
context.unbindService(this);
}

@Override
public void onServiceDisconnected(ComponentName name)
{

}
};

// Try to bind the service.
try
{
context.bindService(getServiceIntent(context), connection, Context.BIND_AUTO_CREATE);
}
catch (RuntimeException ignored)
{
// This is probably a broadcast receiver context
// even though we are calling getApplicationContext().
// Just call startForegroundService instead
// since we cannot bind a service to a
// broadcast receiver context.
// The service also have to call startForeground in this case.
context.startForegroundService(getServiceIntent(context));
}
}
else
{
// Normal stuff below API 26.
Log.w(TAG, "startService");
context.startService(getServiceIntent(context));
}
}

从启动服务的 Activity 调用此函数。有趣的是: 它可以工作并且不会引发异常。 我已经在模拟器上进行了测试,我的设备也是 Oreo,我想确认这是防止这种异常发生的最佳方法。

我的问题是:这是实际创建前台服务的好方法吗?有什么想法吗?谢谢您的意见。

最佳答案

根据codelab ,它看起来像是在 Android 9.0+ 上实现前台服务的正确方法

关于android - Context.startForegroundService 然后没有调用 Service.startForeground : Alternative solution,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55906296/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com