从头开始敲代码之《从BaseApplication/Activity开始》
2015-09-14 17:27
295 查看
转载请注明出处王亟亟的大牛之路
其安易持,其未兆易谋;其脆易泮,其微易散。为之于未有,治之于未乱。合抱之木,生于毫末;九层之台,起于垒土;千里之行,始于足下。为者败之,执者失之。是以圣人无为故无败,无执故无失。民之从事,常于几成而败之。慎终如始,则无败事。是以圣人欲不欲,不贵难得之货,学不学,复众人之所过,以辅万物之自然而不敢为。
作为系列专题的第一篇,这一篇文章属于小难产,中间夹杂着一些工作上的事,一些蛋疼的事(学车之类的),说实在的,做了Coder之后发现业余时间还真不是太多。。。。唉。。。整个专栏的前 5 6篇将会比较简单,便于过度。
包目录:
好,废话不多进入正题
这篇文章干什么呢?
对我们平时用的最多相当较为常用的Activity进行简单的封装,以满足基础的需求
封装是什么?封装的好处是什么?
1.将抽象得到的数据和行为(或功能)相结合,形成一个有机的整体.
2.增强安全性和简化编程,使用者不必了解具体的实现细节,而只是要通过外部接口,以特定的访问权限来使用类的成员.
这一篇来自定义我们自己的 BaseApplication 以及 BaseActivity
为什么要那么做?
白话版:把什么初始化,稀里哗啦一大堆的Toast Dialog的工具全部丢进去,让后续的Activity的业务更清晰。
每一次的例子都是自己花心思写的,质量好坏客观见谅
BaseActivitypublic class BaseApplication extends Application{ /* * 初始化TAG * */ private static String TAG=BaseApplication.class.getName(); /*Activity堆*/ private Stack<Activity> activityStack = new Stack<Activity>(); @Override public void onCreate() { super.onCreate(); LogUtils.d(TAG,TAG+"---onCreate()"); printAppParameter(); } /*打印出一些app的参数*/ private void printAppParameter(){ LogUtils.d(TAG, "OS : "+Build.VERSION.RELEASE + " ( " + Build.VERSION.SDK_INT + " )"); DeviceMgr.ScrSize realSize = DeviceMgr.getScreenRealSize(this); LogUtils.d(TAG, "Screen Size: " + realSize.w + " X " + realSize.h); } public void addActivity(final Activity curAT) { if (null == activityStack) { activityStack = new Stack<Activity>(); } activityStack.add(curAT); } public void removeActivity(final Activity curAT) { if (null == activityStack) { activityStack = new Stack<Activity>(); } activityStack.remove(curAT); } //获取最后一个Activity public Activity currentActivity() { Activity activity = activityStack.lastElement(); return activity; } //返回寨内Activity的总数 public int howManyActivities() { return activityStack.size(); } //关闭所有Activity public void finishAllActivities() { for (int i = 0, size = activityStack.size(); i < size; i++) { if (null != activityStack.get(i)) { activityStack.get(i).finish(); } } activityStack.clear(); } }
上面就是一个比较常用的一个实现,声明了
Stack<Activity>用于存放项目过程中未Destory的Activity。写了几个常用增删查的操作,然后打印出一些APP的属性。
那还可以在Application里做什么?
初始化 如初始化 ImageLoader这一类的第三方控件还有Sp,缓存等操作
在onCreate方法中调用
//创建默认的ImageLoader配置参数 ImageLoaderConfiguration configuration = ImageLoaderConfiguration .createDefault(this); //Initialize ImageLoader with configuration. ImageLoader.getInstance().init(configuration);
编写一些通用的方法 如吐司 Dialog等
简化吐司
public void showMyToast(final Activity curAT, int textResId) { showMyToast(curAT, textResId, Toast.LENGTH_LONG); }
退出App
public void exit() { TRIeIDLog.logD(TAG, "finishAllActivities..."); finishAllActivities(); android.os.Process.killProcess(android.os.Process.myPid()); System.exit(0); }
诸如此类的方法都可以在 Application中进行编写。
那么我们再来看下我们的BaseActivity
public abstract class BaseActivity extends Activity { InputMethodManager _inputMethodManager; protected Resources res; protected BaseApplication baseApp; protected static final String TAG = BaseActivity.class.getName(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(getLayout()); res = this.getApplicationContext().getResources(); baseApp = (BaseApplication) this.getApplication(); _inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); this.getWindow().setSoftInputMode( WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN); findById(); setListener(); logic(); baseApp.addActivity(this); } @Override public boolean onTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { if (getCurrentFocus() != null && getCurrentFocus().getWindowToken() != null) { _inputMethodManager.hideSoftInputFromWindow(getCurrentFocus() .getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); } } return super.onTouchEvent(event); } @Override protected void onPause() { super.onPause(); } @Override protected void onResume() { super.onResume(); } @Override protected void onDestroy() { super.onDestroy(); baseApp.removeActivity(this); } //FindById protected abstract void findById(); //setListener protected abstract void setListener(); //Logic protected abstract void logic(); protected abstract int getLayout(); //是否支持最小SDK protected boolean isSupportedSDK(int sdkVerCode) { LogUtils.d(TAG, "isSupportedSDK - ConfigUtil.MIN_SDK_VER_CODE = \"" + ConfigUtil.MIN_SDK_VER_CODE + "\""); LogUtils.d(TAG, "isSupportedSDK - sdkVerCode = \"" + sdkVerCode + "\""); return sdkVerCode >= ConfigUtil.MIN_SDK_VER_CODE; } //网络错误种类 protected int getNetworkErrorTip(int code) { LogUtils.d(TAG, "getNetworkErrorTip - code = \"" + code + "\""); int textResId = R.string.error_network_time_out; switch (code) { case RespHandleListener.ErrCode.ERR_NETWORK_NOT_AVAILABLE: textResId = R.string.error_network_not_available; break; case RespHandleListener.ErrCode.ERR_SERVER_ERROR: textResId = R.string.error_network_server_busy; break; case RespHandleListener.ErrCode.ERR_TIME_OUT: case RespHandleListener.ErrCode.ERR_CLIENT_ERROR: case RespHandleListener.ErrCode.ERR_UNKNOWN_ERROR: break; default: break; } LogUtils.d(TAG, "getNetworkErrorTip - textResId = \"" + textResId + "\""); return textResId; } }
网络判断的工具接口
RespHandleListener
public interface RespHandleListener { class ErrCode { public static final int ERR_SUCCEED = 0; public static final int ERR_NETWORK_NOT_AVAILABLE = -1; public static final int ERR_TIME_OUT = -2; public static final int ERR_SERVER_ERROR = -3; public static final int ERR_CLIENT_ERROR = -4; public static final int ERR_UNKNOWN_ERROR = -5; } void onError(int code); void onReqBegin(); void onReqEnd(String jsonResp); }
分析:
之前 BaseApplication中的一些方法在BaseActivity中进行了调用,BaseActivity又对我们的onCreate进行了简单的封装,把业务逻辑与控件捕捉等操作进行了分离(具体的使用,在之后会贴出)
那我们还可以在BaseActivity中做些什么?
吐司也可以做在这里,Dialog也一样
protected void showErrorToast(int code) { baseApp.showMyToast(this, getNetworkErrorTip(code)); }
网络判断的工具类getNetworkErrorTip()
屏幕信息等也可以在默认这里获取,以及一些硬件情况诸如NFC BLE等(这部分会在下一篇博文写)
接下来贴下Demo代码
public class MainActivity extends BaseActivity implements View.OnClickListener{ Button button; @Override protected void findById() { button=(Button)findViewById(R.id.button); } @Override protected void setListener() { button.setOnClickListener(this); } @Override protected void logic() { LogUtils.d("-------->logic",add(1,3)); } @Override protected int getLayout() { return R.layout.activity_main; } @Override public void onClick(View v) { if (v.getId()==R.id.button){ Toast.makeText(MainActivity.this,"点击了按钮",Toast.LENGTH_SHORT).show(); } } private int add(int a, int b){ return a+b; } }
运行效果
这么做,妈妈再也不担心我的onCreate方法几百行了,再也不担心我少findById一个控件了,当然还可以进一步的封装 用泛型
<T>来对控件操作进一步简化,这个会在后面的文章写到。
用到的第三方库:
一个很简便的日志库
compile 'com.apkfuns.logutils:library:1.0.6'
源码:http://yunpan.cn/cmNbQInJuKHXw 访问密码 4a23
相关文章推荐
- Android AsyncTask完全解析,带你从源码的角度彻底理解
- 去掉android二维码的边框
- 从头开始敲代码之《从BaseApplication/Activity开始》
- android 开发第五弹---水波纹与自定义view实现绚丽粒子
- 解决Android中No resource found that matches android:TextAppearance.Material.Widget.Button.Inverse问题
- Android数据库安全解决方案,使用SQLCipher进行加解密
- (转)27个提升效率的iOS开源库推荐
- 去除AndroidStudio中libpng关于iCCP的警告
- android.widget.FrameLayout$LayoutParams cannot be cast to android.widget.AbsListView$LayoutParams
- swiper:前应用较广泛的移动端网页触摸内容滑动js插件
- Android5.0新控件CardView的介绍和使用
- 深入理解Android之Gradle
- Android SDK 在线更新镜像服务器资源
- iOS App提交指南-协议、税务和银行业务
- IOS开发模块总结(二)后台运行程序(1) 后台运行程序详解(二)
- Android 让图片等比例缩放的三种方法
- iOS 计算年龄
- android studio 代理配置
- IOS开发模块总结(二)后台运行程序(1) 后台运行程序详解(一)
- iOS开发的22个奇谲巧技