【问题标题】:How to do (or avoid) permanently running services in android apps?如何在 Android 应用程序中做(或避免)永久运行的服务?
【发布时间】:2013-12-24 00:00:09
【问题描述】:

这个问题是在如何编写好程序的哲学问题与如何保护电池和系统资源的基于事实的问题之间的一种平衡行为。具体来说,它是关于 Android 服务,为了执行所需的任务,必须在手机的后台永久运行。

在我的情况下,我有几个服务在后台运行。一个扫描手机是否连接到 WiFi,如果是,设置一个变量,一个检查位置并在找到足够精确的位置时更新位置,一个检查接近传感器,一个分析噪音水平,打开检查 RSS-Feed 是否有更新...

该应用程序有几个问题,我认为它们可能源于这个设计决定。大多数情况下,(除了通过 SensorEventListener 提供更新的位置服务和接近传感器)我所有服务的架构都是这样的

public class ArchetypicalService extends Service
{
Checker checker;

public SharedPreferences prefs;
public final static String PREFS = Constants.PREFS;

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

@Override
public void onCreate() 
{
    prefs = getSharedPreferences(PREFS, 0);
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) 
{
    checker = new Checker();
    checker.run();
    return START_STICKY;
}

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

private class Checker implements Runnable
{
    private Handler handler = new Handler();
    public static final int checkingDelay = 1000; // this number varies depending on what purpose this service has
    @Override
    public void run() 
    {
        //what happends here depends on what the service does
        handler.postDelayed(this, checkingDelay);
    }
}
}

服务在应用启动时启动。像这样:

Intent intent = new Intent(this,ArchetypicalService.class);
startService(intent);

感谢 START_STICKY,即使我们停止活动,该服务也会继续运行。当我写这一切时,这一切对我来说似乎是教科书,但我使用 android 工作的次数越多,我遇到的博客条目就越多,这些条目告诉我不应该实现永久运行的服务。它们不仅是糟糕的风格,还使应用程序更有可能崩溃并耗尽电池和手机资源。这可能是正确的:我的应用程序经常崩溃并耗尽电池。

所以,我的问题是:如果一个功能,比如传感器扫描或检查互联网上的数据,必须在后台定期完成,即使所有活动都已关闭,有没有更好的方法来实现它?(虽然我欢迎所有答案或想法,但我更欢迎那些提供一些有用示例代码的人)

【问题讨论】:

    标签: android android-service


    【解决方案1】:

    如果一个功能,如传感器扫描或检查互联网上的数据,必须在后台定期完成,即使所有活动都已关闭,有没有更好的方法来实现它?

    使用AlarmManager 安排定期进行的工作。

    例如,以“检查 RSS-Feed 的更新”为例。将服务保留在内存中,玩弄它的虚拟拇指,等待时间过去,直到再次检查 RSS 提要,这对您来说是荒谬的。在其他平台上,您可以使用 cron 或 Windows 计划任务之类的东西——在 Android 上,相当于 AlarmManager

    几乎任何情况下,流程是“做工作,等待某个固定时间段,完成工作,等待某个固定时间段,......”应该使用AlarmManagerIntentService 来实现,后者为您提供后台线程并在工作完成时自动关闭。这样,您只有在主动向用户提供价值时才会消耗 RAM。

    【讨论】:

      【解决方案2】:

      http://developer.android.com/guide/components/services.html。服务不创建单独的线程。如果它是一个长时间运行的操作,你需要在线程中运行它们。因此,如果有很多服务,那么在主 ui 线程上运行所有内容都会消耗内存。确保在线程中运行。可能会解决您的应用程序崩溃问题。另请检查此链接。 How can I keep requesting a page every 5 seconds and not kill the battery?.

      【讨论】:

      • 好的。我会试试的。似乎很容易替换 checker = new Checker(); checker.run();使用线程 t = new Thread(checker = new Checker()); t.start();
      • 这将需要一些时间(可能是几天)来评估性能并查看崩溃是否像迄今为止那样频繁发生。我会在这里发布结果。
      • 他们再也不会回来了^
      • @Deminetix 什么?我不明白
      猜你喜欢
      • 2017-05-29
      • 2017-04-04
      • 1970-01-01
      • 2012-09-23
      • 1970-01-01
      • 1970-01-01
      • 2018-12-02
      • 1970-01-01
      相关资源
      最近更新 更多