1

我有一个 Activity(MainActivity) 启动一个服务 (FirstService) 和 FirstService 启动另一个服务 (SsecondService)。场景是 MainActivity 应该等待来自 FirstService 的结果,但这只会在它收到来自 SecondService 的内容时发送结果。问题是FirstService的“onDestroy()”方法在MainActivity得到最终结果之前被调用并注销了SecondService。

>> I/FirstService: On create...
>> I/FirstService: Handling intent...
>> I/SecondService: On create...
>> I/SecondService: On handling intent..
>> I/FirstService: OnDestroy receiver...
>> I/SecondService: Handling result ...
>> I/SecondService: Publishing result ...

在我的活动中:

    @Override
    public boolean onNavigationItemSelected(MenuItem item) {
        // Handle navigation view item clicks here.
        int id = item.getItemId();

        if (id == R.id.nav_home) {
            // Handle the camera action
        } else if (id == R.id.nav_camera) {

        } else if (id == R.id.nav_pictures) {
            startAction();   
        }
        drawer.closeDrawer(GravityCompat.START);
        return true;
    }

    public void startAction {
        Log.i("MainActivity", "Starting FirstService");
        Intent intent = new Intent(this, FirstService.class);
        intent.setAction(FirstService.ACTION_FETCH_PICTURES);
        intent.putExtra(FirstService.EXTRA_ACCOUNT, account);
        this.startService(intent);
    }

    private BroadcastReceiver receiver = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            Log.i("MainActivity", "Waiting for onReceive");
            Bundle bundle = intent.getExtras();
            if (bundle != null) {
                resultCode = bundle.getInt(FirstService.RESULT);
                switch (resultCode) {
                    case FirstService.RESULT_CODE_OK: [...]
                    }
                    [...]
                    }
                }
            }
        }
    };

    @Override
    protected void onResume() {
        super.onResume();
        Log.i("MainActivity", "on resume");
        registerReceiver(receiver, new IntentFilter(FirstService.NOTIFICATION));
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.i("MainActivity", "Unregister receiver...");
        unregisterReceiver(receiver);
    }

我的第一服务:

 @Override
    public void onCreate() {
        super.onCreate();
        Log.i("FirstService", "On create...");           
        registerReceiver(secondReceiver, new IntentFilter(SecondService.NOTIFICATION_SECOND));
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        Log.i("SecondService", "Handling intent...");
        if (intent != null) {
            final String action = intent.getAction();
            // .... some more code
            Intent intent = new Intent(this, SecondService.class);
            intent.setAction(SecondService.ACTION_FETCH_VALIDITY);
            intent.putExtra(SecondService.EXTRA_ACCOUNT, accNumber);
            this.startService(intent);
        }
    }

    private void publishResults(int result) {
        Log.i("FirstService", "Publishing result...");
        Intent intent = new Intent(NOTIFICATION);
        intent.putExtra(RESULT, result);
        sendBroadcast(intent);
    }

    public BroadcastReceiver secondReceiver = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            Log.i("SecondService", "On receiving result...");
            Bundle bundle = intent.getExtras();
            if (bundle != null) {
                result = bundle.getInt(SecondService.RESULT);
                switch (result) {
                    //[....]
                }
                publishResults(result);
            }
        }
    };


    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.i("SecondService", "OnDestroy receiver...");
        unregisterReceiver(secondReceiver);
    }

我现在为此苦苦挣扎了几个小时,但找不到解决方案。我做错了什么,我应该怎么做才能让它发挥作用?任何想法都受到欢迎。干杯!

4

2 回答 2

0

基本上,您有两种选择:

使用静态广播接收器

您可以使用独立的BroadcastReceiver. 它必须在应用程序中注册Manifest。每当您的SecondService想要发布某些内容时,它都会像以前一样广播结果。然后接收器可以启动另一个Service来处理结果。另请参阅文档

如果您阅读链接,您会发现使用 static 有一些缺点BroadcastReceiver。那么为什么不Service直接从SecondService跳过接收器并启动一些(第三个?) ?

这将我们带到了第二个选项:

将第一个服务实现为“正常”服务

现在,FirstService正在扩展IntentService. 如果FirstService是作为 start 实现的,Service那么您可以通过START_STICKYService.onStartCommand(). 您将继续使用动态BroadcastReceiver,甚至Service直接通过onStartcommand(). 一旦完成,您Service将取消注册接收器并调用stopSelf()

an 的优点IntentService是它不在 UI 线程上工作。但是一个startedService可以使用AsyncTask,所以它也可以避免冻结UI。

于 2016-01-25T10:14:39.187 回答
0

你不应该使用IntentService. 如果您查看 IntentService 的文档,服务会启动并在其中完成工作onHandleIntent,然后完成。它不等待任何东西。这就是为什么FirstService正在被摧毁,因为它已经完成了它的工作。相反,请使用 SimpleService和 in 处理程序线程来完成您的工作。在这种情况下,您的服务将继续运行。

于 2016-01-25T10:27:55.390 回答