开源中国(OSChina)源码解析(2)——闪屏页

1、前言

今天跟大家一起对闪屏页的源码进行分析。先请大家看一下,下面的视觉图,对这个闪屏页的机能有一个大致的了解。

  • 全屏
  • 没有状态栏
  • 延迟加载
  • 加载开源中国的欢迎图

开源中国(OSChina)源码解析(2)——闪屏页_第1张图片

2、源码分析

2.1、启动入口

我们首先得找到程序的入口,然后才能知道启动的页面是哪一个activity。
在清单文件中找到包含以下属性的IntentFilter

讲解:决定一个应用程序最先启动哪个组件
<action android:name="android.intent.action.MAIN" />
讲解:决定应用程序是否显示在程序列表里(就是是否在桌面上显示一个启动图标)
<category android:name="android.intent.category.LAUNCHER" />

IntentFilter对应启动页面就是net.oschina.app.LaunchActivity,那么启动入口就找到了,接下来就请大家打开LaunchActivity源代码文件。

开源中国(OSChina)源码解析(2)——闪屏页_第2张图片

2.2、 启动界面

路径:OSChina\app\src\main\java\net\oschina\app\LaunchActivity.java

/**
 * 应用启动界面
 */
public class LaunchActivity extends BaseActivity {

    // 讲解:解析布局文件(app_start)
    @Override
    protected int getContentView() {
        return R.layout.app_start;
    }

    // 讲解:初始化数据
    @Override
    protected void initData() {
        super.initData();
        // 在这里我们检测是否是新版本安装,如果是则进行老版本数据迁移工作
        // 该工作可能消耗大量时间所以放在子线程中执行
        AppOperator.runOnThread(new Runnable() {
            @Override
            public void run() {
                doMerge();
            }
        });
    }

    private void doMerge() {
        // 判断是否是新版本
        if (Setting.checkIsNewVersion(this)) {
            // Cookie迁移
            String cookie = OSCApplication.getInstance().getProperty("cookie");
            if (!TextUtils.isEmpty(cookie)) {
                OSCApplication.getInstance().removeProperty("cookie");
                User user = AccountHelper.getUser();
                user.setCookie(cookie);
                AccountHelper.updateUserCache(user);
                OSCApplication.reInit();
            }
        }

        // 栏目相关数据合并操作
        DynamicTabFragment.initTabPickerManager();
      
        // 讲解:等待0.8秒后执行跳转操作。
        *****************************************************************
        // Delay...
        try {
            Thread.sleep(800);
        } catch (InterruptedException e) {
            e.printStackTrace(); <= 讲解:此处不合理,应该统一管理日志。
        }

        // 完成后进行跳转操作
        redirectTo();
        *****************************************************************
        // =>因为doMerge处理已经是在子线程中,所以直接等待0.8秒就可以了,
        // 如果不是在子线程中,则可以考虑用下面这种方式启动主页面。
        
        // 完成后进行跳转操作
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                redirectTo();
            }
        }, 800);
        *****************************************************************
    }

    // 讲解:跳转到主界面
    private void redirectTo() {
        Intent intent = new Intent(this, MainActivity.class);
        startActivity(intent);
        finish();
    }
}

2.3、 布局分析

从布局文件的代码中可以知道,这是一个帧布局FrameLayout,并没有包含欢迎图片的Imageview,从可维护性的角度来说,这里直接包含欢迎图片应该是简单而且比较合理的。

开源中国(OSChina)源码解析(2)——闪屏页_第3张图片

回到清单文件,我们会发现启动页面指定了一个启动主题

android:theme="@style/App.Theme.Launch"

路径:OSChina\app\src\main\res\values\theme.xml


<resources>
    
    <style name="App.Theme.Launch" parent="Base.App.Theme">
        "android:windowBackground">@mipmap/welcome
        "android:windowNoTitle">true
        "android:windowFullscreen">true
        "android:windowContentOverlay">@null
    style>

    <style name="Base.App.Theme" parent="Base.App.Theme.Light">
        "windowActionBar">false
        "windowNoTitle">true
    style>
resources>

通过阅读上面的主题代码,我们可以得到以下几点:

  • 欢迎图片是通过windowBackground属性进行指定的,而主题是优先于布局文件加载的。
  • 通过windowFullscreen属性隐藏状态栏。
  • 通过windowNoTitle属性隐藏标题栏。

2.4、 通过主题加载背景图片

在上一节中,我们有一个问题就是,为什么不直接在布局文件中指定欢迎图片,而是在主题中指定。如果你亲自动手去写了一遍代码以后,细心的你就会发现,在应用启动后,会有一个短暂的白画面,然后才是欢迎图。

原因就是setContentView(R.layout.app_start)需要解析时间,而主题是优先于布局文件加载的,利用这个特性就可以解决短暂白画面的问题。这个套路你学会了吗?

3、总结

今天我们分析了开源中国的闪屏页的源码,大家有时间,可以自己新建一个工程,然后一步步的去实现它,相信你会有很多收获的。

你可能感兴趣的:(源码分析(OSChina))