《Android从菜鸟到高手》——002“面向对象思想”在Android的基本应用
来源:互联网 发布:linux系统chown指令 编辑:程序博客网 时间:2024/05/22 04:21
面向对象的特征
讲到面向对象,就不得不提起它的三大特性:封装、继承、多态。
封装
封装是面向对象编程的核心思想,将对象的属性和行为封装起来,用“类”作为载体。类通常对客户隐藏其实现细节,这就是封装的思想。
Android针对封装的使用场景:
1.封装第三方开源框架,封装变化。
比如说,项目中要用到图片加载框架UniversalImageLoader。如果不针对图片加载框架进行封装,那么每个图片加载的地方,都会是这样的:
ImageLoader.getInstance().loadImage(imageUrl, new ImageLoadingListener() { @Override public void onLoadingStarted(String imageUri, View view) { } @Override public void onLoadingFailed(String imageUri, View view, FailReason failReason) { } @Override public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) { mImageView.setImageBitmap(loadedImage); } @Override public void onLoadingCancelled(String imageUri, View view) { } });
过段时间,老板说:Picasso好像很不错,下个版本咱们换这个框架,给你一天时间能搞定吗?囧…
然后开始疯狂Ctrl^C、Ctrl^V,把每一个地方换成这样:
Picasso.with(this).load("url").placeholder(R.mipmap.ic_default).into(imageView);
然后,由于Picasso不支持缓存,还要解决各种问题。
可是,如果老板下次又要换Glide、Fresco等其他框架呢?怎么办?
很多人觉得,封装只是为了隐藏细节,有点像保护隐私的感觉。但很多时候,封装其实是为了实现下层对上层的透明。
2.封装工具类,减少重复。
封装工具类,关键在于减少重复的工作。举个例子:
SharedPreferences大家应该都用过,每次使用的时候,都要写这样的模(chong)板(fu)代码。
//指定操作的文件名称 SharedPreferences share = getSharedPreferences(SILENAME, MODE_PRIVATE); SharedPreferences.Editor edit = share.edit(); //编辑文件 edit.putInt("age", 22); //根据键值对添加数据 edit.putString("name", "LJie"); edit.commit(); //保存数据信息
如果简单封装一下呢?
public class SPUtils{ /** * 保存在手机里面的文件名 */ public static final String FILE_NAME = "share_data"; /** * 保存数据的方法,我们需要拿到保存数据的具体类型,然后根据类型调用不同的保存方法 * * @param context * @param key * @param object */ public static void put(Context context, String key, Object object) { SharedPreferences sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE); SharedPreferences.Editor editor = sp.edit(); if (object instanceof String) { editor.putString(key, (String) object); } else if (object instanceof Integer) { editor.putInt(key, (Integer) object); } else if (object instanceof Boolean) { editor.putBoolean(key, (Boolean) object); } else if (object instanceof Float) { editor.putFloat(key, (Float) object); } else if (object instanceof Long) { editor.putLong(key, (Long) object); } else { editor.putString(key, object.toString()); } SharedPreferencesCompat.apply(editor); } /** * 得到保存数据的方法,我们根据默认值得到保存的数据的具体类型,然后调用相对于的方法获取值 * * @param context * @param key * @param defaultObject * @return */ public static Object get(Context context, String key, Object defaultObject) { SharedPreferences sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE); if (defaultObject instanceof String) { return sp.getString(key, (String) defaultObject); } else if (defaultObject instanceof Integer) { return sp.getInt(key, (Integer) defaultObject); } else if (defaultObject instanceof Boolean) { return sp.getBoolean(key, (Boolean) defaultObject); } else if (defaultObject instanceof Float) { return sp.getFloat(key, (Float) defaultObject); } else if (defaultObject instanceof Long) { return sp.getLong(key, (Long) defaultObject); } return null; } /** * 移除某个key值已经对应的值 * @param context * @param key */ public static void remove(Context context, String key) { SharedPreferences sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE); SharedPreferences.Editor editor = sp.edit(); editor.remove(key); SharedPreferencesCompat.apply(editor); } /** * 清除所有数据 * @param context */ public static void clear(Context context) { SharedPreferences sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE); SharedPreferences.Editor editor = sp.edit(); editor.clear(); SharedPreferencesCompat.apply(editor); } /** * 查询某个key是否已经存在 * @param context * @param key * @return */ public static boolean contains(Context context, String key) { SharedPreferences sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE); return sp.contains(key); } /** * 返回所有的键值对 * * @param context * @return */ public static Map<String, ?> getAll(Context context) { SharedPreferences sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE); return sp.getAll(); } /** * 创建一个解决SharedPreferencesCompat.apply方法的一个兼容类 * * * */ private static class SharedPreferencesCompat { private static final Method sApplyMethod = findApplyMethod(); /** * 反射查找apply的方法 * * @return */ @SuppressWarnings({ "unchecked", "rawtypes" }) private static Method findApplyMethod() { try { Class clz = SharedPreferences.Editor.class; return clz.getMethod("apply"); } catch (NoSuchMethodException e) { } return null; } /** * * commit方法是同步的,并且我们很多时候的commit操作都是UI线程中,毕竟是IO操作,尽可能异步; * 如果找到则使用apply执行,否则使用commit; * * @param editor */ public static void apply(SharedPreferences.Editor editor) { try { if (sApplyMethod != null) { sApplyMethod.invoke(editor); return; } } catch (IllegalArgumentException e) { } catch (IllegalAccessException e) { } catch (InvocationTargetException e) { } editor.commit(); } }}
那么我们在使用的时候只需要这样写:
SPUtils.put(context, 'age', 23);
是不是很酷?
3.编写BaseActivity抽象类,通过继承实现复用,通过覆盖实现多态。
我们在编写Activity的时候,其实也会写很多重复的代码。比如说:
- 设置全屏
- 生命周期打印Log
- 设置沉浸状态栏
- 界面是否可以旋转
- 启动另一个Activity
如果我们可以编写一个BaseActivity的抽象类,并且让这个BaseActivity实现一些公共的功能,然后让我们的Activity都继承自这个BaseActivity,那么,我们就可以减少重复代码的出现,同时Activity的业务逻辑也会更加清晰。
public abstract class BaseActivity extends Activity implements View.OnClickListener { /** 是否沉浸状态栏 **/ private boolean isSetStatusBar = true; /** 是否允许全屏 **/ private boolean mAllowFullScreen = true; /** 是否禁止旋转屏幕 **/ private boolean isAllowScreenRoate = false; /** 当前Activity渲染的视图View **/ private View mContextView = null; /** 日志输出标志 **/ protected final String TAG = this.getClass().getSimpleName(); /** View点击 **/ public abstract void widgetClick(View v); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.d(TAG, "BaseActivity-->onCreate()"); Bundle bundle = getIntent().getExtras(); initParms(bundle); View mView = bindView(); if (null == mView) { mContextView = LayoutInflater.from(this) .inflate(bindLayout(), null); } else{ mContextView = mView; } //这里判断允许是否屏幕旋转 if (mAllowFullScreen) { requestWindowFeature( Window.FEATURE_NO_TITLE); } //是否沉侵式标题栏 if (isSetStatusBar) { steepStatusBar(); } //写入布局 setContentView(mContextView); if (!isAllowScreenRoate) { setRequestedOrientation( ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); } initView(mContextView); setListener(); doBusiness(this); } /** * [沉浸状态栏] */ private void steepStatusBar() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { // 透明状态栏 getWindow().addFlags( WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); // 透明导航栏 getWindow().addFlags( WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); } } /** * 初始化参数 * * @param parms */ public abstract void initParms(Bundle parms); /** * [绑定视图] * * @return */ public abstract View bindView(); /** * 绑定布局 * * @return */ public abstract int bindLayout(); /** * 初始化控件 * * @param view */ public abstract void initView(final View view); /** * 绑定控件 * * @param resId * * @return */ protected T $(int resId) { return (T) super.findViewById(resId); } /** * 设置监听 */ public abstract void setListener(); @Override public void onClick(View v) { widgetClick(v); } /** * 业务操作 * * @param mContext */ public abstract void doBusiness(Context mContext); /** * 页面跳转 * * @param clz */ public void startActivity(Class clz) { startActivity(new Intent(BaseActivity.this,clz)); } /** * 携带数据的页面跳转 * * @param clz * @param bundle */ public void startActivity(Class clz, Bundle bundle) { Intent intent = new Intent(); intent.setClass(this, clz); if (bundle != null) { intent.putExtras(bundle); } startActivity(intent); } /** * 含有Bundle通过Class打开编辑界面 * * @param cls * @param bundle * @param requestCode */ 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); } @Override protected void onRestart() { super.onRestart(); Log.d(TAG, "onRestart()"); } @Override protected void onStart() { super.onStart(); Log.d(TAG, "onStart()"); } @Override protected void onResume() { super.onResume(); Log.d(TAG, "onResume()"); } @Override protected void onPause() { super.onPause(); Log.d(TAG, "onPause()"); } @Override protected void onStop() { super.onStop(); Log.d(TAG, "onStop()"); } @Override protected void onDestroy() { super.onDestroy(); Log.d(TAG, "onDestroy()"); } /** * 简化Toast * @param msg */ protected void showToast(String msg) { Toast.makeText(this,msg,Toast.LENGTH_SHORT) .show(); } /** * 是否允许全屏 * * @param allowFullScreen */ public void setAllowFullScreen(boolean allowFullScreen) { this.mAllowFullScreen = allowFullScreen; } /** * 是否设置沉浸状态栏 * * @param isSetStatusBar */ public void setSteepStatusBar(boolean isSetStatusBar) { this.isSetStatusBar = isSetStatusBar; } /** * 是否允许屏幕旋转 * * @param isAllowScreenRoate */ public void setScreenRoate(boolean isAllowScreenRoate) { this.isAllowScreenRoate = isAllowScreenRoate; }}
注意:BaseActivity里面只适合封装那些公共的代码逻辑,具体应该封装哪些代码,要视情况而定。
0 0
- 《Android从菜鸟到高手》——002“面向对象思想”在Android的基本应用
- 《Android从菜鸟到高手》——001从面向对象开始谈起
- 从菜鸟到高手 Android系列问答汇总
- 《Android从菜鸟到高手》开篇及索引
- [新人课堂] 从菜鸟到高手 Android系统手机的通用技巧
- 《黄帝内经》从养生到面向对象的思想!
- 面向对象的基本思想
- Java之美[从菜鸟到高手演练]之Comparator和Comparable在排序中的应用
- Java之美[从菜鸟到高手演练]之Comparator和Comparable在排序中的应用
- Android面试题——Java面向对象思想
- 从面向过程到面向对象——在C中如何实现面向对象编程
- 面向对象-基本思想
- 视频Android studio1.3.1从菜鸟到高手--第一季-IT蓝豹
- 从菜鸟到高手,R语言书单都在这!
- 菜鸟于飞------从嵌入式软件开发到android 应用开发的思考
- 对象和类(一)——面向对象设计的基本思想和特点
- Android编程思想,面向对象程序设计第四篇——继承(上)重复代码放在基类
- 5: 面向对象的基本思想
- 产生死锁的必要条件和解决方法
- 机器学习实战---读书笔记: 第5章 基Logistic回归
- tomcat增加用户后仍提示拒绝权限的问题
- 从零开始学Spring Boot(3)——JPA
- 使用typedef 定义数组
- 《Android从菜鸟到高手》——002“面向对象思想”在Android的基本应用
- 深入分析Java ClassLoader原理
- No.513 Find Bottom Left Tree Value
- Hello R!
- Java单例模式(singleton),饿汉式和内部类的区别
- eclipse使用git上传项目到GitHub
- 日志总结-java变量类型
- thinking in java——0321学习笔记
- faster rcnn:assert (boxes[:, 2] >= boxes[:, 0]).all()分析塈VOC2007 xml坐标定义理解