Telegram阅读心得---页面结构(1)

Telegram阅读心得---页面结构(1)

获得telegram的源码

  1. 开发环境

Android Studio 3.3 Canary 3

Build #AI-181.5281.24.33.4884283, built on July 11, 2018

JRE: 1.8.0_152-release-1136-b04 amd64

JVM: OpenJDK 64-Bit Server VM by JetBrains s.r.o

Windows 10 10.0

ndk版本ndk 16b

  1. clone telegram

git clone [email protected]:DrKLO/Telegram.git

clone主仓库的内容之后,要获取子仓库的内容

git submodule init

git submodule update

  1. 安装ndk

    我使用的是ndk16b,如果你自带的ndk版本不适合,请切换到ndk16b试一试.

jni目录下面的Android.mk中,LOCAL_MODULE:=avutil下面添加一句LOCAL_SHORT_COMMANDS:=true,再将'-DVERSION="1.3.1"'修改为-DVERSION="1.3.1"

Application.mk下面添加APP_SHORT_COMMANDS:=true

  1. 修改Module级别下面的build.gradle

signingConfigs内的内容全部注释掉,这一步是了直接使用android studio 提供的签名,而不必麻烦得使用自己的签名

buildTypes中和signingConfigs相关的内容注释掉,特别的在buildTypes.debug中的applicationIdSuffix ".beta"也要注释掉

  1. 在telegram的网站https://my.telegram.org/注册并申请appid.把获得的id填入BuildVars.java的APP_IDAPP_HASH内,HOCKEY_APP_HASHHOCKEY_APP_HASH_DEBUG就随便填写一个32位的数字就行

  2. 申请firebase的google-service.json,保存到Module级别的目录下面

  3. 现在点一下这个神奇的按钮
    UTOOLS1554777325864.png

    就可以跑起来啦

  4. 如果你遇到编译安装后启动失败的问题,请关闭telegram的instant run,

阅读源码一定要有目的性

带着你的问题去看源码,要不然就会陷入,代码的海洋中找不到方向.

我第一次看源码从哪里入手呢,我选择了页面的架构,先从整体上看看这个app都是有哪些组成的.

查看Androidmianfest

这里可以看到LaunchActivity就是主入口的activity

翻遍在Androidmianfest中注册的activity可以发现,activity的数量很少,


org.telegram.ui.LaunchActivity

org.telegram.ui.ShareActivity

org.telegram.ui.ExternalActionActivity

org.telegram.ui.IntroActivity

org.telegram.messenger.OpenChatReceiver

org.telegram.ui.PopupNotificationActivity

org.telegram.ui.VoIPActivity

org.telegram.ui.VoIPGroupActivity

org.telegram.ui.VoIPPermissionActivity

org.telegram.ui.VoIPFeedbackActivity

可以看到拥有下面这个属性的org.telegram.ui.LaunchActivity就是主activity




                

                

                



那么我们就从这里入手.

记得,一定要带着问题去看

问题一. telegram有这么多的页面,为什么activity的数量那么少呢?

首先猜测是不是由一个activity+多个fragement实现的呢?

这里将telegram调到主页面,可以使用adb命令来看一下

dumpsys activity org.telegram.messengerok

结果如下


TASK org.telegram.messengerok id=10679 userId=0

  ACTIVITY org.telegram.messengerok/org.telegram.ui.LaunchActivity 3ceac50 pid=10773

    Local Activity b23cd31 State:

      mResumed=true mStopped=false mFinished=false

      mChangingConfigurations=false

      mCurrentConfig={1.0 460mcc11mnc [zh_CN] ldltr sw500dp w500dp h953dp 345dpi nrml long hdr port finger -keyb/v/h -nav/h winConfig={ mBounds=Rect(0, 0 - 1080, 2057) mAppBounds=Rect(0, 89 - 1080, 2146) mWindowingMode=fullscreen mActivityType=standard} s.31 themeChanged=0 themeChangedFlags=0}

      mLoadersStarted=true

      FragmentManager misc state:

        mHost=android.app.Activity$HostCallbacks@f1b2ff6

        mContainer=android.app.Activity$HostCallbacks@f1b2ff6

        mCurState=5 mStateSaved=false mDestroyed=false

    ViewRoot:

      mAdded=true mRemoved=false

      mConsumeBatchedInputScheduled=true

      mConsumeBatchedInputImmediatelyScheduled=false

      mPendingInputEventCount=0

      mProcessInputEventsScheduled=false

      mTraversalScheduled=true      mIsAmbientMode=false (barrier=16046)

      android.view.ViewRootImpl$NativePreImeInputStage: mQueueLength=0

      android.view.ViewRootImpl$ImeInputStage: mQueueLength=0

      android.view.ViewRootImpl$NativePostImeInputStage: mQueueLength=0

    Choreographer:

      mFrameScheduled=true

      mLastFrameTime=108084593 (12 ms ago)

.......

下面还有一些无关的

这里只给出一部分的输出内容,可以看到,并不是fragment实现的,其实,如果细心一点,在一开始就会发现LaunchActivity extends Activity

LaunchActivity直接继承的是activity,自然不会有fragment来实现了

那么是用什么来实现的呢

接着往下看

查看LaunchActivity的布局文件

布局文件可能会带来一些新的思路

这一个activity足足有3395行,刚开始看到时候可能会有点头大

Telegram阅读心得---页面结构(1)_第1张图片
UTOOLS1554793816963.png

不要慌,我们先从简单的看起,没错!就是布局文件.

然后我吭哧吭哧去看哪里setContenview(),然后我就看到了这样的


setContentView(drawerLayoutContainer, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));

居然是由代码生成的.

去看一下res/layout的资源文件,xml的布局文件居然只有4个

Telegram阅读心得---页面结构(1)_第2张图片
UTOOLS1554794135657.png

telegram为什么要这么做呢,真相只有一个

Telegram阅读心得---页面结构(1)_第3张图片
UTOOLS1554794263778.png

我们知道我们通过xml布局文件是通过LayoutInflater来解析生成View的,解析的过程会花掉一部分的时间, 如果是自己通过代码来构建布局,则省去了这个步骤,那么界面的显示就会更加流畅啦.

有点跑题,现在拉回来

找到了LaunchActivity的根布局drawerLayoutContainer,看一下它里面都加了什么view,可以看到有sideMenu,actionBarLayout.

sideMenu可以看到,它是一个侧边栏

Telegram阅读心得---页面结构(1)_第4张图片
UTOOLS1554797727141.png

sideMenu.setOnItemClickListener(),我看到这里是实现了很多的点击事件,发现了presentFragment(new GroupCreateActivity(args));

跟进这个函数,发现跟到了actionBarLayout.presentFragment()中,

可以看到这里会把"fragment"加入containerViewBack中(containerViewBack是一个linearLayout),并且在actionBarLayout中维护了一个返回栈fragmentsStack


....

//

containerViewBack.addView(fragmentView);

....

fragmentsStack.add(fragment);

....

再看一下这个所谓的"fragment" 到底是什么


    protected View fragmentView;

    protected ActionBarLayout parentLayout;

    protected ActionBar actionBar;

在基类BaseFragment中,可以看到它内部有一个fragmentView,也就是被添加到containerViewBack的那个view.

actionBarLayoutBaseFragment中都提供了相应的入栈presentFragment()和出栈removeFragmentFromStack()的方法.

那么到这里我的疑惑就解开了,telegram自己实现了一个类似于官方的fragment的自己的一个fragemnt,从来实现一个activity来管理多个页面的.

那么这篇就讲到这里啦.

晚安

你可能感兴趣的:(Telegram阅读心得---页面结构(1))