本次学习思路是跟着环信的sdk 的apk例子,根据用户操作,把功能走一遍,代码的讲解跟随功能一起讲;
所以首先在我们安装好了apk之后,从点击launch图标之后执行的一系列代码开始跟踪,ready?~~ Go!
0,初始化应用application:
看到这里有一个sdk初始化助手类,集成自HXSDKHelper环信sdk助手类,里面定义了很多公共的方法和属性以及软件相关的配置,包括程序初始化,获取上下文,设置用户自定义配置,初始化连接监听,获取群组列表并通知更新,获取好友列表并通知更新以及反初始化方法;
hxSDKHelper.onInit(applicationContext);
我们很容易猜到,这时做了软件的初始化,跟踪进去,DemoHXSDKHelper这个类是继承自HXSDKHelper的,而HXSDKHelper是一个抽象类,我们来看看这个抽象类里面做了什么,初始化是这样的:
public synchronized boolean onInit(Context context){ if(sdkInited){ return true; } appContext = context; // create HX SDK model hxModel = createModel(); // create a defalut HX SDK model in case subclass did not provide the model if(hxModel == null){ hxModel = new DefaultHXSDKModel(appContext); } int pid = android.os.Process.myPid(); String processAppName = getAppName(pid); Log.d(TAG, "process app name : " + processAppName); // 如果app启用了远程的service,此application:onCreate会被调用2次 // 为了防止环信SDK被初始化2次,加此判断会保证SDK被初始化1次 // 默认的app会在以包名为默认的process name下运行,如果查到的process name不是app的process name就立即返回 if (processAppName == null || !processAppName.equalsIgnoreCase(hxModel.getAppProcessName())) { Log.e(TAG, "enter the service process!"); // 则此application::onCreate 是被service 调用的,直接返回 return false; } // 初始化环信SDK,一定要先调用init() EMChat.getInstance().init(context); // 设置sandbox测试环境 if(hxModel.isSandboxMode()){ EMChat.getInstance().setEnv(EMEnvMode.EMSandboxMode); } if(hxModel.isDebugMode()){ // set debug mode in development process EMChat.getInstance().setDebugMode(true); } Log.d(TAG, "initialize EMChat SDK"); initHXOptions(); initListener(); syncGroupsListeners = new ArrayList<HXSyncListener>(); syncContactsListeners = new ArrayList<HXSyncListener>(); syncBlackListListeners = new ArrayList<HXSyncListener>(); isGroupsSyncedWithServer = hxModel.isGroupsSynced(); isContactsSyncedWithServer = hxModel.isContactSynced(); isBlackListSyncedWithServer = hxModel.isBacklistSynced(); sdkInited = true; return true; }
第一句是调用子类的createModel方法,我们不知道这个model是干嘛的,点进去,我们发现DemoHXSDKModel extends DefaultHXSDKModel;
DefaultHXSDKModel extends HXSDKModel;
那我们从父类开始看起,
HXSDKModel是一个抽象类,定义一些用户自定义配置相关的方法,但是它没有具体的实现,具体的实现交给了它的子类DefaultHXSDKModel ;包括是否开启消息回执,是否需要好友关系,是否接受邀请,是否振铃等方法;
DemoHXSDKModel 这个类里面是一些操作用户列表的方法,包括保存到数据库和获取;
这样我们就明白了,原来这玩意就是一个操作用户列表和配置文件的一个类;
然后就是初始化环信sdk了, EMChat.getInstance().init(context);
1.读取服务器配置和手机运行环境,随后初始化asmack的静态代码(因为有些功能要使用,需要提前加载);
2.读取用户配置信息;
3.添加网络连接监听;
4.初始化消息推送服务;
5.设置初始化完成;
到这里,软件的初始化做完了,那么,跳转到第一个页面:开屏页;
1.进入开屏页:
package com.easemob.chatuidemo.activity; import android.content.Intent; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.os.Bundle; import android.view.animation.AlphaAnimation; import android.widget.RelativeLayout; import android.widget.TextView; import com.easemob.chat.EMChatManager; import com.easemob.chat.EMGroupManager; import com.easemob.chatuidemo.DemoHXSDKHelper; import com.easemob.chatuidemo.R; /** * 开屏页 * */ public class SplashActivity extends BaseActivity { private RelativeLayout rootLayout; private TextView versionText; private static final int sleepTime = 2000; @Override protected void onCreate(Bundle arg0) { setContentView(R.layout.activity_splash); super.onCreate(arg0); rootLayout = (RelativeLayout) findViewById(R.id.splash_root); versionText = (TextView) findViewById(R.id.tv_version); versionText.setText(getVersion()); AlphaAnimation animation = new AlphaAnimation(0.3f, 1.0f); animation.setDuration(1500); rootLayout.startAnimation(animation); } @Override protected void onStart() { super.onStart(); new Thread(new Runnable() { public void run() { if (DemoHXSDKHelper.getInstance().isLogined()) { // ** 免登陆情况 加载所有本地群和会话 //不是必须的,不加sdk也会自动异步去加载(不会重复加载); //加上的话保证进了主页面会话和群组都已经load完毕 long start = System.currentTimeMillis(); EMGroupManager.getInstance().loadAllGroups(); EMChatManager.getInstance().loadAllConversations(); long costTime = System.currentTimeMillis() - start; //等待sleeptime时长 if (sleepTime - costTime > 0) { try { Thread.sleep(sleepTime - costTime); } catch (InterruptedException e) { e.printStackTrace(); } } //进入主页面 startActivity(new Intent(SplashActivity.this, MainActivity.class)); finish(); }else { try { Thread.sleep(sleepTime); } catch (InterruptedException e) { } startActivity(new Intent(SplashActivity.this, LoginActivity.class)); finish(); } } }).start(); } /** * 获取当前应用程序的版本号 */ private String getVersion() { String st = getResources().getString(R.string.Version_number_is_wrong); PackageManager pm = getPackageManager(); try { PackageInfo packinfo = pm.getPackageInfo(getPackageName(), 0); String version = packinfo.versionName; return version; } catch (NameNotFoundException e) { e.printStackTrace(); return st; } } }
核心代码就是上面这个啦,首先判断是否已经登录了,原理就是判断当前获取到的用户和最后登录的用户是不是同一个,是的话返回true;如果是的话加载群组和会话信息(因为这两个时间比较长而且必须等到这两个东西加载完成才能进去系统,所以放在开屏页很合适);
因为是第一次登录,当然是转到登录页面啦;下一节开始讲用户登录;