使用插件方式接入環(huán)信

有時(shí)候我們需要在應(yīng)用中接入即時(shí)通訊等功能,可是又苦于apk過(guò)大管跺、65535方法數(shù)等相關(guān)問(wèn)題义黎,這時(shí)候最好的方式就是用插件化的方式接入,下面是我用一個(gè)插件化框架接入環(huán)信的過(guò)程豁跑,跟大家分享一下廉涕。

這里我使用的是Apkplug這個(gè)插件化框架,這是一款我目前通過(guò)對(duì)比找到的最適合的插件化工具贩绕,在使用方便火的、運(yùn)行穩(wěn)定等方面均有良好表現(xiàn),還提供后臺(tái)托管淑倾,這一點(diǎn)也是極大的方便了開(kāi)發(fā)者馏鹤。
這里是這個(gè)框架的官方文檔可以參考

環(huán)信插件開(kāi)發(fā)

一、插件開(kāi)發(fā)

首先我們對(duì)這個(gè)插件的需求是:能在一個(gè)有用戶系統(tǒng)的宿主app里提供聊天功能娇哆。

進(jìn)一步細(xì)分為如下具體功能:

1 能跟宿主一起登陸

2 能跟宿主用戶系統(tǒng)有統(tǒng)一映射

3 能提供聊天界面

4 能提供好友界面

5 能提供最近會(huì)話界面

具體實(shí)現(xiàn):

1 首先要按照環(huán)信的文檔湃累,先進(jìn)行初始化和相關(guān)配置

public class MyApplication extends Application {
@Override
public void onCreate() {
    super.onCreate();

    EMOptions options = new EMOptions();

    EaseUI.getInstance().init(this, options);

    //xugai
    EMClient.getInstance().setDebugMode(false);

}
}

插件在宿主中啟動(dòng)時(shí)會(huì)自動(dòng)執(zhí)行application中的初始化代碼勃救。配置就不在這里貼了,可以參考環(huán)信文檔或下面的demo代碼治力。

2 跟宿主一起登陸蒙秒,是為了能夠跟宿主融合的更加融洽,如果點(diǎn)擊按鈕彈出一個(gè)登陸界面宵统,則像是兩個(gè)app之間的互相調(diào)用晕讲。所以在宿主登陸的時(shí)候,同時(shí)要登陸插件马澈,并對(duì)用戶透明瓢省。因此插件需要提供一個(gè)登陸接口。我用Dispatcher的方式聲明接口:

繼承一個(gè)com.apkplug.easemobplug.Processores類(lèi)痊班,實(shí)現(xiàn)Receive方法勤婚,在方法中調(diào)用環(huán)信登陸,宿主使用這個(gè)接口時(shí)可以把用戶名涤伐、密碼傳過(guò)來(lái)馒胆。參數(shù)的傳遞是靠人為約定的,宿主開(kāi)發(fā)者和插件開(kāi)發(fā)者按照約定取值凝果。DispatchAgent類(lèi)是管插件和宿主理通信的類(lèi)祝迂,在登陸完成后,我調(diào)用dispatchAgent.reply回調(diào)宿主器净,同樣液兽,給宿主發(fā)送結(jié)果的參數(shù)格式也是要人為約定好。

public class EaseLogin extends Processor {
BundleContext context;
DispatchAgent dispatchAgent;

public EaseLogin(BundleContext context) {
    super(context);
    this.context = context;
    dispatchAgent = new DispatchAgent(context);
}
@Override
public void Receive(URI uri, HashMap<String, Object> hashMap) {

    String userName = (String) hashMap.get("UserName");
    String passWord = (String) hashMap.get("Password");

    if(userName == null || passWord == null){
        dispatchAgent.reply(getMsgId(),false,new Exception("your username or password is null"));
        return;
    }
    EMClient.getInstance().login(userName, passWord, new EMCallBack() {
        @Override
        public void onSuccess() {
            dispatchAgent.reply(getMsgId(),true,"success");
        }

        @Override
        public void onError(int i, String s) {
            dispatchAgent.reply(getMsgId(),false,s);
        }

        @Override
        public void onProgress(int i, String s) {

        }
    });
}
}

這樣一個(gè)登陸接口就做好了掌动。

3 跟宿主應(yīng)用統(tǒng)一用戶系統(tǒng),環(huán)信插件里的用戶和聊天的好友一定是宿主應(yīng)用用戶系統(tǒng)中的用戶及好友宁玫,所以哪些人是用戶粗恢,那些人跟哪些人是好友,需要宿主告訴環(huán)信插件欧瘪。

首先需要提供注冊(cè)接口眷射,宿主用戶注冊(cè)時(shí),同步注冊(cè)環(huán)信插件佛掖,映射關(guān)系隨便定義:

public class EaseCreateAccount extends BaseProcessor {
    public EaseCreateAccount(BundleContext context) {
        super(context);
    }

