首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >bindService从不调用onServiceConnected

bindService从不调用onServiceConnected
EN

Stack Overflow用户
提问于 2015-07-29 16:42:21
回答 1查看 827关注 0票数 0

我的公司生产一个SDK,作为一个Android库aar文件交付。作为SDK的一部分,我们定义了一个服务:

代码语言:javascript
复制
    <service
        android:name=".session.internal.ChatSession"
        android:description="@string/description"
        android:enabled="true"
        android:exported="false"
        android:label="Network communication service"
    />

然后,该服务由SDK中的更多代码启动和绑定:

代码语言:javascript
复制
public boolean bindService(final Runnable whenBound) {
    if (connection == null) {
        // Make sure the service is running
        boolean success = startService();
        if(BuildConfig.DEBUG && !success) {
            throw new AssertionError("startService failed");
        }

        connection = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                chatSession = (IChatSession) service;
                if(whenBound != null) {
                    whenBound.run();
                }
            }

            @Override
            public void onServiceDisconnected(ComponentName name) {
                chatSession = null;
                connection = null;
            }
        };

        success = context.bindService(new Intent(context, ChatSession.class), connection, Context.BIND_IMPORTANT);
        if(BuildConfig.DEBUG && !success) {
            throw new AssertionError("bindService failed");
        }

        return success;
    }

    if(whenBound != null) {
        whenBound.run();
    }

    return true;
}

boolean startService() {
    boolean success = true;

    if(!isServiceRunning()) {
        success = context.startService(new Intent(context, ChatSession.class)) != null;
    }
    return success;
}

只要只有一个应用程序使用安装在移动设备上的SDK,这一切都能正常工作。

由于服务既没有显式导出(android:exported="false"),也没有隐式导出(没有定义<intent-filter> ),所以我们期望它在安装多个应用程序时也能很好地工作,每个应用程序在调用bindService时都具有自己的私有服务实例。

实际上,两个应用程序都不能像调用ServiceConnection.onServiceConnectedServiceConnected.onServiceDisconnected那样工作,尽管对context.startServicecontext.bindService的调用都返回成功。

一旦这两个应用程序都安装好了,唯一的方法就是卸载这两个应用程序,然后只重新安装其中一个应用程序。单独卸载是不够的。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-07-29 19:07:10

结果,问题实际上是这段代码,它首先阻止了服务的启动:

代码语言:javascript
复制
if(!isServiceRunning()) {
    success = context.startService(new Intent(context, ChatSession.class)) != null;
}

我为isServiceRunning编写了几段代码,这些代码错误地确定服务仅基于名称运行:

代码语言:javascript
复制
public boolean isServiceRunning() {
    ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
    List<ActivityManager.RunningServiceInfo> services = manager.getRunningServices(Integer.MAX_VALUE);
    if(services == null) {
        return false;
    }
    for (ActivityManager.RunningServiceInfo service : services) {
        if (ChatSession.class.getName().equals(service.service.getClassName())) {
            return true;
        }
    }
    return false;
}

将if替换为:

代码语言:javascript
复制
        if (Process.myPid() == service.pid && ChatSession.class.getName().equals(service.service.getClassName())) {

似乎解决了这个问题。

我仍然对此不感兴趣,因为看起来应该有一个更好的检查方法。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31706378

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档