Android通用初始化Activity模板
很多Android程序开始运行的时候,都会首先启动一个初始化的InitActivity,然后在这个InitActivity的加载函数(onCreate)中,再去启动一个SplashScreen:这个SplashScreen除了启动时显示美观之外,另外可能会做一些初始化检查工作:比如网络是否可用。最后InitActivity根据SplashScreen的检查结果选择退出或者显示程序的MainActivity。大致的代码如下:
基本上每个Android程序的InitActivity的实现都差不多,只不过调用的是各自的SplashActivity和MainActivity类以及出错后错误信息不一样。其余大部分都是重复的代码。我们可不可以设计一个通用的InitActivity类,从而减少这种重复呢?答案当然是肯定的。
封装重用的核心设计思想就是将“变化的部分分离出来”,让我们先把变化的部分找出来再说,阅读一下代码,对于不同的程序,变化的部分当在以下三个地方
1) Intent intent = new Intent(this, SplashActivity.class);
2) Intent intent = new Intent(this, WeatherActivity.class);
3) Toast.makeText(this, "网络错误", Toast.LENGTH_LONG).show();
第三个很简单,只需要在封装好的类里加上一个虚函数
protected abstract StringgetInitErrMsg();
并把相应的代码改成
Toast.makeText(this,getInitErrMsg, Toast.LENGTH_LONG).show();即可
对于前两个地方,我们可以看到对于不同的程序就是调用的SplashActivity和
MainActivity的类型不一样,我们很自然的会想到用模板去解决。改写之后的代码大致如下 :
然而可以看到,编译器对于如下两行都报错:
错误信息是:
网上查了一下,有好多人都碰到这种错误,比如如下帖子讨论的:
http://stackoverflow.com/questions/182636/how-to-determine-the-class-of-a-generic-type/182672
大致原因差不多就是运行时无法决议模版参数类型。按照网上的讨论,试着改写了几次代码,改动比较多而丑陋,最终仍然没解决问题,有点陷入死胡同的感觉。
我种种尝试都是想在模板类中去决议模版参数类型,但如果转换一个思路,将这种类型决议放到子类当中去就很简单了,按照这个思路重新修改下了代码。
在模板类中又添加了两个虚函数
然后我们的实现子类只需要如下简单几行代码即可:
修改之后,编译器的错误立马消失了,然后运行测试一下,结果一切OK。