    @Override
    public void Receive(URI uri, HashMap<String, Object> hashMap) {
        String userName = (String) hashMap.get("UserName");
        String password = (String) hashMap.get("Password");
        if(userName == null || password == null){
            dispatchAgent.reply(getMsgId(),false,new Exception("username or password is null"));
            return;
        }
        try {
            EMClient.getInstance().createAccount(userName,password);
            dispatchAgent.reply(getMsgId(),true,"success");
        } catch (HyphenateException e) {
            dispatchAgent.reply(getMsgId(),false,e);
        }
    }
}

好友的同步有兩種實(shí)現(xiàn)方式:

1 直接由宿主調(diào)用插件接口妖碉,設(shè)置插件的好友列表

2 宿主只管好友添加,插件自己去服務(wù)器拿好友列表

貌似方法2要好很多芥被,但是需要服務(wù)端的對(duì)接欧宜,只有服務(wù)端可以直接添加好友,客戶端添加好友的接口拴魄,最多只能等對(duì)方登陸時(shí)候才添加成功冗茸。

demo里這兩種我都實(shí)現(xiàn)了席镀,跟上面登陸接口一樣,我實(shí)現(xiàn)了一個(gè)直接給好友列表界面添加好友的接口夏漱,只供參考豪诲,我并沒(méi)有調(diào)用。我用的第二種方式挂绰,當(dāng)宿主的用戶系統(tǒng)添加好友時(shí)屎篱,同時(shí)給環(huán)信添加好友,因此我對(duì)外提供了添加好友的接口葵蒂。

public class EaseAddFriend extends BaseProcessor {
    public EaseAddFriend(BundleContext context) {
        super(context);
    }

    @Override
    public void Receive(URI uri, HashMap<String, Object> hashMap) {
        String username = (String) hashMap.get("UserName");
        try {
            EMClient.getInstance().contactManager().addContact(username, "you have to accept");
            dispatchAgent.reply(getMsgId(),true,"success");
        } catch (HyphenateException e) {
            dispatchAgent.reply(getMsgId(),false,e);
        }
    }
}

一系列你希望宿主用到的接口實(shí)現(xiàn)好后交播,就可以對(duì)外注冊(cè)了,plugin.xml中添加:

<processor
    uri="http://apkplug.plug.com/meseplug/login"
    className="com.apkplug.easemobplug.Processores.EaseLogin"
/>

<processor
    uri="http://apkplug.plug.com/meseplug/init"
    className="com.apkplug.easemobplug.Processores.EaseInit"
/>

<processor
    uri="http://apkplug.plug.com/meseplug/regist"
    className="com.apkplug.easemobplug.Processores.EaseCreateAccount"
/>

<processor
    uri="http://apkplug.plug.com/meseplug/contect"
    className="com.apkplug.easemobplug.Processores.EaseContectsProcessor"
/>

<processor
    uri="http://apkplug.plug.com/meseplug/addfriend"
    className="com.apkplug.easemobplug.Processores.EaseAddFriend"
/>

<processor
    uri="http://apkplug.plug.com/meseplug/deletefriend"
    className="com.apkplug.easemobplug.Processores.EaseDeleteFriend"
/>

4 提供聊天界面刹勃、好友界面堪侯、會(huì)話界面,環(huán)信提供一些直接可用的界面荔仁,稍加改動(dòng)就可以使用伍宦,宿主使用時(shí),只需要用Intent啟動(dòng)即可乏梁,需要注意的是次洼,一些manifest文件activity標(biāo)簽中配置的值,并不能同步到宿主遇骑,如果需要那些值卖毁,只能在宿主配置插件的activity,比如主界面落萎,android:windowSoftInputMode="adjustPan"
這個(gè)值不配置的話亥啦,輸入法彈出會(huì)壓縮界面控件,只在插件里配置是不起作用的练链。

<activity android:name=".ui.MainActivity"
        android:theme="@style/Theme.AppCompat.NoActionBar"
        android:windowSoftInputMode="adjustPan"
/>

提供了這些功能后翔脱,插件就開(kāi)發(fā)完成了。

二媒鼓、宿主開(kāi)發(fā)

1 安裝插件届吁,為了方便,我這里直接用了本地安裝

PlugManager.getInstance().installAssets("app-debug.apk", "1.0.0", new OnInstallListener() {
                        @Override
                        public void onDownloadProgress(String url, String filePath, long bytesWritten, long totalBytes, PlugInfo plugInfo) {

                        }

                        @Override
                        public void onInstallSuccess(final org.osgi.framework.Bundle bundle, PlugInfo plugInfo) {
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    textView.setText(textView.getText()+"\n插件安裝成功");
                                }
                            });
                            startChat();
                        }

                        @Override
                        public void onInstallFailuer(int i, PlugInfo plugInfo, String errorMsg) {

                        }

                        @Override
                        public void onDownloadFailure(String errorMsg) {

                        }
                    });
                }

