前言
Telegram是一款强大的端到端加密IM,专注于安全性和速度,支持Android/IOS/Windows/macOS等平台,功能丰富,运行流畅,免费开源,代码具有学习和研究意义。
Telegram is a cloud-based mobile and desktop messaging app with a focus on security and speed.
123![ezgif-1-8f6a1c06cd9e.webp](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/eab9a234b2534133bfcc9004ab93f91c~tplv-k3u1fbpfcp-zoom-in-crop-mark:3024:0:0:0.image) ![ezgif-3-89bc771499a8.webp](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/5d62b135e05d453791894246274ff08f~tplv-k3u1fbpfcp-zoom-in-crop-mark:3024:0:0:0.image)
源码编译
编译环境为Android Studio4.2.1版本,JDK使用Android Studio自带的OpenJDK 11
![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/1f648978b5854bb9841c842a6c38593f~tplv-k3u1fbpfcp-zoom-in-crop-mark:3024:0:0:0.image)
从github.com/DrKLO/Teleg…下载Telegram源代码
复制自己的release.keystore到TMessagesProj/config目录
在gradle.properties文件中填写RELEASE_KEY_PASSWORD, RELEASE_KEY_ALIAS, RELEASE_STORE_PASSWORD,如:
RELEASE_KEY_PASSWORD=123456
RELEASE_KEY_ALIAS=jack
RELEASE_STORE_PASSWORD=123456
复制代码
访问console.firebase.google.com,创建两个android应用程序,应用程序id分别为org.telegram.messenger和org.telegram.messenger.beta,然后下载google-services.json,复制到TMessagesProj目录下
![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/05739831c63443928d7a25cd6d865358~tplv-k3u1fbpfcp-zoom-in-crop-mark:3024:0:0:0.image)
登录my.telegram.org,申请api_id and api_hash,然后替换TMessagesProj/src/main/java/org/telegram/messenger/BuildVars.java文件中的APP_ID和APP_HASH字段
![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/3b2b30af79ce4dad8550e47afcb08759~tplv-k3u1fbpfcp-zoom-in-crop-mark:3024:0:0:0.image)
![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/25358fa893724b88b196a8703b1d326f~tplv-k3u1fbpfcp-zoom-in-crop-mark:3024:0:0:0.image)
编译运行程序
源码解析
Telegram服务端源码不开源,那研究Telegram客户端代码有何意义呢?个人认为Telegram作为世界级IM,研究其源码还是相当有意义的,如下:
学习Telegram优秀的设计&编程思想,如单模块,单Activity架构,动态生成布局等
将Telegram中相对独立的功能如rlottie(贴纸),MTProto(通信协议),webrtc(音视频通话)剔除其业务逻辑然后抽出来,集成到自己的项目中
Telegram源码极其庞大和复杂,博大精深(晦涩难懂),有以下特点:
项目只有一个模块TMessagesProj,没有模块化,没有组件化,没有Kotlin,没有MVVM...
项目极少直接使用第三方类库,没有okhttp,没有glide,包含大量c/c++代码(tgnet,ffmpeg,webrtc,rlottie...)
项目中极少使用xml文件进行布局,基本都是使用代码动态生成界面,采用单Activity+多Fragment(这里的Fragment和Android SDK里的Fragment没有任何关系)
一个java类文件常常多达几千至几万行而没有任何注释说明,阅读起来感觉太爽了_^_
目前仅仅研究了一点点其贴纸使用的类库rlottie,如下:
贴纸尺寸为512*512像素,时长不超过3s,每秒运行60帧
贴纸文件名后缀为.tgs,本地缓存路径为Android/data/org.telegram.messenger/cache
tgs文件可以直接拖放到lottiefiles.com/preview上预览效果
123![22.gif](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/fb313615670c41c68faaf13b5477e33e~tplv-k3u1fbpfcp-zoom-in-crop-mark:3024:0:0:0.image) ![33.gif](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/80664eff08f241e490b06b1611b87168~tplv-k3u1fbpfcp-zoom-in-crop-mark:3024:0:0:0.image)
rlottie代码分析
native代码
TMessagesProj/jni/lottie.cpp rlottie包装类,定义了一些native函数,供java层调用
TMessagesProj/rlottie rlottie核心代码
TMessagesProj/lz4 压缩类库代码
java代码
RLottieImageView 继承于ImageView,内部调用RLottieDrawable展示播放tgs动画
RLottieDrawable 继承于Drawable,调用native代码创建渲染动画
//使用文件路径创建动画
public static native long create(String src, String json, int w, int h, int[] params, boolean precache, int[] colorReplacement, boolean limitFps);
//使用json字符串创建动画
protected static native long createWithJson(String json, String name, int[] params, int[] colorReplacement);
//销毁动画
public static native void destroy(long ptr);
//设置指定层次的颜色
private static native void setLayerColor(long ptr, String layer, int color);
//替换颜色
private static native void replaceColors(long ptr, int[] colorReplacement);
//获取一帧动画
public static native int getFrame(long ptr, int frame, Bitmap bitmap, int w, int h, int stride, boolean clear);
//创建缓存
private static native void createCache(long ptr, int w, int h);
复制代码
我已经将rlottie相关代码从Telegram里抽出并上传到github.com/kongpf8848/…
其他开源IM
Signal,主打私密性,老马推荐Use Signal,GitHub
Wire,加密聊天IM,GitHub
资源
Telegram官网
Telegram Android源码
Telegram iOS源码
Telegram API
|