SpintNBA项目模仿笔记(一)随机启动图

来源:互联网 发布:马尔科夫转移矩阵法 编辑:程序博客网 时间:2024/06/06 02:12

最近匆匆看了许多开源项目,SpintNBA这个开源项目写的很好,打算用自己的方式重构,做不到的部分再返回来看源码,这样才有助于吸收。
源码地址:https://github.com/smuyyh/SprintNBA
源码:

没想到一开始就卡住了。。。我们知道,每个应用为了开启时不空白,有个启动页面,但是这个启动页面一般是固定的,但是这个项目的启动页是从几张图中随机选择一张,这是怎么做的呢?于是看回源码的style.xml:

<style name="AppTheme.Base" parent="Theme.AppCompat.Light.DarkActionBar">        <item name="windowActionBar">true</item>        <item name="windowNoTitle">true</item>        <!--<item name="actionBarSize">100dip</item>-->        <item name="colorPrimary">@color/colorPrimary</item>        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>        <item name="colorAccent">@color/colorAccent</item>        <item name="android:windowNoTitle">true</item>        <item name="android:windowIsTranslucent">true</item>        <item name="android:windowAnimationStyle">@style/SlideRightAnimation</item>        <item name="android:windowContentOverlay">@android:color/transparent</item>        <item name="android:windowBackground">@color/colorWindowBg</item>        <item name="android:actionMenuTextColor">@android:color/white</item>    </style>
<style name="NoTitleFullscreen" parent="AppTheme.Base">    <item name="android:windowNoTitle">true</item>    <item name="windowActionBar">false</item>    <item name="android:windowFullscreen">true</item>    <item name="android:windowContentOverlay">@null</item></style>

注意,中间有这么一句:

<item name="android:windowContentOverlay">@null</item>

这一句是关键,有了这一句,就可以不用担心启动图被白色或者黑色破坏了,可以按照自己的逻辑加载启动图。

写着写着,想起来没加自定义Application以及父类BaseActivity,问题又来了,自定义Application要放些什么,BaseActivity又该放些什么?

或许,你看到这个问题一笑置之,你这家伙是小白吧?好吧,我Andoid也工作一年半了,知道一般Crash和第三方一般放入Application,而BaseActivity应该放类似头部Toolbar初始化,点击事件分发这种的,只不过想看看作者有什么特别的东西,值得学习的。

自定义Application,onCreate()中,作者的特别做法:

 mContext = this; AppUtils.init(mContext);

mContext:作者设置的全局静态变量,Application的生存周期较长,用此方法可省去一些特殊位置获取Context的烦恼,另外一定程度上降低了Context为空的风险。

然后第二句,因为这个类不长,让我们看一下AppUtil的源码:

public class AppUtils {    private static Context mContext;    private static Thread mUiThread;    private static Handler sHandler = new Handler(Looper.getMainLooper());    public static void init(Context context) { //在Application中初始化        mContext = context;        mUiThread = Thread.currentThread();    }    public static Context getAppContext() {        return mContext;    }    public static AssetManager getAssets() {        return mContext.getAssets();    }    public static Resources getResource() {        return mContext.getResources();    }    public static boolean isUIThread() {        return Thread.currentThread() == mUiThread;    }    public static void runOnUI(Runnable r) {        sHandler.post(r);    }    public static void runOnUIDelayed(Runnable r, long delayMills) {        sHandler.postDelayed(r, delayMills);    }    public static void removeRunnable(Runnable r) {        if (r == null) {            sHandler.removeCallbacksAndMessages(null);        } else {            sHandler.removeCallbacks(r);        }    }}

这个类主要关注三点,

  1. mContext
    在此类中用于获取资源,没什么好说的

  2. sHandler
    这个很有用,因为Handler是导致内存泄漏的主因之一,这样写可以防止内存泄漏,而且handler.post,handler.postDelayed这两个方法用途也比较广,自从5.0以后,view.post方法有改动,最好使用handler.post,这样有助于兼容后面的版本。
    removeCallbacks在每次调用handler后使用,防止内存泄漏。可在base中destroy中调用:
    AppUtils.removeCallbacks(null)

  3. mUiThread
    这个用于Handler消息循环判断是否在主线程。

另:Application一般与项目名相同,看个人习惯。

个人认为这个类棒极了,于是写了三次加深印象,写着写着发现一点:初始化其实可以不必传入Context。因为下面的方法没有一个在application需要调用的,也就是说,在调用时,application已经完成了初始化,思考了一下,感觉改成这样比较好:

SprintNBA.getSuperContext().getResources();

然后,原项目报错了。
为啥呀?这样做不是比较好么0 0,我哪里错了???
这里写图片描述
于是看了一下,作者把一些常见工具类封装了一个包,里面有一些常用工具类,常用自定义控件,权限处理以及异常处理,好吧,这样做确实省时间,打算自己封装一个,不打算抄作者的。

原创粉丝点击