OSChina App代码分析之BaseApplication

转载请标明出处:
http://blog.csdn.net/zq2114522/article/details/50444217;
本文出自:【梁大盛的博客】

OSChina App代码分析之BaseApplication

  • 引:进入程序以后Application类是一个不的不进行分析的大类.在OSChina当中Application承当着保存配置数据的角色此外还提供显示提示的功能(Toast).当然他的子类AppContext扩张了更多的功能.这就是后话了.这一篇文章当中具体分析BaseApplication类

    首先抛出通过阅读BaseApplication类到底学到什么东西.

    1. sdk版本判断
    2. BaseApplication充当这个应用程序运行过程中的简单数据存储角色(通过sharedPreferences实现)
    3. 自定义Toast

BaseApplication.java

package net.oschina.app.base;

import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.res.Resources;
import android.os.Build;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import net.oschina.app.R;
import net.oschina.app.util.StringUtils;

@SuppressLint("InflateParams")
public class BaseApplication extends Application {
    //杂七杂八的数据都是存在在这个xml文件
    private static String PREF_NAME = "creativelocker.pref";
    //用来存储cache文件更新时间戳
    private static String LAST_REFRESH_TIME = "last_refresh_time.pref";
    static Context _context;
    static Resources _resource;
    //上一次Toast显示的文字
    private static String lastToast = "";
    //上一次Toast显示的时间
    private static long lastToastTime;

    //当前framework是否大于等于GINGERBREAD(Andrdoi 2.3)
    //因为在GINGERBREAD以前的更新sharedPreferences只能
    //调用commit函数,在GINGERBREAD及其以
    //后的版本可以调用性能更好的apply函数
    private static boolean sIsAtLeastGB;

