Android应用开发软件工程师,自己动手打造自己的专属应用框架

Android应用开发程序员,自己动手打造自己的专属应用框架转载请标明出处:http://http://blog.csdn.net/andr

Android应用开发程序员,自己动手打造自己的专属应用框架

转载请标明出处:http://http://blog.csdn.net/android_ls/article/details/12279097一、UML类图复习:

       UML类图中有些标记很容易混淆,这里先复习下,请大家看下面这幅图:

Android应用开发软件工程师,自己动手打造自己的专属应用框架

   注:这幅图来自《大话设计模式》这本书中的插图。

二、应用框架:

       A、基本概念

       抽象(抽出共同之现象)——在同领域的程序中,常含有许多类别,这些类别有其共同点,我们将类别之共同结构抽离出来,称为抽象类别。其抽象之步骤是: 1、观察几个相似的类别;2、分辨它们的异同点;3、把它们的共同点抽离出来。

       衍生(与众不同之现象)——基于通用结构里的抽象类别,添加些特殊功能(扩展),使之成为具体类别,再诞生对象。

       所以抽象类别的存在目的,是要用其衍生子类别,而不是由它本身来诞生对象。由于抽象类别本身不诞生对象,所以有些方法并不完整。反之,类别之内的方法,皆是完整的,而且要用来诞生对象,就称它为具体类别。所谓不完整就是方法的方法体从缺,只有方法的描述。

       B、打造自己的专属应用框架之类图:

Android应用开发软件工程师,自己动手打造自己的专属应用框架

       上图中有关网络模块的请查看 Android仿人人客户端(v5.7.1)——网络模块处理的架构 这篇博文。

       C、打造自己的专属应用框架之编码实现:

      BaseApplication类源码如下:

