今日头条开源项目 分析笔记1

1.InitApp==>项目的入口Application

1.1.继承了MultiDexApplication

  超过65K方法的APP,会遇到65535的错误。原因就是为了支持比较大型的APP而产生。

  参考文章:Android分包MultiDex原理详解。

1.2.在build.gradle中修改multiDexEnabled

  

  然后记得在dependencies中加:

  implementation ‘com.android.support:multidex:1.0.2‘

1.3.用第三方库facebook的开源调试工具==Stetho

  参考文章:Stetho简化Android调试

  作用:可以用谷歌浏览器调试手机,获得非常详细的数据。

  具体方式,参考上面文章。

  下面讲解这个项目是如何使用的。

  封装好这个SdkManager,主要就是为了初始化Stetho。

  

  第二个函数涉及到了OkHttpClient

  参考这篇文章了解HttpLoggingInterceptor。

  HttpLoggingInterceptor该拦截器用于记录应用中的网络请求的信息。

  因为这里只有调试的时候才会用到这个工具,所以在src目录下创建了两个包,名字相同。

  一个叫做debug,一个叫做release。

  然后在build.gradle中也做相应的改变==>

  debugCompile ‘com.facebook.stetho:stetho:1.5.0‘

  debugImplementation ‘com.squareup.okhttp3:logging-interceptor:3.9.0‘

  implementation ‘com.squareup.okhttp3:okhttp:3.9.0‘

1.4.BuildConfig:Gradle自定义你的BuildConfig

  参考文章:BuildConfig:Gradle自定义你的BuildConfig

  

  直接在buildTypes中修改或添加一些属性。

  BuildType是系统直接产生的一个类,可以判断当前应用是Debug模式还是release模式。

1.5.Android Studio 配置Gradle

  参考文章:Android Studio 配置Gradle(包括signingConfigs、buildTypes、重命名等)。

  

  在build.gradle中声明一个函数,获取当前时间。

  

  生成apk文件重命名。

2.启动页设置

2.1.新建一个启动页

  

2.2.配置清单

  

  参考这篇文章了解android:configChanges的作用。

  orientation==>屏幕方向改变了。

  screenSize==>屏幕大小改变了。

  uiMode==>用户的模式发生了变化。

  切屏还是会重新调用各个生命周期,切横屏、竖屏只会执行一次。

2.3.设置android:theme主题

  

  在styles.xml文件中加上一个主题风格,用作启动页的主题。

  用android:windowBackground来设置主题背景。

2.4.drawable文件夹中新建一个样式

  

  第一个item是背景颜色。

  第二个item将中心点设置为logo。

3.BaseActivity使用rxlifecyle框架

3.1.使用原因

  实际的项目中会出现很多订阅关系,那么取消订阅的代码也就越来越多。造成了项目很难维护。所以我们必须寻找

  其他可靠简单可行的方式。

  github地址:https://github.com/trello/RxLifecycle

3.2.使用方法

  在build.gradle中添加引用

  implementation ‘com.trello.rxlifecycle2:rxlifecycle:2.0.1‘

  implementation ‘com.trello.rxlifecycle2:rxlifecycle-components:2.0.1‘

3.3.然后将BaseActivity继承RxAppCompatActivity即可。

4.滑动切换Activity使用Slidr框架

4.1.效果预览

  参考文章:滑动切换Activity。

  github地址:https://github.com/r0adkll/Slidr

  

4.2.导入Slidr到项目

  先在build.gradle添加==>

  compile ‘com.r0adkll:slidableactivity:2.0.5‘

4.3.Slidr使用

  需要准备两个Activity,唯一需要注意的是Activity的Theme需要重写下面的代码

  

  然后需要在两个Activity的布局文件中的最顶层的Layout中,为Activity设置背景(否则Activity会是透明的)

  

  然后在代码中配置:

  

  .primaryColor(primary)==>滑动时状态栏的渐变介绍的颜色

  .secondaryColor(secondary)==>滑动时状态栏的渐变开始的颜色

  .scrimColor(Color.BLACK)==>滑动时Activity之间的颜色

  .position(SlidrPosition.LEFT)==>从左边滑动

  .scrimStartAlpha(0.8f)==>滑动开始时两个Activity之间的透明度

  .scrimEndAlpha(0f)==>滑动结束时两个Activity之间的透明度

  .velocityThreshold(5f)==>超过这个滑动速度,忽略位移限定值就切换Activity

  .distanceThreshold(.35f)==>滑动位移占屏幕的百分比,超过这个间距就切换Activity

5.SettingUtil

5.1.源代码如下

