前言
前不久打算学习下开源的Android APP源码,github和OSCHINA上找了蛮久,发现oschina的2.2.1版本适配于eclipse界面最容易编译,于是就开始了oschina的源码之旅。希望把源码分析的路一直走下去并记录博客分享出来。
AndroidManifest.xml
从主界面的AndroidManifest.xml布局文件上看,oschina的main activity是AppStart:
<activity
android:name=".<strong>AppStart</strong>"
android:label="@string/app_name"
android:screenOrientation="portrait"
android:theme="@style/Theme.AppStartLoad" >
<intent-filter>
<action android:name="<strong>android.intent.action.MAIN</strong>" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
于是我们就找到AppStart类定义,位于app/src/net/oschina/app/AppStart.java。这个main activity看起来比较简单,实现的功能是APP启动时一个透明的动画效果,然后显示出主界面。
AppStart.java
AppStart的源码较少,直接贴出来供大家参考:
1. OnCreate函数在activity被创建时候调用,首先是判断当前的mainactivity是否会create出双实例。因为所有的activity都是AppManager负责管理的,先找出当前活动的MainActivity,判断是否已经存在,存在的话就finish掉。AppManager是activity堆栈式管理的一个类,实现了APP所有的activity功能,下面会贴出源码。
public class AppStart extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 防止第三方跳转时出现双实例
Activity aty = AppManager.getActivity(MainActivity.class);
if (aty != null && !aty.isFinishing()) {
finish();
}
//弹出“开源中国”的欢迎界面,使用AlphaAnimation类实现动画效果。
//渐变从0.5f到1.0f,表示从半透明到不透明,持续0.8s。
final View view = View.inflate(this, R.layout.app_start, null);
setContentView(view);
// 渐变展示启动屏
AlphaAnimation aa = new AlphaAnimation(0.5f, 1.0f); //渐变(从半透明到不透明)
aa.setDuration(800); //持续时间
view.startAnimation(aa);
aa.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationEnd(Animation arg0) {
redirectTo(); //动画结束,启动uploadLog日志服务,启动MainActivity主界面(就是oschina显示资讯、热点、博客的界面)
}
@Override
public void onAnimationRepeat(Animation animation) {}
@Override
public void onAnimationStart(Animation animation) {}
});
}
KJFrameForAndroid 又叫KJLibrary,是一个android的orm 和 ioc 框架。同时封装了android中的Bitmap与Http操作的框架,使其更加简单易用;KJFrameForAndroid的设计思想是通过封装Android原生SDK中复杂的复杂操作而达到简化Android应用级开发,最终实现快速而又安全的开发APP。我们提倡用最少的代码,完成最多的操作,用最高的效率,完成最复杂的功能。使用KJFrameForAndroid,你可以只用一行代码就完成http请求、网络图片加载、数据库数据保存或读取。
有熟悉该框架的同学可以给介绍下PreferenceHelper的用途?
@Override
protected void onResume() {
super.onResume();
int cacheVersion = PreferenceHelper.readInt(this, "first_install",
"first_install", -1);
int currentVersion = TDevice.getVersionCode();
if (cacheVersion < currentVersion) {
PreferenceHelper.write(this, "first_install", "first_install",
currentVersion);
cleanImageCache();
}
}
private void cleanImageCache() {
final File folder = FileUtils.getSaveFolder("OSChina/imagecache");
KJAsyncTask.execute(new Runnable() {
@Override
public void run() {
for (File file : folder.listFiles()) {
file.delete();
}
}
});
}
4. 跳转到函数,实现从AppStart这个activity到MainActivity的工作,同时启动上传LOG日志的服务。
private void redirectTo() {
//启动上传LOG日志的服务
Intent uploadLog = new Intent(this, LogUploadService.class);
startService(uploadLog);
//启动MainActivity,用的都是Intent就行activity的通讯,但是没有数据需要传递
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
finish();
}
/**
* activity堆栈式管理
*
* @author FireAnt(http://my.oschina.net/LittleDY)
* @created 2014年10月30日 下午6:22:05
*
*/
public class AppManager {
private static Stack<Activity> activityStack;
private static AppManager instance;
//构造函数private,不可直接实例,必须使用getAppManager()接口获取实例。
private AppManager() {}
/**
* 单例模式
*/
public static AppManager getAppManager() {
if (instance == null) {
instance = new AppManager();
}
return instance;
}
/**
* 添加Activity到堆栈
*/
public void addActivity(Activity activity) {
if (activityStack == null) {
activityStack = new Stack<Activity>();
}
activityStack.add(activity);
}
/**
* 获取当前Activity(堆栈中最后一个压入的)
*/
public Activity currentActivity() {
Activity activity = activityStack.lastElement();
return activity;
}
/**
* 结束当前Activity(堆栈中最后一个压入的)
*/
public void finishActivity() {
Activity activity = activityStack.lastElement();
finishActivity(activity);
}
/**
* 结束指定的Activity
*/
public void finishActivity(Activity activity) {
if (activity != null && !activity.isFinishing()) {
activityStack.remove(activity);
activity.finish();
activity = null;
}
}
/**
* 结束指定类名的Activity
*/
public void finishActivity(Class<?> cls) {
for (Activity activity : activityStack) {
if (activity.getClass().equals(cls)) {
finishActivity(activity);
break;
}
}
}
/**
* 结束所有Activity
*/
public void finishAllActivity() {
for (int i = 0, size = activityStack.size(); i < size; i++) {
if (null != activityStack.get(i)) {
finishActivity(activityStack.get(i));
break;
}
}
activityStack.clear();
}
/**
* 获取指定的Activity
*
* @author kymjs
*/
public static Activity getActivity(Class<?> cls) {
if (activityStack != null)
for (Activity activity : activityStack) {
if (activity.getClass().equals(cls)) {
return activity;
}
}
return null;
}
/**
* 退出应用程序
*/
public void AppExit(Context context) {
try {
finishAllActivity();
// 杀死该应用进程
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(0);
} catch (Exception e) {
}
}
}
第一篇微博,大家多多提意见!后面是MainActivity类的分析,未完待续。。。