1. 程式人生 > >今日頭條開源項目 分析筆記1

今日頭條開源項目 分析筆記1

tde time() multi 3.1 pat ems 判斷網絡 其他 播放

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();
    }
}
View Code

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;
    }
    
}
View Code

6.2.判斷網絡

  判斷是否有網絡,是否連接了WIFI,移動網絡是否開啟。  



今日頭條開源項目 分析筆記1