gpt4 book ai didi

java - 持有唤醒锁并调用 startForeground 后服务被终止

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:55:27 29 4
gpt4 key购买 nike

我遇到了一个问题,即使我持有唤醒锁并且调用了 startForeground,我的服务还是被终止了。当平板电脑 (ASUS Transformer TF101) 发生这种情况时,停止服务而不调用 onDestroy。没有其他可见的应用程序,log cat 没有显示任何异常(没有“内存不足”消息等)。服务被杀死后立即重启。

我正在开发的应用程序是一个聊天客户端,需要持续连接,它也是基于插件的,所以我的应用程序是这样开发的:客户端 - 主机服务 - 多个子“服务”。

粘性主机服务持有唤醒锁并调用 startForeground(并显示通知),子服务不粘性,不持有唤醒锁并且是后台服务。

如果客户端本身是打开的,问题就不会发生,但我要使用的模型是用户可以使用设备并保持连接(接收消息等),而无需客户端本身始终处于打开状态。

任何人都可以解释为什么服务会以这种方式被杀死,如果是的话,可以阻止它发生吗?正如聊天客户端在用户登录和注销时显示的那样,服务终止会终止所有打开的连接,这会使聊天客户端“弹跳”。目前,它似乎每 15 到 45 分钟发生一次。

此外,如果有人知道有一种方法可以在整个连接期间保持套接字连接持续打开而无需持有唤醒锁,我很想听听!

主机服务源的修剪测试用例版本如下。

public class HostService extends Service
{
PowerManager m_powerManager = null;
PowerManager.WakeLock m_wakeLock = null;

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

@Override
public void onCreate()
{
super.onCreate();
}

@Override
public void onDestroy()
{
if( m_wakeLock != null )
{
m_wakeLock.release();
m_wakeLock = null;
}

stopForeground( true );

super.onDestroy();
}

@Override
public int onStartCommand( Intent intent, int flags, int startId )
{
// Display a notification about us starting. We put an icon in the
// status bar.
Notification notification = createNotification();

startForeground( R.string.service_running, notification );

if( m_powerManager == null )
{
m_powerManager = (PowerManager)getSystemService(Context.POWER_SERVICE);
}

if( m_wakeLock == null )
{
m_wakeLock = m_powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Keep background services running");
m_wakeLock.acquire();
}

// We want this service to continue running until it is explicitly
// stopped, so return sticky.
return START_STICKY;
}

/**
* Create a notification to show the service is running
*/
private Notification createNotification()
{
CharSequence text = getText( R.string.service_running );
CharSequence title = getText( R.string.app_name );

// The PendingIntent to launch our activity if the user selects this
// notification
PendingIntent contentIntent = PendingIntent.getActivity( this, 0, new Intent(this, MainChat.class) , 0 );

Notification notification = new Notification( android.R.drawable.sym_action_chat, title, System.currentTimeMillis() );
notification.setLatestEventInfo( this, title, text, contentIntent );

return notification;
}

private final IMessageInterface.Stub m_serviceImplementation = new IMessageInterface.Stub()
{
...
};
}

Android list (相关位):

<uses-sdk android:minSdkVersion="11" android:targetSdkVersion="11" />

<service android:name="com.mydomain.chatClient.server.HostService" android:exported="true" android:enabled="true" android:process=":remote"/>

<uses-permission android:name="android.permission.WAKE_LOCK" />

最佳答案

I am having a problem where my service is being killed even though I am holding a wake lock and I have called startForeground.

startForeground()降低了服务被杀死的可能性,但并不能阻止它。

The app I am developing is a chat client and needs a constant connection, it is also plugin based, so my app is developed as such: Client - HostService - Multiple child 'Services'.

我建议去掉其中一层。即使操作系统没有关闭您,许多用户也会(例如,任务 killer 、设置中的运行服务)认为您运行了太多服务。

If the client itself is open the issue does not occur, but the model I am going for is that the user can use the device and stay connected (receiving messages etc) without having the client itself open at all times.

我建议将其设为可选。你可能认为它很性感。您的一些用户会攻击您,因为您浪费了他们的电池。

Can anybody offer any explanation as to why the service is being killed in this way, and if so prevent it from happening?

我将从摆脱 android:process=":remote" 开始.你不需要它。你不想要它。你可能会因为拥有它而伤害自己,因为它可能会加速 Android 摆脱你的服务的兴趣。你拥有它绝对是在伤害用户,因为你在无缘无故地浪费 RAM。

然后,如果您将这些插件实现为单独的应用程序,我将摆脱这些插件。在那种情况下,它们中的每一个都将在自己的进程中运行,从而浪费更多的 RAM。此外,您当前的实现会有缺陷,因为您将无法将服务命名为 com.mydomain.chatClient.server.HostService。直到时间结束,因为你没有使用 <intent-filter>将“服务在内部命名的内容”和“其他希望使用它的单独安装的应用程序调用的服务”的关注点分开。如果您没有将插件实现为单独的应用程序,那么我看不到将它们放在单独的服务中而不是将它们全部折叠到一个服务中的值(value)。

Also, if anybody is aware of a way to keep a socket connection open continuously without holding a wake lock for the entire connection duration, I would love to hear it!

如果套接字是无线数据而不是 WiFi,则不需要 WakeLock每时每刻。套接字将保持打开状态,该套接字上的传入数据包将唤醒您的代码。在这一点上,你想要捕获一个 WakeLock足够长的时间让你在数据到达时做任何你正在做的事情,然后释放 WakeLock .

但是,如果您使用的是 WiFi,这个技巧就不起作用,所以 WakeLock (可能需要一个 WifiLock )。

关于java - 持有唤醒锁并调用 startForeground 后服务被终止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6317696/

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