在发布结果之前,Android服务会被销毁

时间:2016-01-25 09:15:29

标签: android android-service android-broadcastreceiver

我有一个Activity(MainActivity)启动Service(FirstService),FirstService启动另一个Service(SsecondService)。场景是MainActivity应该等待FirstService的结果,但是这只会在从SecondService收到一些结果时发送结果。 问题是" onDestroy()"调用FirstService的方法,并在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);
    }

我现在正在努力工作几个小时,无法找到解决方案。我做错了什么,我该怎么做才能让它发挥作用?任何想法都受到欢迎。 干杯!

2 个答案:

答案 0 :(得分:0)

基本上,您有两种选择:

使用静态BroadcastReceiver

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

如果您阅读该链接,您会发现使用静态BroadcastReceiver存在缺点。那你为什么不跳过接收器直接从 SecondService 开始一些(第三个?)Service

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

将第一项服务实施为“正常”服务

目前, FirstService 正在扩展IntentService。 如果 FirstService 是作为已启动的Service实施的,那么只要需要从START_STICKY返回Service.onStartCommand(),您就可以确保它保持活动状态。您将继续使用动态BroadcastReceiver,甚至可以直接通过Service访问onStartcommand()。一旦完成,Service将取消注册接收方并致电stopSelf()

IntentService的优点是它不能在UI线程上完成工作。但是,已启动的Service可以使用AsyncTask,因此它也可以避免冻结用户界面。

答案 1 :(得分:0)

您不应该使用IntentService。如果您查看IntentService的文档,服务将启动并在onHandleIntent中完成其工作,然后完成。它不等任何事情。这就是FirstService被摧毁的原因,因为它已经完成了它的工作。相反,使用Simple Service并在处理程序线程中完成您的工作。这是您的服务将继续运行的情况。