| 友情围观,群主的耐心,我等菜鸟自愧不如 |
引用:暄落 发表于 2020-09-24 13:58 嗯,以官方的Demo为参照点,如果搞不定,你就开贴,需要什么协助会尽力帮你 |
引用:JackJiang 发表于 2020-09-24 13:40 新进展是我这边连接github 项目中的 MobileIMSDK-master\demo_binary\Server\MobileIMSDKServerDemo_deploy_v5.0b20200905\run.bat在我本地是不会断开的,应该是我们后端的同学那里代码有问题。现在那边正在排查 |
| [已回复] 求助关于MobileIMSDK聊天消息指纹码的生成以及其它疑问 这段代码解决了我的这个问题。我在退出登录的时候没有解绑监听器。 |
引用:暄落 发表于 2020-09-24 13:29 好,我来把RainbowChat中的“退出登陆”这个功能的主要实现代码,发你参一下,具体如果你不太理解功能是怎么样UI交互的,你就自已下载APP体验一下。 具体的功能体验就是:RainbowChat的“退出登陆”功能在下图中,点退出登陆时,会关闭当前连接并释放im sdk这一层的资源并跳转到登陆界面。 我贴的是没有删减的代码,你不需要关注的业务内容,跳过不看就行。 下面是“退出登陆”按钮,点击时的事件处理:
// 点击"退出登陆"
exitBtn.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v)
{
new AlertDialog.Builder(MoreActivity.this)
.setTitle($$(R.string.general_are_u_sure))
.setMessage($$(R.string.main_more_msg_tone_exit_to_login))
.setPositiveButton($$(R.string.general_ok), new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog,int which)
{
// 退出登陆(但不退出JVM——即不通出APP进程)
LoginActivity.doLogoutNoConfirm(MyApplication.getInstance2(), false, new Observer(){
// 此通知将在注册与IM服务器的连接、释放IM资源、释放本APP中所有activity后被通知
@Override
public void update(Observable arg0, Object arg1)
{
// 退出登陆时,取消"自动登陆"的开关量设置
PreferencesToolkits.setAutoLogin(MoreActivity.this, false);
// 代码执行至此,表示APP中所有的activity都已被回收(包括本MoreAcvitity),
// 而要再次显示登陆界面activity的话,只能借助APP全局唯一的Context——即
// Application实例,以下代码千万不可引用错了Context哦
Context ctx = MyApplication.getInstance2();
Intent iLogin = IntentFactory.createLoginIntent(ctx);
// 因Application对象并不是Activity,所以必须要加此flag,否则无法启动Activity
iLogin.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// 进入登陆activity
ctx.startActivity(iLogin);
}
});
}
})
.setNegativeButton($$(R.string.general_cancel), null)
.show();
}
});
LoginActivity.doLogoutNoConfirm()方法的主要代码如下: /**
* 退出APP的登陆,并释放所有资源。
* <p>
* 注:方法中不涉及任何GUI,用在多线程中调用也没事。
*
* @param context
* @param exitJVM true表示完成退出APP(可用于完关闭应用时),否则表
* 示仅退出所有Activity(可用于切换到登陆界面重新登陆等场景下)
* @param obsAfterLogoutIMServer 本观察者将在logout im server完成后,被
* 调用,当前此参数已知的是在更多界面中的”退出登陆“时使用了。一般来说,本参数
* 的设置只在exitJVM参数=false时才有意义,请参见源码
*/
public static void doLogoutNoConfirm(final Context context, final boolean exitJVM
, final Observer obsAfterLogoutIMServer)
{
// TODO 退出登陆时如有其它事情要处理,可在此补充!
// 【1】注销HTTP服务器的登陆
。。。。。。。。
// 【2】注销IM服务器连接并释放IM框架所占的所有资源
IMClientManager.doLogoutIMServer(context
, new Observer(){// 为何要使用观察者?因退出登陆数据发送是在异步线程中实现的,
// 使用观察者的目的是确保退出JVM等是在数据已发送完成后再行的哦!!!!
@Override
public void update(Observable observable, Object data) {
// 释放APP应用占用的资源
systemExit(context, exitJVM);
//
if(obsAfterLogoutIMServer != null)
obsAfterLogoutIMServer.update(null, null);
}
});
// 【3】重置大文件下载管理器
。。。。。。。
}IMClientManager.doLogoutIMServer()方法的实现代码: /**
* 退出IM服务器连接并释放IM所占的所有资源(含退出IM框架连接、再释放IM框架所占的资源)。
* <p>
* 在切换账号等功能场景下,使用本方法可以保证重新登陆时IM框架
* 已回到重初状态,从而完全正常的重新登陆。
*
* @see LocalDataSender#sendLoginout()
* @see IMClientManager#releaseMobileIMSDK()
*/
public static void doLogoutIMServer(final Context context, final Observer obsForSucess)
{
// 退出登陆
new AsyncTask<Object, Integer, Integer>(){
private Observer obsForSucess = null;
@Override
protected Integer doInBackground(Object... params)
{
int code = -1;
try
{
if(params != null)
obsForSucess = (Observer)params[0];
// local user info 为空即意味着用户极是打开了登陆界面而尚未有登陆过,那当然就不需要退出登陆罗
if(MyApplication.getInstance(context).getIMClientManager().getLocalUserInfo() != null)
code = LocalDataSender.getInstance().sendLoginout();
}
catch (Exception e)
{
Log.e(TAG, "错误发生于doLogout:sendLoginout时:"+e.getMessage(), e);
}
return code;
}
@Override
protected void onPostExecute(Integer code)
{
// local user info 为空即意味着用户极是打开了登陆界面而尚未有登陆过,那当然就不需要退出登陆罗
if(MyApplication.getInstance(context).getIMClientManager().getLocalUserInfo() != null)
{
if(code == 0)
Log.d(LoginActivity.class.getSimpleName(), "注销登陆请求已成功发出!");
else
Log.w(LoginActivity.class.getSimpleName(), "注销登陆请求发送失败。错误码是:"+code+"!");
}
try
{
// 释放IM所占资源
MyApplication.getInstance(context).getIMClientManager().releaseMobileIMSDK();
}
catch (Exception e)
{
Log.e(TAG, "错误发生于logoutMobileIMSDK:onPostExecute:releaseMobileIMSDK()时:"+e.getMessage(), e);
}
// * 处理完成后通知观察者做其它事哦
if(obsForSucess != null)
obsForSucess.update(null, null);
}
}.execute(obsForSucess);IMClientManager.releaseMobileIMSDK()方法的实现代码: /**
* 释放IM框架所占用的资源,在退出登陆时请务必调用本方法,否则重
* 新登陆将不能正常实现(指APP进程不退出时切换账号这种情况)。
*/
public void releaseMobileIMSDK()
{
// 释放IM核心库资源
ClientCoreSDK.getInstance().release();
// 重置本类的初始化标识
this.resetInitFlag();
// 清空设置的回调
ClientCoreSDK.getInstance().setChatBaseEvent(null);
ClientCoreSDK.getInstance().setChatMessageEvent(null);
ClientCoreSDK.getInstance().setMessageQoSEvent(null);
// 清空本量中的关键全局变量
this.localUserInfo = null;
this.currentFrontGroupChattingGroupID = null;
this.currentFrontTempChattingUserUID = null;
this.currentFrontChattingUserUID = null;
// 重置关键数据模型变量
this.friendsListProvider = null;
this.groupsProvider = null;
this.messagesProvider = null;
this.groupsMessagesProvider = null;
this.alarmsProvider = null;
this.currentVideoChattingActivity = null;
ProhibitSpeechCheckerProvider.getInstance().clear();
// 释放实时音视频相关资源
VVP2PProvider.getInstance(context).release();
}注意一点:RainbowChat中,在登陆界面跳转前,就进行是IM SDK的Init,所以即使是你看到的“退出登陆”这种情况,也可以确保再次登陆前已经完成im sdk的init: /**
* 打开LoginActivity的Intent构造方法. 此方法通常用于无法普通地打开登陆界面的场景.
*
* @param thisActivity
* @return
*/
public static Intent createLoginIntent(Context thisActivity)
{
// init MobileIMSDK first(必须保证此代码被调用,否则IM框架无法完成IM服务器的连接等工作)
// 通常在打开登陆界面调用此方法,是合理的,因为它下一步就是登陆im框架啊
MyApplication.getInstance(thisActivity).getIMClientManager().initMobileIMSDK();
Intent intent = new Intent(thisActivity, LoginActivity.class);
return intent;
}IMClientManager.initMobileIMSDK()的代码实现: /**
* IM框架初始化方法,本方法在连接IM服务器前必须被调用1次,否则IM底层框架将无法工作。
*/
public void initMobileIMSDK()
{
if(!this._init)
{
baseEventListener = new ChatBaseEventListener(context);
transDataListener = new ChatMessageEventListener(context);
messageQoSListener = new MessageQoSListener(context);
ClientCoreSDK.getInstance().init(context);
ClientCoreSDK.getInstance().setChatBaseEvent(baseEventListener);
ClientCoreSDK.getInstance().setChatMessageEvent(transDataListener);
ClientCoreSDK.getInstance().setMessageQoSEvent(messageQoSListener);
// ClientCoreSDK.DEBUG = true;
friendsListProvider = new FriendsListProvider();
groupsProvider = new GroupsProvider();
messagesProvider = new MessagesProvider();
groupsMessagesProvider = new GroupsMessagesProvider();
alarmsProvider = new AlarmsProvider(this.context);
this._init = true;
}
} |
引用:JackJiang 发表于 2020-09-24 13:26 嗯嗯,我怀疑是 退出账号→登录另一账号 这样的情况导致的。上边有我的退出登录与登录逻辑,我是仿写的 SDK Demo 里面的代码实现的 |
引用:暄落 发表于 2020-09-24 13:13 你想做的是,在不退出app的情况下,实现退出当前账号,前重新登陆这样的功能逻辑是吗? 如果是,我就把RainbowChat产品中的实现,贴给你参一下。 |
引用:JackJiang 发表于 2020-09-24 12:27 是的,我在出现的时候去后端那里看了一下,不存在同一账号重复登陆的情况。 |
引用:暄落 发表于 2020-09-24 10:50 这么规律,一定是其它问题。你排查过,不存在同一账号重复登陆是吧 |
引用:JackJiang 发表于 2020-09-24 10:45 我断开重连,早上怀疑是退出登录-登录,多次导致的问题,结果刚刚我连接sdk中的 run.bat ,发现连接自己的没有什么问题,可能是后端同学那里的问题。现在所有连接那个地址的都是 45s 断一次。 |
引用:JackJiang 发表于 2020-09-24 10:45 有一个回复提示进审核了,没有显示出来 |
引用:暄落 发表于 2020-09-24 09:16 你贴的这个内容,跟你发的帖子问题,是有关联的吗? |
引用:JackJiang 发表于 2020-09-23 12:47 退出登录代码: ----------------------------------------- 注销登录之后初始化的代码 ----------------------------------------------------- 再次登录的代码 |
引用:JackJiang 发表于 2020-09-23 12:47 我找到了触发条件:当我下线切换账号,重复几次就会出先这样的情况,应该是我退出登录或者登录写的有问题,麻烦站长帮我看下 |
|
按照你的Log显示,每隔45秒断一次,这一定是另有原因。 检查一下:这台手机的登陆ID,是否有别的手机有用同样的ID,也就是看看是否存在同一个ID重复登际的情况。 |