【问题标题】:Background service confusion后台服务混乱
【发布时间】:2016-05-03 16:39:20
【问题描述】:

我正在尝试了解如何在启动应用程序关闭后保持 Android 服务运行。我已经尝试查看后台服务的示例(例如this 一个,以及 Xamarin 站点上的一些),但在每种情况下,如果最小化的应用程序从屏幕上“滑出”,服务就会停止运行。我不希望服务像这样意外停止,它应该持续运行,直到请求确认停止。该服务不会消耗太多资源,只是获取一个 GPS 位置并每 2 分钟将其发布到一个网站。

作为背景,我是 Xamarin/Android 的新手,但过去使用 C# 在 Windows 中创建了几个成功的服务

稍后) 我尝试的一个示例确实在正在运行的应用程序的设置列表中留下了一项,但一旦滑出屏幕,实际上并没有执行任何服务任务。此外,状态栏中没有图标。在做了一些阅读之后,似乎我的 androidmanifest 文件缺少一个“服务”属性(尽管我尝试过的样本都没有这个);我现在尝试的是这个

    <service
      android:name=".LocationService"
      android:icon="@drawable/icon"
      android:label="@string/service_name"
    >
    <intent-filter>
      <action android:name="android.service.LocationService" />
      <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
    </service>

...但仍然没有运气。

【问题讨论】:

    标签: xamarin xamarin.android


    【解决方案1】:

    您是否看过 Xamarin 示例 here 来源是 here

    他们创建了这样的服务:

    [Service]
    public class SimpleService : Service
    {
        System.Threading.Timer _timer;
        
        public override StartCommandResult OnStartCommand (Android.Content.Intent intent, StartCommandFlags flags, int startId)
        {
                Log.Debug ("SimpleService", "SimpleService started");
    
                DoStuff ();
    
                return StartCommandResult.Sticky;
        }
        
        public override void OnDestroy ()
        {
            base.OnDestroy ();
            
            _timer.Dispose ();
            
            Log.Debug ("SimpleService", "SimpleService stopped");       
        }
    
        public void DoStuff ()
        {
            _timer = new System.Threading.Timer ((o) => {
                Log.Debug ("SimpleService", "hello from simple service");}
            , null, 0, 4000);
        }
    
        public override Android.OS.IBinder OnBind (Android.Content.Intent intent)
        {
            throw new NotImplementedException ();
        }
    }
    

    并以此开始和停止它:

    StartService (new Intent (this, typeof(SimpleService)));
    StopService (new Intent (this, typeof(SimpleService)));
    

    听起来你还想要一个 Sticky 服务Docs

    当系统面临内存压力时,Android 可能会停止任何正在运行的服务。此规则的例外是显式在前台启动的服务,本文稍后将对此进行讨论。

    当系统停止服务时,Android 将使用从 OnStartCommand 返回的值来确定服务应该如何或是否应该重新启动。该值的类型为 StartCommandResult,可以是以下任意一种:

    • Sticky – 将重新启动粘性服务,并且在重新启动时将空意图传递给 OnStartCommand。当服务持续执行长时间运行的操作时使用,例如更新股票 Feed。
    • RedeliverIntent – 服务重新启动,并且在服务被系统停止之前传递给 OnStartCommand 的最后一个意图被重新传递。用于继续执行长时间运行的命令,例如完成大文件上传。
    • NotSticky – 服务不会自动重启。
    • StickyCompatibility - 在 API 级别 5 或更高级别上,重新启动的行为类似于 Sticky,但在早期版本中会降级为级别 5 之前的行为。

    希望这会有所帮助。

    【讨论】:

    • 我之前没有尝试过那个特定的示例,但现在有,并且结果相同,即当 UI 应用程序关闭时服务停止。 (我不得不重写 Timer() 调用,因为根据示例我的 Xamarin 安装不支持它,但这不应该影响服务)。据我所知,“粘性”属性只影响系统停止的服务,而不影响用户从屏幕上滑出的应用程序。
    • 啊,好吧,我正在研究这个 developer.android.com/reference/android/app/… 可能是您正在寻找的更多内容
    • 感谢您的建议:尝试了第二个示例,结果相同(您建议的第一个示例是 Java,我不确定如何转换);但是这个link 示例似乎继续作为服务运行——我需要做更多的测试才能确定......
    • 是的,很抱歉第一个只是一个参考,所以我可以在 Xamarin 中查找该属性。很高兴您找到了适合您需求的样品!
    【解决方案2】:

    现在解决了。混淆主要是由于许多示例已过时(使用不推荐使用的方法)以及对“纯”Android 项目和 Xamarin 项目的不同建议。当然不需要按照我上面的建议修改 androidmanifest 文件。

    如果有人想找到类似的东西,我的项目是here

    当然,解决最初的问题现在提出了一些新问题,但如果需要,我会单独发布。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-11-25
      • 2021-07-26
      • 1970-01-01
      • 1970-01-01
      • 2011-02-07
      • 1970-01-01
      • 2016-06-30
      • 2013-02-22
      相关资源
      最近更新 更多