2 登陸插件绿鸣,我已經(jīng)注冊(cè)過(guò)了用戶疚沐,這里不再調(diào)用,調(diào)用方式相同潮模。用DispatchAgent對(duì)象調(diào)用call方法亮蛔,

final DispatchAgent dispatchAgent=new DispatchAgent(PlugManager.getInstance().getBundleContext());

    HashMap<String,Object> params2 = new HashMap<String, Object>();
    params2.put("UserName","apkplug");
    params2.put("Password","lbh131206");
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            textView.setText(textView.getText()+"\n開(kāi)始登陸環(huán)信");
        }
    });
    dispatchAgent.call("http://apkplug.plug.com/meseplug/login", params2, new WorkerCallback() {
        @Override
        public void reply(URI uri, Object... objects) throws Exception {

            if(!(Boolean) objects[0]){
                return;
            }
            textView.setText(textView.getText()+"\n環(huán)信登陸成功");
            chatInitandLogin(dispatchAgent);

        }

        @Override
        public void timeout(URI uri) throws Exception {

        }

        @Override
        public void Exception(URI uri, Throwable throwable) {
            System.err.println(uri);
        }
    });

登陸后就隨時(shí)可以進(jìn)行界面跳轉(zhuǎn)了

Intent intent = new Intent();
    intent.setClassName(MainActivity.this, className);
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    startActivity(intent)

demo地址:

宿主:
https://github.com/apkplug/SDKDemo/tree/master/EasePlugUser

插件:
https://github.com/apkplug/SDKDemo/tree/master/EasemobPlug

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市再登,隨后出現(xiàn)的幾起案子尔邓,更是在濱河造成了極大的恐慌晾剖,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,734評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件梯嗽,死亡現(xiàn)場(chǎng)離奇詭異齿尽,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)灯节,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén)循头,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人炎疆,你說(shuō)我怎么就攤上這事卡骂。” “怎么了形入?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,133評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵全跨,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我亿遂,道長(zhǎng)浓若,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,532評(píng)論 1 293
  • 正文 為了忘掉前任蛇数,我火速辦了婚禮挪钓,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘耳舅。我一直安慰自己碌上,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,585評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布浦徊。 她就那樣靜靜地躺著馏予,像睡著了一般。 火紅的嫁衣襯著肌膚如雪盔性。 梳的紋絲不亂的頭發(fā)上吗蚌,一...
    開(kāi)封第一講書(shū)人閱讀 51,462評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音纯出,去河邊找鬼。 笑死敷燎,一個(gè)胖子當(dāng)著我的面吹牛暂筝,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播硬贯,決...
    沈念sama閱讀 40,262評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼焕襟,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了饭豹?” 一聲冷哼從身側(cè)響起鸵赖,我...
    開(kāi)封第一講書(shū)人閱讀 39,153評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤务漩,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后它褪,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體饵骨,經(jīng)...
    沈念sama閱讀 45,587評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,792評(píng)論 3 336
  • 正文 我和宋清朗相戀三年茫打,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了居触。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,919評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡老赤,死狀恐怖轮洋,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情抬旺,我是刑警寧澤弊予,帶...
    沈念sama閱讀 35,635評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站开财,受9級(jí)特大地震影響汉柒,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜床未,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,237評(píng)論 3 329
  • 文/蒙蒙 一竭翠、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧薇搁,春花似錦斋扰、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,855評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至宏娄,卻和暖如春问裕,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背孵坚。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,983評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工粮宛, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人卖宠。 一個(gè)月前我還...
    沈念sama閱讀 48,048評(píng)論 3 370
  • 正文 我出身青樓巍杈,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親扛伍。 傳聞我的和親對(duì)象是個(gè)殘疾皇子筷畦,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,864評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,116評(píng)論 25 707
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)、插件刺洒、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,103評(píng)論 4 62
  • 這種方式也是可以的鳖宾,直接在ARP( )內(nèi)進(jìn)行pdst的賦值 注意吼砂,scapy發(fā)包有一個(gè)弊端,就是鼎文,如果目標(biāo)地址暫時(shí)...
    FKTX閱讀 282評(píng)論 0 1
  • 狐貍說(shuō)我舔呀舔呀 我家老爺就硬了 我問(wèn)后來(lái)呢 狐貍說(shuō)我家老爺把我掰開(kāi) 翻云覆雨地掰開(kāi) 我再問(wèn)他看到了什么 狐貍說(shuō)我...
    楊孜閱讀 447評(píng)論 0 2
  • 由于這幾天沒(méi)有多少閑暇時(shí)間用來(lái)看書(shū)渔肩,今天才將《暗時(shí)間》完結(jié)∑剩《暗時(shí)間》最后幾節(jié)內(nèi)容是介紹數(shù)學(xué)方面的方法論赖瞒,出神入化...
    王偵閱讀 773評(píng)論 0 0