public class SettingUtil {
    private SharedPreferences setting= PreferenceManager.getDefaultSharedPreferences(InitApp.AppContext);

    private static final class SettingUtilInstance{
        private static final SettingUtil instance=new SettingUtil();
    }

    public static SettingUtil getInstance(){
        return SettingUtilInstance.instance;
    }

    /**
     * 获取是否开启无图模式
     * @return
     */
    public boolean getIsNoPhotoMode(){
        return setting.getBoolean("switch_noPhotoMode",false)&& NetWorkUtil.isMobileConnected(InitApp.AppContext);
    }

    /**
     * 获取主题颜色
     * @return
     */
    public int getColor(){
        int defaultColor=InitApp.AppContext.getResources().getColor(R.color.colorPrimary);
        int color=setting.getInt("color",defaultColor);
        if((color!=0)&& Color.alpha(color)!=255){
            return defaultColor;
        }
        return color;
    }

    /**
     * 设置主题颜色
     * @param color
     */
    public void setColor(int color){
        setting.edit().putInt("color",color).apply();
    }

    /**
     * 获取是否开启夜间模式
     * @return
     */
    public boolean getIsNightMode(){
        return setting.getBoolean("switch_nightMode",false);
    }

    /**
     * 设置夜间模式
     * @param flag
     */
    public void setIsNightMode(boolean flag){
        setting.edit().putBoolean("switch_nightMode",flag).apply();
    }

    /**
     * 获取是否开启自动切换夜间模式
     * @return
     */
    public boolean getIsAutoNightMode(){
        return setting.getBoolean("auto_nightMode",false);
    }

    /**
     * 设置开启自动切换夜间模式
     * @param flag
     */
    public void setIsAutoNightMode(boolean flag){
        setting.edit().putBoolean("auto_nightMode",flag).apply();
    }

    public String getNightStartHour(){
        return setting.getString("night_startHour","22");
    }

    public void setNightStartHour(String nightStartHour){
        setting.edit().putString("night_startHour",nightStartHour).apply();
    }

    public String getNightStartMinute(){
        return setting.getString("night_startMinute","00");
    }

    public void setNightStartMinute(String nightStartMinute){
        setting.edit().putString("night_startMinute",nightStartMinute).apply();
    }

    public String getDayStartHour(){
        return setting.getString("day_startHour","06");
    }

    public void setDayStartHour(String day_startHour){
        setting.edit().putString("day_startHour",day_startHour).apply();
    }

    public String getDayStartMinute(){
        return setting.getString("day_startMinute","00");
    }

    public void setDayStartMinute(String day_startMinute){
        setting.edit().putString("day_startMinute",day_startMinute).apply();
    }

    /**
     * 获取是否开启导航栏上色
     * @return
     */
    public boolean getNavBar(){
        return setting.getBoolean("nav_bar",false);
    }

    /**
     * 获取是否开启视频强制横屏
     * @return
     */
    public boolean getIsVideoForceLandscape(){
        return setting.getBoolean("video_force_landscape",false);
    }

    /**
     * 获取图标值
     * @return
     */
    public int getCustomIconValue(){
        String s=setting.getString("custom_icon","0");
        return Integer.parseInt(s);
    }

    /**
     * 获取滑动返回值
     * @return
     */
    public int getSlidable(){
        String s=setting.getString("slidable","1");
        return Integer.parseInt(s);
    }

    /**
     * 获取是否开启视频自动播放
     * @return
     */
    public boolean getIsVideoAutoPlay(){
        return setting.getBoolean("video_auto_play",false)&&NetWorkUtil.isWifiConnected(InitApp.AppContext);
    }

    /**
     * 获取字体大小
     * @return
     */
    public int getTextSize(){
        return setting.getInt("textsize",16);
    }

    /**
     * 设置字体大小
     * @param textSize
     */
    public void setTextSize(int textSize){
        setting.edit().putInt("textsize",textSize).apply();
    }

    public boolean getIsFirstTime(){
        return setting.getBoolean("first_time",true);
    }

    public void setIsFirstTime(boolean flag){
        setting.edit().putBoolean("first_time",flag).apply();
    }
}

5.2.这个类的作用

  利用SharePreferences来记住一些需要记住的用户设置数据。

  比如是否开启无图模式

  设置和获取主题颜色

  设置夜间模式

  设置开启视频强制横屏模式

  设置字体大小

  判断是否是第一次

6.NetWorkUtil

6.1.源代码

public class NetWorkUtil {