package com.lbt.hairdesigner;import android.app.Activity;import android.content.Context;import android.content.Intent;import android.os.Bundle;import android.view.Window;import android.widget.Toast;import com.lbt.hairdesigner.utils.LogUtil;/** * 功能描述:对Activity类进行扩展 * @author android_ls */public abstract class BaseActivity extends Activity {    /**     * LOG打印标签     */    private static final String TAG = BaseActivity.class.getSimpleName();        /**     * 全局的Context {@link #mContext = this.getApplicationContext();}     */    protected Context mContext;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        requestWindowFeature(Window.FEATURE_NO_TITLE);        int layoutId = getLayoutId();        if (layoutId != 0) {            setContentView(layoutId);            // 删除窗口背景            getWindow().setBackgroundDrawable(null);        }        mContext = this.getApplicationContext();        ((BaseApplication) this.getApplication()).addActivity(this);        // 向用户展示信息前的准备工作在这个方法里处理        preliminary();    }    /**     * 向用户展示信息前的准备工作在这个方法里处理     */    protected void preliminary() {        // 初始化组件        setupViews();        // 初始化数据        initialized();    }    /**     * 获取全局的Context     * @return {@link #mContext = this.getApplicationContext();}     */    public Context getContext() {        return mContext;    }    /**     * 布局文件ID     * @return     */    protected abstract int getLayoutId();    /**     * 初始化组件     */    protected abstract void setupViews();    /**     * 初始化数据     */    protected abstract void initialized();    /**     * Debug输出Log信息     * @param tag     * @param msg     */    protected void debugLog(String msg) {        LogUtil.d(TAG, msg);    }    /**     * Error输出Log信息     * @param msg     */    protected void errorLog(String msg) {        LogUtil.e(TAG, msg);    }        /**     * Info输出Log信息     * @param msg     */    protected void showLog(String msg) {        LogUtil.i(TAG, msg);    }        /**     * 长时间显示Toast提示(来自String)     * @param message     */    protected void showToast(String message) {        Toast.makeText(mContext, message, Toast.LENGTH_LONG).show();    }        /**     * 长时间显示Toast提示(来自res)     * @param resId     */    protected void showToast(int resId) {        Toast.makeText(mContext, getString(resId), Toast.LENGTH_LONG).show();    }        /**     * 短暂显示Toast提示(来自res)     * @param resId     */    protected void showShortToast(int resId) {        Toast.makeText(mContext, getString(resId), Toast.LENGTH_SHORT).show();    }    /**     * 短暂显示Toast提示(来自String)     * @param text     */    protected void showShortToast(String text) {        Toast.makeText(mContext, text, Toast.LENGTH_SHORT).show();    }        /**      * 通过Class跳转界面      **/    public void startActivity(Class<?> cls) {        startActivity(cls, null);    }    /**     * 含有Bundle通过Class跳转界面      **/    public void startActivity(Class<?> cls, Bundle bundle) {        Intent intent = new Intent();        intent.setClass(this, cls);        if (bundle != null) {            intent.putExtras(bundle);        }        startActivity(intent);        overridePendingTransition(R.anim.push_left_in, R.anim.push_left_out);    }    /**     * 通过Action跳转界面     **/    public void startActivity(String action) {        startActivity(action, null);    }    /**     * 含有Bundle通过Action跳转界面     **/    public void startActivity(String action, Bundle bundle) {        Intent intent = new Intent();        intent.setAction(action);        if (bundle != null) {            intent.putExtras(bundle);        }        startActivity(intent);        overridePendingTransition(R.anim.push_left_in, R.anim.push_left_out);    }        /**     * 含有Bundle通过Class打开编辑界面      **/    public void startActivityForResult(Class<?> cls, Bundle bundle, int requestCode) {        Intent intent = new Intent();        intent.setClass(this, cls);        if (bundle != null) {            intent.putExtras(bundle);        }        startActivityForResult(intent, requestCode);        overridePendingTransition(R.anim.push_left_in, R.anim.push_left_out);    }            /**     * 带有右进右出动画的退出     */    @Override    public void finish() {        super.finish();        overridePendingTransition(R.anim.push_right_in, R.anim.push_right_out);    }    /**     * 默认退出     */    public void defaultFinish() {        super.finish();    }    }


            BaseNetworkActivity类源码如下:     

package com.lbt.hairdesigner;import java.util.ArrayList;import java.util.List;import android.os.Bundle;import android.os.Handler;import com.lbt.hairdesigner.net.AsyncBaseRequest;import com.lbt.hairdesigner.net.DefaultThreadPool;/** * 功能描述:应用中需要访问网络的Activity基类 * @author android_ls */public abstract class BaseNetworkActivity extends BaseActivity {    /**     * 当前activity所持有的所有网络请求     */    protected List<AsyncBaseRequest> mAsyncRequests;    /**     * 当前activity所持有的Handler     */    protected Handler mHandler;    /**     * 当前activity所持有的线程池对象     */    protected DefaultThreadPool mDefaultThreadPool;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);    }    /**     * 向用户展示信息前的准备工作在这个方法里处理     */    protected void preliminary() {        mHandler = new Handler();        mAsyncRequests = new ArrayList<AsyncBaseRequest>();        mDefaultThreadPool = DefaultThreadPool.getInstance();        // 初始化组件        setupViews();        // 初始化数据        initialized();    }    public List<AsyncBaseRequest> getAsyncRequests() {        return mAsyncRequests;    }    public Handler getHandler() {        return mHandler;    }    public DefaultThreadPool getDefaultThreadPool() {        return mDefaultThreadPool;    }    @Override    protected void onPause() {        /**         * 在activity暂停的时候,同时设置终止标识,终止异步线程         */        cancelAllRequest();        super.onPause();    }    @Override    protected void onDestroy() {        /**         * 在activity销毁的时候,同时设置终止标识,终止异步线程         */        cancelAllRequest();        super.onDestroy();    }    /**     * 取消当前Activity相关的网络请求     */    private void cancelAllRequest() {        if (mAsyncRequests != null && mAsyncRequests.size() > 0) {            try {                int size = mAsyncRequests.size();                for (int i = 0; i < size; i++) {                    AsyncBaseRequest request = mAsyncRequests.get(i);                    request.setInterrupted(true);                    mAsyncRequests.remove(request);                    size = mAsyncRequests.size();                }            } catch (Exception e) {                // TODO Auto-generated catch block                e.printStackTrace();            }        }    }    }

            PhotoNetworkActivity类源码如下:




Android应用开发软件工程师,自己动手打造自己的专属应用框架


Android应用开发软件工程师,自己动手打造自己的专属应用框架

   

Android应用开发软件工程师,自己动手打造自己的专属应用框架


Android应用开发软件工程师,自己动手打造自己的专属应用框架


Android应用开发软件工程师,自己动手打造自己的专属应用框架


2、具体实现层,个别类的源码

   HairDesignerMainActivity类源码如下:

package com.lbt.hairdesigner.ph;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.os.Bundle;import android.util.TypedValue;import android.view.View;import android.widget.ImageView;import android.widget.LinearLayout;import android.widget.RatingBar;import android.widget.RelativeLayout;import android.widget.TextView;import com.lbt.hairdesigner.BaseNetworkActivity;import com.lbt.hairdesigner.R;import com.lbt.hairdesigner.UGCFrameLayout;import com.lbt.hairdesigner.entity.CommentInfo;import com.lbt.hairdesigner.entity.PersonalHomeInfo;import com.lbt.hairdesigner.main.ClientHomepageActivity;import com.lbt.hairdesigner.main.MyCalendarActivity;import com.lbt.hairdesigner.personal.ChangePersonalInfoActivity;import com.lbt.hairdesigner.utils.BitmapUtil;import com.lbt.hairdesigner.utils.Constant;/** * 功能描述:我的主页 * @author android_ls */public class PersonalHomepageLayout extends UGCFrameLayout {    /**     * LOG打印标签     */    private static final String TAG = PersonalHomepageLayout.class.getSimpleName();    /**用户图像*/    private ImageView ivUserImage;    private TextView tv_username;    private ImageView iv_sex_icon;    private RatingBar ratingbar;    private TextView tv_price;    private TextView tv_haoping;    private TextView tv_yifuwu;    private LinearLayout ll_yonghudianping_arrow;    private TextView tv_dianping_count;    private ImageView iv_dianping_user_icon;    private TextView tv_dianping_nickname;    private TextView tv_dianping_content;    private TextView tv_dianping_time;    private RelativeLayout rl_xijianchui;    private RelativeLayout rl_tangfa;    private RelativeLayout rl_ranfa;    private RelativeLayout rl_huli;    private TextView tv_xijianchui_price;    private TextView tv_tangfa_price;    private TextView tv_ranfa_price;    private TextView tv_huli_price;    private RelativeLayout rl_yuyue_shijian;    private RelativeLayout rl_address;    private RelativeLayout rl_haopinglv;    private RelativeLayout rl_yifuwu;    private TextView tv_address;    private TextView tv_fujin_shangquan;    private TextView tv_fujianxinxi;    private LinearLayout ll_signature_arrow;    private TextView tv_personalized_signature;    private LinearLayout ll_happy_baby_show;    private LinearLayout ll_happy_baby_show_arrow;    private LinearLayout ll_coupon_list_arrow;    private RelativeLayout rl_yonghu_dianping;    private RelativeLayout rl_personal_jiamubiao;    private RelativeLayout rl_signature;    private RelativeLayout rl_happy_baby_show;    private RelativeLayout rl_youhuixinxi;    public PersonalHomepageLayout(BaseNetworkActivity activity) {        super(activity);    }    @Override    protected void setupViews() {        super.setupViews();        topMenuNavbar.tvTitle.setText("我的主页");        tv_username = (TextView) viewRoot.findViewById(R.id.tv_username);        ivUserImage = (ImageView) viewRoot.findViewById(R.id.iv_big_icon);        iv_sex_icon = (ImageView) viewRoot.findViewById(R.id.iv_sex_icon);        ratingbar = (RatingBar) viewRoot.findViewById(R.id.ratingbar);        tv_price = (TextView) viewRoot.findViewById(R.id.tv_price);        tv_haoping = (TextView) viewRoot.findViewById(R.id.tv_haoping);        tv_yifuwu = (TextView) viewRoot.findViewById(R.id.tv_yifuwu);        ll_yonghudianping_arrow = (LinearLayout) viewRoot.findViewById(R.id.ll_yonghudianping_arrow);        ll_yonghudianping_arrow.setOnClickListener(this);        tv_dianping_count = (TextView) viewRoot.findViewById(R.id.tv_dianping_count);        iv_dianping_user_icon = (ImageView) viewRoot.findViewById(R.id.iv_dianping_user_icon);        tv_dianping_nickname = (TextView) viewRoot.findViewById(R.id.tv_dianping_nickname);        tv_dianping_content = (TextView) viewRoot.findViewById(R.id.tv_dianping_content);        tv_dianping_time = (TextView) viewRoot.findViewById(R.id.tv_dianping_time);        rl_xijianchui = (RelativeLayout) viewRoot.findViewById(R.id.rl_xijianchui);        rl_tangfa = (RelativeLayout) viewRoot.findViewById(R.id.rl_tangfa);        rl_ranfa = (RelativeLayout) viewRoot.findViewById(R.id.rl_ranfa);        rl_huli = (RelativeLayout) viewRoot.findViewById(R.id.rl_huli);        iv_dianping_user_icon.setOnClickListener(this);        rl_xijianchui.setOnClickListener(this);        rl_tangfa.setOnClickListener(this);        rl_ranfa.setOnClickListener(this);        rl_huli.setOnClickListener(this);        rl_haopinglv = (RelativeLayout) viewRoot.findViewById(R.id.rl_haopinglv);        rl_haopinglv.setOnClickListener(this);        rl_yifuwu = (RelativeLayout) viewRoot.findViewById(R.id.rl_yifuwu);        rl_yifuwu.setOnClickListener(this);        tv_xijianchui_price = (TextView) viewRoot.findViewById(R.id.tv_xijianchui_price);        tv_tangfa_price = (TextView) viewRoot.findViewById(R.id.tv_tangfa_price);        tv_ranfa_price = (TextView) viewRoot.findViewById(R.id.tv_ranfa_price);        tv_huli_price = (TextView) viewRoot.findViewById(R.id.tv_huli_price);        rl_yuyue_shijian = (RelativeLayout) viewRoot.findViewById(R.id.rl_yuyue_shijian);        rl_yuyue_shijian.setOnClickListener(this);        rl_address = (RelativeLayout) viewRoot.findViewById(R.id.rl_address);        rl_address.setOnClickListener(this);        tv_address = (TextView) viewRoot.findViewById(R.id.tv_address);        tv_fujin_shangquan = (TextView) viewRoot.findViewById(R.id.tv_fujin_shangquan);        tv_fujianxinxi = (TextView) viewRoot.findViewById(R.id.tv_fujianxinxi);        ll_signature_arrow = (LinearLayout) viewRoot.findViewById(R.id.ll_signature_arrow);        ll_signature_arrow.setOnClickListener(this);        tv_personalized_signature = (TextView) viewRoot.findViewById(R.id.tv_personalized_signature);        ll_happy_baby_show = (LinearLayout) viewRoot.findViewById(R.id.ll_happy_baby_show);        ll_happy_baby_show_arrow = (LinearLayout) viewRoot.findViewById(R.id.ll_happy_baby_show_arrow);        ll_happy_baby_show_arrow.setOnClickListener(this);        ll_coupon_list_arrow = (LinearLayout) viewRoot.findViewById(R.id.ll_coupon_list_arrow);        ll_coupon_list_arrow.setOnClickListener(this);        rl_yonghu_dianping = (RelativeLayout) viewRoot.findViewById(R.id.rl_yonghu_dianping);        rl_yonghu_dianping.setOnClickListener(this);        rl_personal_jiamubiao = (RelativeLayout) viewRoot.findViewById(R.id.rl_personal_jiamubiao);        rl_personal_jiamubiao.setOnClickListener(this);        rl_signature = (RelativeLayout) viewRoot.findViewById(R.id.rl_signature);        rl_signature.setOnClickListener(this);        rl_happy_baby_show = (RelativeLayout) viewRoot.findViewById(R.id.rl_happy_baby_show);        rl_happy_baby_show.setOnClickListener(this);        rl_youhuixinxi = (RelativeLayout) viewRoot.findViewById(R.id.rl_youhuixinxi);        rl_youhuixinxi.setOnClickListener(this);    }    @Override    public void onClick(View v) {        Bundle bundle = new Bundle();        switch (v.getId()) {        case R.id.rl_yonghu_dianping:        case R.id.ll_yonghudianping_arrow:            // 用户点评            mActivity.startActivity(UserCommentListActivity.class);            break;        case R.id.rl_personal_jiamubiao:        case R.id.rl_xijianchui:            mActivity.startActivity(PriceListActivity.class);            break;        case R.id.rl_tangfa:            mActivity.startActivity(PriceListActivity.class);            break;        case R.id.rl_ranfa:            mActivity.startActivity(PriceListActivity.class);            break;        case R.id.rl_huli:            mActivity.startActivity(PriceListActivity.class);            break;        case R.id.rl_yuyue_shijian:            bundle.putInt("flage", Constant.PERSONAL_HOMEPAGE_MY_CALENDAR_CODE);            mActivity.startActivity(MyCalendarActivity.class, bundle);            break;        case R.id.rl_address:            mActivity.startActivity(ShopListActivity.class);            break;        case R.id.ll_signature_arrow:        case R.id.rl_signature:            bundle.putInt("flage", Constant.CHANGE_PERSOANL_SIGNATURE_CODE);            bundle.putString("signature", tv_personalized_signature.getText().toString());            mActivity.startActivity(ChangePersonalInfoActivity.class, bundle);            break;        case R.id.ll_happy_baby_show_arrow:        case R.id.rl_happy_baby_show:            mActivity.startActivity(WorksShowActivity.class);            break;        case R.id.rl_haopinglv:            bundle.putInt("flage", Constant.REVIEW_HAOPINGLV_CODE);            mActivity.startActivity(ReviewActivity.class, bundle);            break;        case R.id.rl_yifuwu:            bundle.putInt("flage", Constant.REVIEW_YIFUWU_CODE);            mActivity.startActivity(ReviewActivity.class, bundle);            break;        case R.id.ll_coupon_list_arrow:        case R.id.rl_youhuixinxi:            mActivity.startActivity(CouponListActivity.class);            break;        case R.id.iv_dianping_user_icon:            // 点评用户的图像单击事件处理            mActivity.startActivity(ClientHomepageActivity.class);            break;        default:            super.onClick(v);            break;        }    }    @Override    protected int getLayoutId() {        return R.layout.personal_homepage;    }    @Override    protected void initialized() {        // 构造测试数据        PersonalHomeInfo personalHome = new PersonalHomeInfo();        personalHome.setUid(1004);        personalHome.setName("王念西");        // personalBaseInfo.setHeadurl("");        // personalBaseInfo.setTinyurl("");        personalHome.setMainurl("");        personalHome.setSex(1);        personalHome.setStar(4f);        personalHome.setPrice(200);        personalHome.setGoodReputation(0.5);        personalHome.setYifuwu(50);        personalHome.setCommentCount(126);        CommentInfo commentInfo = new CommentInfo();        commentInfo.setCid(102);        commentInfo.setUid(23);        commentInfo.setNickname("Vicy1985");        commentInfo.setIconPath("");        commentInfo.setContent("很时尚,不错,这个发型我喜欢,好评,下次还会找你剪头发。");        commentInfo.setTime("2013-05-03 09:38");        personalHome.setCommentInfo(commentInfo);        // 用户基本信息字段赋值        tv_username.setText(personalHome.getName());        Bitmap bitmap = BitmapFactory.decodeResource(mActivity.getResources(), R.drawable.user_big_icon);        ivUserImage.setImageBitmap(BitmapUtil.drawRoundBitmap(bitmap, 8));        if (personalHome.getSex() == 1) {            iv_sex_icon.setImageResource(R.drawable.sex_man);        } else {            iv_sex_icon.setImageResource(R.drawable.jishi_female);        }        ratingbar.setRating(personalHome.getStar());        tv_price.setText("均价:" + (int) personalHome.getPrice() + "元");        tv_haoping.setText((int) (personalHome.getGoodReputation() * 100) + "%");        tv_yifuwu.setText(personalHome.getYifuwu() + "");        // 用户点评字段赋值        tv_dianping_count.setText("共" + personalHome.getCommentCount() + "条");        CommentInfo comment = personalHome.getCommentInfo();        tv_dianping_nickname.setText(comment.getNickname());        tv_dianping_content.setText(comment.getContent());        tv_dianping_time.setText(comment.getTime());        Bitmap bitmap1 = BitmapFactory.decodeResource(mActivity.getResources(), R.drawable.user_icon);        iv_dianping_user_icon.setImageBitmap(BitmapUtil.drawRoundBitmap(bitmap1, 8));        // 价目表字段赋值        tv_xijianchui_price.setText("小于100");        tv_tangfa_price.setText("600-1000");        tv_ranfa_price.setText("600-1000");        tv_huli_price.setText("600-1000");        // 场地字段赋值        tv_address.setText("地址:上海市长宁区安顺路1026号");        tv_fujin_shangquan.setText("附近商圈:古北");        tv_fujianxinxi.setText("免费停车、免费无线上网");        // 个性签名字段赋值        tv_personalized_signature.setText("我一直在发行业五年,现在一个艺术家工作的可爱的无与伦比的头发工作室,位于旧金山的SOMA区...");        int[] images = {                 R.drawable.f1, R.drawable.f2, R.drawable.f3,                 R.drawable.f4, R.drawable.f5, R.drawable.f6,                 R.drawable.f7, R.drawable.f8,R.drawable.f9,                R.drawable.f10, R.drawable.f13, R.drawable.f12,                R.drawable.f14, R.drawable.f15, R.drawable.f16,                R.drawable.f17, R.drawable.f18, R.drawable.f19 };        for (int i = 0; i < images.length; i++) {            // 显示最近头像            ImageView imageView = new ImageView(mActivity);            int widthAndHeight = pxTodip(60);            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(widthAndHeight, widthAndHeight);            params.rightMargin = pxTodip(10);            imageView.setLayoutParams(params);            // imageView.setPadding(0, pxTodip(5), 0, pxTodip(5));            // imageView.setBackgroundResource(R.drawable.select_friend_avatar_frame);            Bitmap bitmap2 = BitmapFactory.decodeResource(mActivity.getResources(), images[i]);            imageView.setImageBitmap(BitmapUtil.drawRoundBitmap(bitmap2, 8));            ll_happy_baby_show.addView(imageView);            ll_happy_baby_show.invalidate();            imageView.setOnClickListener(new OnClickListener() {                public void onClick(View v) {                }            });        }    }    private int pxTodip(float valuepx) {        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, valuepx, mActivity.getResources().getDisplayMetrics());    }}

四、写在最后面的话:

          向大家推荐高焕堂的《Android应用框架原理与程序设计》这本书,相信你看后会获益良多。