集成融云没有ipc进程的天坑

1,434 阅读5分钟

这几天碰到一个很奇葩的问题,由于以前也没有用过融云的SDK,算是第一次用。然接到的任务就是集成下融云的IMLib库,当时想的这能有多难,不分分钟搞定的节奏么?结果让人大跌眼镜,搞了两天不但没解决,反而一点头绪都没有。然后是网上各种找资料,百度啊,谷歌啊,通通试了个遍,毫无用处。而且还有些更蹊跷的,就是一开始,程序跑起来连io.rong.push进程都是没有的,这个后面通过一通处理,这个进程倒是能出来了,但是ipc进程还是没有,大家都知道这是融云的通信进程,这玩意要是起不起来,那是没法通信的。所以我那个急啊,烦躁啊真心地,特别郁闷。周六回到家都没精打采,整个脑袋都在想这到底是哪里的问题,因为网上说的所有的办法都试了,融云的资料库都看了几个来回,依然还是出不来。但是,我写的demo或者示例程序,一点问题都没有,唯独集成到我们自己的项目就起不起来,真的感觉邪门。有点罗嗦,哈哈~

1、现象

没办法,即然没有思路,那只能一步步来,打log,debug调试。我最开始想到的就是从最简单的途径入手,那就是,我只用一个Application 去做初始化,然后在一个页面去调RongIMClient.connect(因为token用的测试的,后台直接生成),但即使是这样了,在我们的项目中还是不行,不行的现象就是onTokenIncorrectonSuccessonError 三个回调都不会走,服务器更加是连不上了。中间把融云的 log 都打出来看了下,发现有这样两句(图中1):

log日志
然后点击链接服务器或者点击发送消息,就会出现上图2中所示的日志,其中消息发送时的错误很明确:IPC_DISCONNECT。

2、调试

还是那句话,没有好的思路只能一步步来,那就直接调试吧,跟着 connect 方法一步步往里走,走到RongIMClient类的connectServer(final String token, final boolean isReconnect, RongIMClient.ConnectCallback callback)方法里的时候看到了如下图所示的结果:

this.mLibHandler == null
this.mLibHandler == null的时候,请看如下截图:
this.mLibHandler == null
他会执行initBindService()方法,代码如下:

private void initBindService() {
        Intent intent = new Intent(this.mContext, RongService.class);
        intent.putExtra("appKey", this.mAppKey);
        intent.putExtra("deviceId", this.mDeviceId);
        if (this.mLibHandler != null) {
            this.initReceiver();
        } else {
            try {
                this.mContext.bindService(intent, this.mAidlConnection, 1);
            } catch (SecurityException var3) {
                RLog.e("RongIMClient", "initBindService SecurityException");
                var3.printStackTrace();
            }

        }
    }

一直到最后的this.mContext.bindService(intent, this.mAidlConnection, 1);就算执行完了,这也是为什么三个回调都没有结果的原因。 那么 mLibHandler 究竟是个什么鬼呢?我们进去看看,进来是这样的:

public interface IHandler extends IInterface

他是一个接口,接着来:

/**
 * Base class for Binder interfaces.  When defining a new interface,
 * you must derive it from IInterface.
 */
public interface IInterface
{
    /**
     * Retrieve the Binder object associated with this interface.
     * You must use this instead of a plain cast, so that proxy objects
     * can return the correct result.
     */
    public IBinder asBinder();
}

里面只定义了一个asBinder()方法,返回一个IBinder实例,IBinder是个什么东东,熟悉 ipc 的应该会了解,这里就不详说了,那么到这里我们大致明白了,为啥没反应了,因为这个mLibHandler就是负责真正去连接服务器的东东,那如果他为空自然是没法连成功了。

3、尝试

这里面有个很尴尬的地方,那就是虽然上面分析出了为啥连不上服务以及回调不成功的原因,但我依然不知道如何解决这个问题。所以啊,这中间试了一堆的网上办法,什么so库没集成成功啊,tar版本要小于24啊,什么libsqlite.so文件没有添加啊,通通没有效果。如图:

没有ipc进程
所以,老办法来了,我拿着我项目的配置表去一个空项目挨个试试看,死马当活马医呗,然后奇迹发生了,一导入自己项目的工程文件,原本能起来的项目也出问题了,有戏,这说明问题能复现,那就先试着注释掉几个可能会引起冲突的包,发现还是一样,那就看下那些可能会影响到融云ipc进程的东东,这时候有个很熟悉的家伙进入了我的视线:

        ndk {
            //设置支持的SO库架构
            abiFilters 'armeabi', 'x86', 'armeabi-v7a', 'arm64-v8a'
        }

对了,没错,就是楼上那个大兄弟,当我把他注释后,出现了传说中的ipc进程,如图:

ipc进程
然后测试也是ok 的,如图:
连接成功
发送消息出来日志也变了,如图:
no_chatroom
这个问题很奇怪,但需要说明的是,融云我是以第三方库的方式引入的,然后在 app 的 gradle 配置文件里去写的 ndk 配置,所以当我把 app 的 ndk 配置注释掉之后,在融云的库中设置 ndk 配置的时候使用是没有问题的。

4、结尾

写的很乱,我通常是想说的太多,结果是想到什么就写什么,所以,尝尝不知道有没有写清楚,o(∩_∩)o 哈哈~ 我只能说这个问题很奇葩,而且网上没有找到一例跟这个相关的资料,然后,融云的工单系统还非得实名认证,晕死~(吐槽下),其次,加的好多个融云QQ交流群,直到现在也没给我通过~,信春哥,得始终@