3

正在使用. _ _ Service因为我Service在登录后打电话给一个:

context.startService(new Intent(LoginActivity.this, CheckAutoSyncReceivingOrder.class));
context.startService(new Intent(LoginActivity.this, CheckAutoSyncSendingOrder.class));

我在上面都调用了一个计时器Service

CheckAutoSyncReceivingOrder 服务:

它每 1 分钟调用另一个名为ReceivingOrderService的服务以从服务器获取更新的数据。

public class CheckAutoSyncReceivingOrder extends Service {

    Timer timer;

    @Override
    public IBinder onBind(Intent arg0) {
        // TODO Auto-generated method stub
        Log.i(TAG, "CheckAutoSyncReceivingOrder Binding Service...");
        return null;
    }

    @Override
    public void onStart(Intent intent, int startId) {
        // TODO Auto-generated method stub

        if (timer != null) {
            timer.cancel();
            Log.i(TAG, "RECEIVING OLD TIMER CANCELLED>>>");
        }

        timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                Log.i(TAG, "<<<<<<<<< RECEIVING AUTO SYNC SERVICE <<<<<<<<");
                if (InternetConnection.checkConnection(getApplicationContext())) {
                    if (getDatabasePath(DatabaseHelper.DATABASE_NAME).exists())
                        startService(new Intent(
                                CheckAutoSyncReceivingOrder.this,
                                ReceivingOrderService.class));
                } else {
                    Log.d(TAG, "Connection not available");
                }
            }
        }, 0, 60000); // 1000*60 = 60000 = 1 minutes
    }

    @Override
    public void onDestroy() {
        // TODO Auto-generated method stub

        if (timer != null)
            timer.cancel();

        Log.d(TAG, "Stopping Receiving...");

        super.onDestroy();
    }
}

CheckAutoSyncSendingOrder 服务:

它每 2.5 分钟调用另一个名为SendingOrderService的服务将更新的数据发送到服务器。

public class CheckAutoSyncSendingOrder extends Service {

    Timer timer;

    @Override
    public void onStart(Intent intent, int startId) {
        // TODO Auto-generated method stub

        if (timer != null) {
            timer.cancel();
            Log.i(TAG, "OLD TIMER CANCELLED>>>");
        }

        timer = new Timer();

        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                Log.i(TAG, ">>>>>>>> SENDING AUTO SYNC SERVICE >>>>>>>>");
                if (InternetConnection.checkConnection(getApplicationContext())) {
                    if (getDatabasePath(DatabaseHelper.DATABASE_NAME).exists())
                        startService(new Intent(CheckAutoSyncSendingOrder.this,
                                SendingOrderService.class));
                } else {
                    Log.d(TAG, "connection not available");
                }
            }
        }, 0, 150000); // 1000*60 = 60000 = 1 minutes * 2.5 = 2.5 =>Minutes
    }

    @Override
    public void onDestroy() {
        // TODO Auto-generated method stub

        if (timer != null)
            timer.cancel();

        Log.d(TAG, "Stopping Sending...");

        super.onDestroy();
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        return null;
    }

这两个 Activity 将一直运行到 Internet 关闭。当 Internet 连接可用时,它将自动再次呼叫。

主要是我在自动销毁活动服务调用时遇到问题。

有什么解决方案或方法可以改变同一件事的流程吗?

提前谢谢你。

4

2 回答 2

2

文档中:

当服务启动时,它的生命周期独立于启动它的组件,并且服务可以无限期地在后台运行,即使启动它的组件被销毁也是如此。因此,服务应该在其工作完成时通过调用 stopSelf() 自行停止,或者另一个组件可以通过调用 stopService() 来停止它。

由于您在相关问题中“没有覆盖除 onCreate() 之外的任何其他方法”Activity,您可能会遇到以下情况:

  1. Service'onDestroy()不会被调用,除非另一个应用组件调用stopService();
  2. 这意味着Timer继续执行其工作。

根据文档停止服务。

编辑(关于您的评论):

“当我销毁活动时它开始新工作”意味着系统终止了该服务,并且由于您尚未覆盖onStartCommand()其默认返回值是START_STICKY,因此该服务已被重新创建并onStart()已调用其方法。

无法更改此类系统行为。但是您可以在前台运行该服务。

于 2016-01-09T16:47:47.847 回答
2

您必须使用IntentService而不是Service.

  • Service后台运行,但它在应用程序的主线程上运行。
  • IntentService单独的工作线程上运行。

如果运行您的服务的进程被杀死,Android 系统将自动重新启动它,这是默认行为。

因此,如果 Activity 的主线程被破坏,服务将重新启动,但如果您使用IntentService并使用,START_NOT_STICKY则它不会重新启动您的服务。

onStartCommand()此行为由Service 实现中的返回值定义。该常量START_NOT_STICKY告诉 Android 如果它在进程被“杀死”时正在运行,则不要重新启动服务。

您需要onStartCommand()在服务类中覆盖方法并将所有代码从onStart()方法移动到onStartCommand()方法。

根据Android文档:

对于已启动的服务,它们可以决定运行另外两种主要的操作模式,具体取决于它们返回的值onStartCommand()START_STICKY用于根据需要显式启动和停止的服务,而START_NOT_STICKYSTART_REDELIVER_INTENT用于应该只保留的服务在处理发送给他们的任何命令时运行

onStart()每次重新启动服务时onStartCommand()都会调用方法,但如果您返回,则不会调用方法START_NON_STICKY

IntentService有关和之间差异的更多详细信息Service。你可以检查一下

我希望这可以帮助你。

于 2016-01-19T07:33:31.547 回答