【问题标题】:How to force the onServiceDisconnected() get called?如何强制调用 onServiceDisconnected()?
【发布时间】:2012-11-27 08:20:29
【问题描述】:

在我通过调用绑定服务之后:

bindService(new Intent(IBumpAPI.class.getName()), connection, Context.BIND_AUTO_CREATE);

出于调试目的,我需要调用 onServiceDisconnected()。

我知道 Android 系统会在与服务的连接意外丢失时调用它,例如当服务崩溃或被终止时,并且在客户端解除绑定时不会调用它。

所以我的问题是如何强制 onServiceDisconnected() 在我想要的时候被调用以便我可以完成测试?

【问题讨论】:

    标签: android service


    【解决方案1】:

    您需要启动服务,然后使用 Context.BIND_NOT_FOREGROUND 标志绑定,然后停止它。这将导致 onServiceDisconnected 被调用。这是 MainActivity 的代码(假设您定义了 TestService 服务),其中两个按钮链接到调用 doBind 和 doUnbind 方法:

    package com.example.servicetest;
    
    import android.app.Activity;
    import android.content.ComponentName;
    import android.content.Context;
    import android.content.Intent;
    import android.content.ServiceConnection;
    import android.os.Bundle;
    import android.os.IBinder;
    import android.util.Log;
    import android.view.Menu;
    import android.view.View;
    
    public class MainActivity extends Activity {
        private static final String TAG = "MainActivity";
    
        private ServiceConnection connection = new ServiceConnection() {
    
            @Override
            public void onServiceDisconnected(ComponentName name) {
                Log.d(TAG, "Service disconnected: " + name);
            }
    
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                Log.d(TAG, "Service connected: " + name);
            }
        };
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
        }
    
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            // Inflate the menu; this adds items to the action bar if it is present.
            getMenuInflater().inflate(R.menu.activity_main, menu);
            return true;
        }
    
        public void doBind(View v) {
            Intent i = new Intent(this, TestService.class);
            startService(i);
            bindService(i, connection, Context.BIND_NOT_FOREGROUND);
        }
    
        public void doUnbind(View v) {
            Intent i = new Intent(this, TestService.class);
            stopService(i);
        }
    
    }
    

    当您单击按钮时,此代码会提供以下日志:

    11-27 09:21:57.326: D/MainActivity(10724): Service connected: ComponentInfo{com.example.servicetest/com.example.servicetest.TestService}
    11-27 09:21:58.099: D/MainActivity(10724): Service disconnected: ComponentInfo{com.example.servicetest/com.example.servicetest.TestService}
    

    【讨论】:

    • 谢谢,但是 unbindService() 不会调用 onServiceDisconnected()。 (来自 Android 文档)
    • 我觉得它只是在意外发生时才被调用,而不是由于正常的 unbindService() 调用。 (你是对的,它不是直接在文档中)有什么想法吗?谢谢
    • @DinoZarafonitis 它对我有用 Context.BIND_NOT_FOREGROUND 但你 HAVE 调用 startService(i);在那之前。我在答案中包含的代码提供了附加的 logcat 输出。您可能在使用 Context.BIND_NOT_FOREGROUND 时缺少 startService 并且您的服务未启动。
    • 我应该给你买杯啤酒! :D
    • 除了调用 stopService(i) 之外,您还可以打开设置,转到开发人员选项 -> 运行服务 -> 您的应用程序并在那里停止服务。您仍然需要使用 Context.BIND_NOT_FOREGROUND 进行绑定。如果您想在不过多更改代码的情况下进行测试,这将非常方便。
    【解决方案2】:

    您可能只是取消绑定您的服务

    public void openService {
    mConnection = new ServiceConnection() {
                @Override
                public void onServiceConnected(ComponentName name, IBinder service) {
                    mService = IService.Stub.asInterface(service);
                }
                @Override
                public void onServiceDisconnected(ComponentName cn) {
                    mService = null;
                }
            };
             bindService(service, mConnection, Context.BIND_AUTO_CREATE);   
        }
    }
    
    public void closeService() {
        unbindService(mConnection);
        stopService(new Intent(this, Service.class));
    }
    

    【讨论】:

    • 你的意思是 unbingService 和 stopService 什么都不做?
    • 要调用 onServiceDisconnected 你只需要调用 closeService
    • 它没有调用它,我试过了......我已经用结果更新了问题。
    • 可能有点晚了,但这里的解决方案是不要在停止服务之前解除绑定。例如。 stopService 然后解除绑定服务
    • 好吧,我不想停止我的服务,只想在我的活动在后台时解除绑定。我在没有 stopService() 的情况下调用 unbindService() 并且未调用 onServiceDisconnected()。
    猜你喜欢
    • 2021-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-04
    • 1970-01-01
    相关资源
    最近更新 更多