3

这个问题是在如何编写好程序的更哲学问题与如何保护电池和系统资源的基于事实的问题之间的一种平衡行为。具体来说,它与 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 工作的次数越多,我遇到的博客条目就越多,这些博客条目告诉我不应该实现永久运行的服务。它们不仅是糟糕的风格,还使应用程序更有可能崩溃并耗尽电池和手机资源。这可能是对的:我的应用程序经常崩溃并耗尽电池。

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

4

2 回答 2

4

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

用于AlarmManager安排工作定期发生。

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

几乎所有流程是“做工作,等待某个固定时间段,完成工作,等待某个固定时间段,......”的情况都应该使用AlarmManagerand来实现IntentService,后者给你一个后台线程并自动工作完成后关闭。这样,您只有在主动向用户交付价值时才会消耗 RAM。

于 2012-10-17T12:41:03.047 回答
1

http://developer.android.com/guide/components/services.html。服务不创建单独的线程。如果它是一个长时间运行的操作,你需要在线程中运行它们。因此,如果有很多服务,那么在主 ui 线程上运行所有内容都会消耗内存。确保在线程中运行。可能会解决您的应用程序崩溃问题。另请检查此链接。我怎样才能保持每 5 秒请求一个页面而不耗尽电池?.

于 2012-10-17T11:23:48.317 回答