    public static boolean isNetWorkConnected(Context context){
        if(context!=null){
            ConnectivityManager manager=(ConnectivityManager)
                    context.getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo networkInfo=manager.getActiveNetworkInfo();
            return null != networkInfo&&networkInfo.isAvailable();
        }
        return false;
    }

    public static boolean isWifiConnected(Context context){
        if(context!=null){
            ConnectivityManager manager=(ConnectivityManager)
                    context.getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo netWorkInfo=manager.getActiveNetworkInfo();
            if(null!=netWorkInfo&&netWorkInfo.getType()==ConnectivityManager.TYPE_WIFI){
                return netWorkInfo.isAvailable();
            }
        }
        return false;
    }

    public static boolean isMobileConnected(Context context){
        if(context!=null){
            ConnectivityManager manager=(ConnectivityManager)
                    context.getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo networkInfo=manager.getActiveNetworkInfo();
            if(null!=networkInfo&&networkInfo.getType()==ConnectivityManager.TYPE_MOBILE){
                return networkInfo.isAvailable();
            }
        }
        return false;
    }

}

6.2.判断网络

  判断是否有网络,是否连接了WIFI,移动网络是否开启。  

时间: 2024-10-24 23:15:28

今日头条开源项目 分析笔记1的相关文章

vue2.0仿今日头条开源项目

vue-toutiao 这是用 vue.js 2.0 高仿 今日头条 的移动端项目,结合了原生app的部分功能以及网页版. 前言 本人是 今日头条 的重度用户,在学习vue.js过程中,在GitHub上看到了很多高仿webapp的好项目.由此在有了一定的技术积累后,开始构思使用Vue写今日头条,一是自己对于头条的喜爱,另外也是对于自己学习成果的检验. 技术栈 vue.js 2.0全家桶(vue.vuex.vue-router) axios.jsonp element-ui.iview vue-l

TouTiao开源项目 分析笔记9 实现一个问答主页面

1.根据API返回创建几个基础的Bean 1.1.WendaArticleDataBean类 API返回的数据如下: /** * cell_type : 36 * extra : {"wenda_video":[],"show_answer":false,"video_large_card":false,"label_style":{"color_type":0,"name":"

TouTiao开源项目 分析笔记12 从总体到局部 构建视频主页面

1.构建视频主列表的整体碎片VideoTabLayout 1.1.首先创建一个VideoTabLayout package com.jasonjan.headnews.module.video; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.design.widget.TabLayout; import android.support.v4.app.Frag

TouTiao开源项目 分析笔记19 问答内容

1.真实页面预览 1.1.成果预览 首先是问答列表 然后每个item设置点击事件,进入问答内容列表 然后每一个问答内容也设置点击事件,进入问答详情 1.2.触发事件. 在WendaArticleOneImgViewBinder中,设置item的点击事件, 跳转到WendaContentActivity. 在WendaArticleTextViewBinder中,设置item的点击事件, 跳转到WendaContentActivity. 在WendaArticleThreeImgViewBinde

TouTiao开源项目 分析笔记3

1.搭建NewsTabLayout片段 1.1.加载布局 @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_news_tab, container, false); initV

TouTiao开源项目 分析笔记4

1.一些示例文字 第一段 2.一些示例文字 第二段 3.一些示例文字 第三段 4.一些示例文字 第四段 5.一些示例文字 第五段 6.一些示例文字 第六段

TouTiao开源项目 分析笔记5

1.深入理解RxJava 1.1.基本上现在的APP都会有请求网络,然后处理回调的业务吧. 如果请求的数据很多,业务越来越复杂,怎么处理呢? 这里我用到了RxJava来帮我处理业务. RxJava主要复杂事件的通知和订阅.这个挺起来没有什么概念. 其实说白了,RxJava就是优雅地处理函数回调. 1.2.推荐参考文章:我们为什么要用rxjava? 这篇文章以一个案例的方式,详细解释了rxjava的功能. 下面我来深入分析一下. 1.3.以通常思维模式来处理这个案例. 这个比较好理解,但是这种方式

TouTiao开源项目 分析笔记7

1.一些示例文字 第一段 2.一些示例文字 第二段 3.一些示例文字 第三段 4.一些示例文字 第四段 5.一些示例文字 第五段 6.一些示例文字 第六段

树莓派开源项目开发笔记

2.led 没啥新的东西 就是GPIO操作 3.key 可以设置中断方式的来实现GPIO操作 wiringPiISR(gpio_num, rise/fall_edge, isr_server_addr) 4. gpio load i2c时候出现问题 gpio: Unable to load/unload modules as this Pi has the device tree enabled. You need to run the raspi-config program (as root