前言
在开源中国推出Android客户端时就想研究其源码了,只可惜行动远不及心动来得快。趁着心未老,脚力尚可的时候,多搬几块砖吧。接下来的几天,我就和大家一起来学习开源中国的Android客户端的源码。大家也知道,阅读源码是学习编程的一种“捷径”,然而单纯地读源码却很难坚持下去。这次,我就打破常规,以一种“以写代读”的方式来重写一遍应用。我将这个“新”的应用命名为OscHub,因它的实现基本遵照了原客户端的实现方式,故名曰“抄袭”。OscHub的一切版权仍归开源中国所有。
话不多说,既然是抄袭*开源中国*Android客户端,我们首先应该拿到其源码,以方便更好的“抄袭”。下载源码请移步这里。
现在我们已经有了抄袭的材料,就开启我们的抄袭之路吧。
打开你的Android Studio(Eclipse用户请自行解决),创建一个名为OscHub的工程(你也可以起一个任何你喜欢的工程名)。这里我使用了自己的包名ml.uuku.oschub,大家也可以替换成自己喜欢的包名。
工程创建好后,我们直接用开源中国客户端的res目录(除了layout目录)替换掉自己工程的res目录,并修改strings.xml的app_name值为我们的应用名OscHub。只所以没有替换layout目录,是因为layout目录中的很多布局文件使用了自定义的控件,由于我们目前还没有创建这些控件,会导致IDE无法运行我们的“半成品”。与此同时,我们的应用仍然遵照原客户端的包结构形式,在编写代码的工程中,所有类名仍然与原客户端的类名一致。这样做的目的就是为了方便大家能随时查看原代码,并且能将精力聚焦到业务代码的书写,而不用去考虑每个页面的布局和交互效果。后面如果有时间,我会和大家一起来去分析这些布局文件,尤其是theme相关的文件和交互效果的实现,如drawable和color目录下的文件。有兴趣的朋友也可以自己去实现这些布局相关的文件。
我们的应用只支持4.0及以上版本(Level==14),所以原代码中有关版本兼容性问题在OscHub中并没有完全保留。另,所有类文件所在的包都依照原代码包结构,后文中只会提到类名,而没有指定全限定名,请读者朋友参照源码阅读此系列文章。
下面正式开始码字了
在包base下创建类BaseApplication
并继承自Application
。本类中主要提供了对于SharedPreferences
的操作
public class BaseApplication extends Application {
private static String PREF_NAME = "osch_createivelocker.pref";
static Context _context;
static Resources _resources;
@Override
public void onCreate() {
super.onCreate();
_context = getApplicationContext();
_resources = getResources();
}
public static synchronized BaseApplication context() {
return (BaseApplication) _context;
}
public static Resources resources() {
return _resources;
}
public static SharedPreferences getPreferences() {
return context().getSharedPreferences(PREF_NAME, Context.MODE_MULTI_PROCESS);
}
public static SharedPreferences getPreferences(String prefName) {
return context().getSharedPreferences(prefName, Context.MODE_MULTI_PROCESS);
}
public static void set(String key, int value) {
SharedPreferences.Editor editor = getPreferences().edit();
editor.putInt(key, value);
editor.apply();
}
public static void set(String key, boolean value) {
SharedPreferences.Editor editor = getPreferences().edit();
editor.putBoolean(key, value);
editor.apply();
}
public static void set(String key, String value) {
SharedPreferences.Editor editor = getPreferences().edit();
editor.putString(key, value);
editor.apply();
}
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);
}
}
然后创建一个BaseApplication
的子类AppContext
:
public class AppContext extends BaseApplication {
/**
* 是否是首次启动
*/
public static boolean isFirstStart() {
return getPreferences().getBoolean(AppConfig.KEY_FIRST_START, false);
}
/**
* 夜间模式
*/
public static boolean getNightModeSwitch() {
return getPreferences().getBoolean(AppConfig.KEY_NIGHT_MODE_SWITCH, false);
}
/**
* 设置夜间模式
*/
public static void setNightModeSwitch(boolean on) {
}
}
记得在我们的AndroidManifest.xml
中配置该Application哦:)
为方便对所有Activity的管理,我们提供一个Activity管理器AppManager
:
public class AppManager {
private static Stack<Activity> activityStack;
private static AppManager instance;
private AppManager() {
}
/**
* 单例模式
*/
public static AppManager getAppManager() {
if (instance == null) {
instance = new AppManager();
}
return insta