果肉一款福利满满的app,数据源mzitu,MD风格的界面。
如果你是一位想学习一下科特林的同学,那么绝对不要错过肉。如科特林所说它与Java的完美兼容,所以这里有科特林调用Java的,同时也有Java的调用科特林。数据是从网站上爬取的所以这里也有爬虫骚操作。果肉将会不定期更新,增加更多福利。
国际惯例,先上福利。Release1.0
1)网络请求
网络框架并没有使用RxRetrofit等,为了保证精简高效直接使用的HttpURLConnection类
val request = AsyncNetwork()
请求。请求(常量,HOST_MOBILE_URL,null)
请求。setRequestCallback(object : IRequestCallback {
override fun onSuccess(httpURLConnection : HttpURLConnection?,response : String){
//待办事项
}
})
val request = AsyncNetwork()
请求。请求(常量,HOST_MOBILE_URL,mutableMapOf())
请求。setRequestCallback(object : IRequestCallback {
override fun onSuccess(httpURLConnection : HttpURLConnection?,response : String){
//待办事项
}
})
2)数据库
数据库没有使用第三方框架,直接使用的SQL语句。
CREATE TABLE tb_class_page_list(
_id INTEGER PRIMARY KEY ASC AUTOINCREMENT,
href STRING独特,
说明STRING,
image_url STRING,
id_class_page INTEGER REFERENCES tb_class_page(_id)ON DELETE CASCADE ON UPDATE CASCADE,
[index] INTEGER);
3)读写缓存
序列化的效率远低于Parcelable,所以采用Parcelable实现的缓存机制,速度快了大概7,8倍。
VAL 助手 = PageListCacheHelper(?容器。?上下文。?FILESDIR 。 absolutePath)
VAL pageModel : 不限?=帮手。得到(钥匙)
VAL 助手 = PageListCacheHelper(上下文。 FILESDIR 。 absolutePath)
帮手。把(钥匙,对象)
VAL 助手 = PageListCacheHelper(上下文。 FILESDIR 。 absolutePath)
帮手。删除(钥匙)
4) jsoup获取数据
由于数据是用从HTML页面中提取的,所以速度偏慢,为了不影响体验做了一套缓存机制,来做到流畅体验。
Document doc = Jsoup 。解析(HTML);
元素元素=正文。getElementsByTag(“ a ”);
字符串文本=元素。得到(0)。文本();
String imageUrl =元素。得到(0)。attr(“ src ”);
...
5)组件
活动片段替代活动来显示新界面
因为活动需要在Manifiest中注册,所以当有多个活动的时候,就需要编写很长的Manifiest文件,严重影响了Manifiest的可读性,界面的风格也比较笨重。所以一个新页面就注册一个活动不太合适,我们通过用活性做为容器添加不同的片段来达到注册一个活动启动多个不同页面的效果。生命周期由活动管理,更方便简洁。
打开类BaseFragmentActivity : BaseActionActivity(){
伴侣对象{
private const val EXTRA_FRAGMENT_NAME = “ extra_fragment_name ”
private const val EXTRA_FRAGMENT_ARG = “ extra_fragment_arguments ”
@JvmOverloads
@JvmStatic
有趣的 newInstance(上下文:上下文,片段: Class < * >,bundle : Bundle?= null,
clazz : Class < out Activity> = getActivityClazz()): Intent {
val intent = Intent(context,clazz)
意图。putExtra(EXTRA_FRAGMENT_NAME,片段。名)
意图。putExtra(EXTRA_FRAGMENT_ARG,包)
返回意图
}
保护的 开放 乐趣 getActivityClazz() :类< 出活动> {
返回 BaseFragmentActivity ::类。java的
}
}
重写 fun onCreate(savedInstanceState : Bundle?){
super 。的onCreate(savedInstanceState)
的setContentView(R 。布局。 cc_activity_base_fragment)
VAL fragmentName =意图。getStringExtra(EXTRA_FRAGMENT_NAME)
var fragment : Fragment?= 零
,如果(文本实用程序。的isEmpty(fragmentName)){
//组默认片段
//片段= makeFragment(MainFragment :: class.java !!的getName())
} 否则 {
VAL ARGS =意图。getBundleExtra(EXTRA_FRAGMENT_ARG)
试试 {
fragment = makeFragment(fragmentName)
if(args != null)
分段?。arguments = args
} 捕获(E :异常){
e 。的printStackTrace()
}
}
如果(fragment == null)返回
supportFragmentManager
。beginTransaction()
。替换(R 。 ID 。 fragment_container,片段)
。承诺()
}
有趣的 makeFragment(名称: 字符串):片段?{
try {
val fragmentClazz = Class 。forName(name)
返回 fragmentClazz 。newInstance()作为片段
} 捕获(E :异常){
e 。的printStackTrace()
}
返回 null
}
}
6)序列化性能
性能测试,Serializable VS Externalizable,为了避免干扰,我们使用AndroidTest进行测试。
模型
类 Model1 实现 Serializable {
String text;
int code;
布尔布尔;
Model1儿童;
}
类 Model2 扩展 Model1 实现 Externalizable {
public Model2(){
}
@Override
public void readExternal(ObjectInput input)throws IOException,ClassNotFoundException {
文本=输入。的readUTF();
代码=输入。的readInt();
bool =输入。readBoolean();
child = new Model2();
孩子。文本=输入。的readUTF();
孩子。代码=输入。的readInt();
孩子。bool =输入。readBoolean();
}
@Override
public void writeExternal(ObjectOutput output)throws IOException {
输出。writeUTF(文本);
输出。writeInt(代码);
输出。writeBoolean(布尔);
if(child != null){
输出。writeUTF(孩子。文本);
输出。writeInt(孩子。代码);
输出。writeBoolean(孩子。布尔);
}
}
}
测试
@Test
public void serializableVSExternalizable()throws Exception {
List < Model1 > testModel1 = new ArrayList <>();
for(int i = 0 ; i < 50000 ; i ++){
Model1 model1 = new Model1();
model1 。text = “ Hello World ” + i;
model1 。code = i;
model1 。bool = false ;
Model1 child = new Model1();
孩子。text = “ Hello World Child ” + i;
孩子。code = i;
孩子。bool = false ;
model1 。孩子=孩子;
testModel1 。添加(MODEL1);
}
long startTime = System 。的currentTimeMillis();
File file = new File(“ / sdcard / serializable ”);
ObjectOutputStream oStream = new ObjectOutputStream(new FileOutputStream(file));
OStream 。的writeObject(testModel1);
OStream 。关();
日志。E( “串行化”,“写入时间” +(系统。的currentTimeMillis()-开始时间));
startTime = System 。的currentTimeMillis();
ObjectInputStream iStream = new ObjectInputStream(new FileInputStream(file));
testModel1 =(List < Model1 >)iStream 。的readObject();
iStream 。关();
日志。E( “串行化”,“
热门源码