开源中国Android源码剖析(1)

本文是作者学习开源中国2.2.1版本Android APP源码的初步分析,主要关注AndroidManifest.xml及AppStart.java。作者在前言中提到选择此版本因为其易于在eclipse环境中编译。在AndroidManifest.xml中,确定了主入口Activity为AppStart。接着探讨了AppStart.java,同时提出了对PreferenceHelper用途的疑问,期待了解该框架的同学提供见解。博客作为系列文章的第一篇,作者承诺会继续深入分析并分享更多内容。
摘要由CSDN通过智能技术生成

前言

前不久打算学习下开源的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) {}
        });
    }


2. onResume()接口重载,从实现来看可能是负责版本管理。用的接口是PreferenceHelper,来源于kjframe框架(org.kymjs.kjframe.utils.PreferenceHelper)。下面是框架介绍:

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


3. 清除图片缓存,也是用的kjframe框架。

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


5. activity堆栈式管理类AppManager类的实现,APP中所有的activity都采用这个类就行管理。该类是一个单例模式,看源码就知。

/**
 * 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类的分析,未完待续。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值