在Android

时间:2015-11-05 02:09:28

标签: android android-service background-service android-intentservice

我的服务具有可变的生命周期。它可以执行5分钟到2小时(例如)。所以我正在寻找最好的方法,我的服务必须达到以下特点:

  • 每隔5秒向我的服务器发送一次lat-long和一些额外信息(stringbooleanint

我尝试过“正常”服务,并尝试做这样的事情来实现这个目标:

public class MyFiveSecondsService extends Service {
    private Handler handler;
    Runnable r = new Runnable() {
        @Override
        public void run() {
            //here send my new data
        }
    };

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

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if(handler == null){
            handler = new Handler();
        }

        handler.post(r);

        return super.onStartCommand(intent, flags, startId);
    }
}

实际上代码有效,但我在使用这种方法时遇到了一些性能问题,所以我试着这样做:

public class SendUniquePositionIntentService extends IntentService {

    public SendUniquePositionIntentService() {
        super("co.bomboapp.Service.IntentService.SendUniquePositionIntentService");
    }

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

    @Override
    protected void onHandleIntent(Intent intent) {
        //do the logic here
    }
}

public class MyFiveSecondsService extends Service {
    private Handler handler;
    Runnable r = new Runnable() {
        @Override
        public void run() {
            //call my SendUniquePositionIntentService here
        }
    };

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

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if(handler == null){
            handler = new Handler();
        }

        handler.post(r);

        return super.onStartCommand(intent, flags, startId);
    }
}

当我关闭应用程序时,任何服务都继续运行,这种方法都没有用。所以在开始任何其他尝试实现这一目标之前,我想要一些方向,这种“无限循环服务”的最佳方法是什么并保持性能?

我使用Android 4.1作为分钟API,并定位5.0 API。 我的测试设备是Nexus 5正在运行Android 6。 现在我正在使用parse.com作为数据库。

1 个答案:

答案 0 :(得分:3)

"我已经尝试了#34;正常"服务...但我遇到了一些性能问题"

默认情况下,服务在应用程序的主线程上运行,因此当您使用

创建处理程序时
public int onStartCommand(Intent intent, int flags, int startId) {
    if(handler == null){
        handler = new Handler();
    }
    ...
}

处理程序与主线程Looper相关联,并且所有消息和runnable都被传递并随后在线程上执行。这就是"性能问题" 的原因。来自documentation

  

请记住,如果您使用某项服务,默认情况下它仍会在您的应用程序的主要主题中运行...

关于第二种方法和部分

" ...当我关闭应用时,任何服务一直在运行"

你还没有提到你是如何关闭"关闭"应用程序,但我能看到的是

public int onStartCommand(Intent intent, int flags, int startId) {
    ...
    return super.onStartCommand(intent, flags, startId);
}

表示如果系统终止服务,则默认情况下将重新创建该服务。所以如果"关闭"你的应用意味着杀死它,发生以下行动:

  1. 系统会重新创建MyFiveSecondsService
  2. 调用
  3. onStartCommand()并且处理程序发布可运行的
  4. run()方法SendUniquePositionIntentService内启动
  5. 来自onStartCommand()的文档:

      

    默认实现调用onStart(Intent,int)并返回START_STICKY或START_STICKY_COMPATIBILITY。

    请注意,除非您打算这样做,否则从另一个服务启动服务(例如从您的案例中的SendUniquePositionIntentService开始)是多余的。

    你问题的最后部分让我感到困惑。一方面它不适合你,因为" ...任何服务一直在运行" 但另一方面,你喜欢 "执行此操作"无限循环服务"" ......?

    如果您只需要向服务器发送"字符串,布尔值和内注" 等信息(对启动该服务的组件没有任何反馈),我认为& #39; s足以让你使用IntentService。这是一个开箱即用的#34;在后台线程上执行其工作的框架(让您避免冻结主线程)并在完成后自行停止。例如,您可以使用IntentService上的文档 - 它写得很好。

    另请注意,系统杀死服务后服务的行为取决于MyFiveSecondsService返回的标志。例如。使用START_NOT_STICKY在销毁应用后不重新创建服务,或START_REDELIVER_INTENT使用最后onStartCommand()重新传递来重新创建服务。