    //判断当前framework版本是否大于等于GINGERBREAD
    //Build.VERSION.SDK_INIT已int形式保存当前framework版本号
    //在Build.VERSION_CODES类里保存所知的版本号
    static {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
            sIsAtLeastGB = true;
        }
    }

    @Override
    public void onCreate() {
        super.onCreate();
        _context = getApplicationContext();
        _resource = _context.getResources();
    }

    public static synchronized BaseApplication context() {
        return (BaseApplication) _context;
    }

    public static Resources resources() {
        return _resource;
    }

    /**
     * 放入已读文章列表中
     *
     */
    public static void putReadedPostList(String prefFileName, String key,
                                         String value) {
        SharedPreferences preferences = getPreferences(prefFileName);
        int size = preferences.getAll().size();
        Editor editor = preferences.edit();
        //这里有一个bug?
        //clear函数,只是把editor里面的list清空.并且会导致后在调用commit函数不会生效.
        //具体
        if (size >= 100) {
            editor.clear();
        }
        editor.putString(key, value);
        apply(editor);
    }

    /**
     * 读取是否是已读的文章列表
     *
     * @return
     */
    public static boolean isOnReadedPostList(String prefFileName, String key) {
        return getPreferences(prefFileName).contains(key);
    }

    /**
     * 记录列表上次刷新时间
     *
     * @param key
     * @param value
     * @return void
     * @author 火蚁
     * 2015-2-9 下午2:21:37
     */
    public static void putToLastRefreshTime(String key, String value) {
        SharedPreferences preferences = getPreferences(LAST_REFRESH_TIME);
        Editor editor = preferences.edit();
        editor.putString(key, value);
        apply(editor);
    }

    /**
     * 获取列表的上次刷新时间
     *
     * @param key
     * @return
     * @author 火蚁
     * 2015-2-9 下午2:22:04
     */
    public static String getLastRefreshTime(String key) {
        return getPreferences(LAST_REFRESH_TIME).getString(key, StringUtils.getCurTimeStr());
    }

    //GINGERBREAD以后的framework调用apply函数提交修改.之前的版本调用commit函数提交修改.
    @TargetApi(Build.VERSION_CODES.GINGERBREAD)
    public static void apply(SharedPreferences.Editor editor) {
        if (sIsAtLeastGB) {
            editor.apply();
        } else {
            editor.commit();
        }
    }

    public static void set(String key, int value) {
        Editor editor = getPreferences().edit();
        editor.putInt(key, value);
        apply(editor);
    }

    public static void set(String key, boolean value) {
        Editor editor = getPreferences().edit();
        editor.putBoolean(key, value);
        apply(editor);
    }

    public static void set(String key, String value) {
        Editor editor = getPreferences().edit();
        editor.putString(key, value);
        apply(editor);
    }

    public static boolean get(String key, boolean defValue) {
        return getPreferences().getBoolean(key, defValue);
    }

    public static String get(String key, String defValue) {
        return getPreferences().getString(key, defValue);
    }

    public static int get(String key, int defValue) {
        return getPreferences().getInt(key, defValue);
    }

    public static long get(String key, long defValue) {
        return getPreferences().getLong(key, defValue);
    }

    public static float get(String key, float defValue) {
        return getPreferences().getFloat(key, defValue);
    }

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    public static SharedPreferences getPreferences() {
        SharedPreferences pre = context().getSharedPreferences(PREF_NAME,
                Context.MODE_MULTI_PROCESS);
        return pre;
    }

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    public static SharedPreferences getPreferences(String prefName) {
        return context().getSharedPreferences(prefName,
                Context.MODE_MULTI_PROCESS);
    }

    public static int[] getDisplaySize() {
        return new int[]{getPreferences().getInt("screen_width", 480),
                getPreferences().getInt("screen_height", 854)};
    }

    //将屏幕规格信息存储起来
    public static void saveDisplaySize(Activity activity) {
        DisplayMetrics displaymetrics = new DisplayMetrics();
        activity.getWindowManager().getDefaultDisplay()
                .getMetrics(displaymetrics);
        SharedPreferences.Editor editor = getPreferences().edit();
        editor.putInt("screen_width", displaymetrics.widthPixels);
        editor.putInt("screen_height", displaymetrics.heightPixels);
        editor.putFloat("density", displaymetrics.density);
        editor.commit();
    }

    public static String string(int id) {
        return _resource.getString(id);
    }

    public static String string(int id, Object... args) {
        return _resource.getString(id, args);
    }

    public static void showToast(int message) {
        showToast(message, Toast.LENGTH_LONG, 0);
    }

    public static void showToast(String message) {
        showToast(message, Toast.LENGTH_LONG, 0, Gravity.BOTTOM);
    }

    public static void showToast(int message, int icon) {
        showToast(message, Toast.LENGTH_LONG, icon);
    }

    public static void showToast(String message, int icon) {
        showToast(message, Toast.LENGTH_LONG, icon, Gravity.BOTTOM);
    }

    public static void showToastShort(int message) {
        showToast(message, Toast.LENGTH_SHORT, 0);
    }

    public static void showToastShort(String message) {
        showToast(message, Toast.LENGTH_SHORT, 0, Gravity.BOTTOM);
    }

    public static void showToastShort(int message, Object... args) {
        showToast(message, Toast.LENGTH_SHORT, 0, Gravity.BOTTOM, args);
    }

    public static void showToast(int message, int duration, int icon) {
        showToast(message, duration, icon, Gravity.BOTTOM);
    }

    public static void showToast(int message, int duration, int icon,
                                 int gravity) {
        showToast(context().getString(message), duration, icon, gravity);
    }

    public static void showToast(int message, int duration, int icon,
                                 int gravity, Object... args) {
        showToast(context().getString(message, args), duration, icon, gravity);
    }

    //上面一大寸showToast总归到要走到这里
    public static void showToast(String message, int duration, int icon,
                                 int gravity) {
        //message为nul或者为"",就不好意思咯.一律居于门外
        if (message != null && !message.equalsIgnoreCase("")) {
            long time = System.currentTimeMillis();
            //如果message显示的信息和上一回显示的是一样必须有2S的间隔
            //如果message显示的信息和上一回显示的不一样那么立马请进
            if (!message.equalsIgnoreCase(lastToast)
                    || Math.abs(time - lastToastTime) > 2000) {
                //根据layout文件生成View
                //R.layout.view_toast就是一个相对布局里面,横着放着一个ImageView和TextView
                //因为ImageView有时候会隐藏,TextView又是依赖ImageView布局的.
                //所以TextView设置了layout_alignWithParentIfMissing属性
                View view = LayoutInflater.from(context()).inflate(
                        R.layout.view_toast, null);
                ((TextView) 
//设置文字                view.findViewById(R.id.title_tv)).setText(message);
                //还可设置图片哦
                if (icon != 0) {
                    ((ImageView) view.findViewById(R.id.icon_iv))
                            .setImageResource(icon);
                    ((ImageView) view.findViewById(R.id.icon_iv))
                            .setVisibility(View.VISIBLE);
                }
                //创建Toast实例
                Toast toast = new Toast(context());
                //设置Toast实例的View
                toast.setView(view);
                //设置对其方式
                if (gravity == Gravity.CENTER) {
                    toast.setGravity(gravity, 0, 0);
                } else {
                    toast.setGravity(gravity, 0, 35);
                }

                //Toast显示时间
                toast.setDuration(duration);
                toast.show();
                //记录显示的文字
                lastToast = message;
                //记录此次的现实时间戳
                lastToastTime = System.currentTimeMillis();
            }
        }
    }
}

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/toast_background" >

    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingBottom="@dimen/space_8"
        android:paddingLeft="10.0dip"
        android:paddingRight="10.0dip"
        android:paddingTop="@dimen/space_8" >

        <ImageView
            android:id="@+id/icon_iv"
            android:layout_width="wrap_content"
            android:layout_height="40.0dip"
            android:layout_centerVertical="true"
            android:layout_marginRight="@dimen/space_8"
            android:scaleType="fitCenter"
            android:visibility="gone" />

        <TextView
            android:id="@+id/title_tv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignWithParentIfMissing="true"
            android:layout_toRightOf="@id/icon_iv"
            android:gravity="center_vertical"
            android:textColor="@color/white"
            android:textSize="16.0dip" />
    RelativeLayout>

FrameLayout>

总结:
1.SDK framework的判断通过两个关键类Build.VERSION和Build.VERSION_CODES.Build.VERSION记录着当前的版本是多少.Build.VERSION_CODES里面记录了所有版本号的信息

2.基于Application类的特殊性.因为在每个一Activity都可以访问到的相当一个单类?.Application在很多时候也充当保存配置的角色.

3.在使用Toast多数情况下都是调用Toast的静态方法makeText.事实上除了这方法.使用Toast提供构造函数的能更灵活使用Toast.灵活体现在能自定义Toast显示内部的View.还有就是可以设置Toast显示的位置.可以告诉妈妈Toast不用在呆在底部了!

附:
在api里面很清楚可以看到apply函数在GINGERBREAD才新加进的

OSChina App代码分析之BaseApplication_第1张图片

参考:
1:SharedPreferences http://www.android-doc.com/reference/android/content/SharedPreferences.html

2:Editor http://www.android-doc.com/reference/android/content/SharedPreferences.Editor.html

3:Toast http://www.android-doc.com/reference/android/widget/Toast.html

4:Build.VERSION http://www.android-doc.com/reference/android/os/Build.VERSION.html

5:Build.VERSION_CODES http://www.android-doc.com/reference/android/os/Build.VERSION_CODES.html

你可能感兴趣的:(OSChina)