kotlin之开发经验整理
2019-02-26 本文已影响2人
草蜢的逆袭
读取assets中的文本内容
resources.assets.open("test.txt").let {
it.buffered().reader().use { reader ->
Log.e("test", "${reader.readText()}")
}
}
统计字符出现的次数("io.reactivex:rxjava:1.2.1")
/**
* filter中过滤掉空字符
* groupBy 分组
* o.count 进行统计,得到的是一个observable
*/
// Observable.from(txt.toCharArray().asIterable()).filter { !it.isWhitespace() }.groupBy { it }.map(::println)
Observable.from(txt.toCharArray().asIterable()).filter { !it.isWhitespace() }.groupBy { it }.map { o ->
o.count().subscribe {
println("key = ${o.key} , count = $it")
}
}.subscribe()
retrofit发送get请求
interface GithubService {
@GET("/repos/enbandari/Kotlin-Tutorials/stargazers")
fun getUserInfos(): Call<List<User>>
}
// object单例类
object ServiceManager {
val apiService: GithubService by lazy {
Retrofit.Builder().baseUrl("https://api.github.com")
.addConverterFactory(GsonConverterFactory.create()).build().create(GithubService::class.java)
}
}
data class User(val login: String, val id: Long, val avatar_url: String)
单例类的5种实现方式对比
java
第一种方式
public class LazyNotThreadSafe {
private static LazyNotThreadSafe INSTANCE;
private LazyNotThreadSafe() {
}
public static LazyNotThreadSafe getInstance() {
if (INSTANCE == null) {
INSTANCE = new LazyNotThreadSafe();
}
return INSTANCE;
}
}
第二种方式
public class LazyThreadSafeDoubleCheck {
private static LazyThreadSafeDoubleCheck INSTANCE;
private LazyThreadSafeDoubleCheck() {
}
public static LazyThreadSafeDoubleCheck getInstance() {
if (INSTANCE == null) {
synchronized (LazyThreadSafeDoubleCheck.class) {
if (INSTANCE == null) {
//初始化时分为实例化和赋值两步, 尽管我们把这一步写成下面的语句,
// 但Java虚拟机并不保证其他线程『眼中』这两步的顺序究竟是怎么样的
INSTANCE = new LazyThreadSafeDoubleCheck();
}
}
}
return INSTANCE;
}
}
第三种方式
public class LazyThreadSafeStaticInnerClass {
private static class Holder {
private static LazyThreadSafeStaticInnerClass INSTANCE = new LazyThreadSafeStaticInnerClass();
}
private LazyThreadSafeStaticInnerClass() {
}
public static LazyThreadSafeStaticInnerClass getInstance() {
return Holder.INSTANCE;
}
}
第四种方式
public class LazyThreadSafeSynchronized {
private static LazyThreadSafeSynchronized INSTANCE;
private LazyThreadSafeSynchronized() {
}
public static synchronized LazyThreadSafeSynchronized getInstance() {
if (INSTANCE == null) {
INSTANCE = new LazyThreadSafeSynchronized();
}
return INSTANCE;
}
}
第五种方式
public class PlainOldSingleton {
private static PlainOldSingleton INSTANCE = new PlainOldSingleton();
private PlainOldSingleton() {
}
public static PlainOldSingleton getInstance() {
return INSTANCE;
}
}
kotlin
第一种方式
class LazyNotThreadSafe private constructor(){
companion object {
val instance by lazy {
LazyNotThreadSafe()
}
// 下面是另一种等价的写法, 获取单例使用 get 方法
private var instance2: LazyNotThreadSafe? = null
fun get(): LazyNotThreadSafe {
if (instance2 == null)
instance2 = LazyNotThreadSafe()
return instance2!!
}
}
}
第二种方式
class LazyThreadSafeDoubleCheck private constructor() {
companion object {
val instance by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
LazyThreadSafeDoubleCheck()
}
private @Volatile
var instance2: LazyThreadSafeDoubleCheck? = null
fun get(): LazyThreadSafeDoubleCheck {
if (instance2 == null) {
synchronized(this) {
if (instance2 == null) {
instance2 = LazyThreadSafeDoubleCheck()
}
}
}
return instance2!!
}
}
}
第三种方式
class LazyThreadSafeStaticInnerClass private constructor() {
companion object {
fun getInstance() = Holder.instance
}
private object Holder {
val instance= LazyThreadSafeStaticInnerClass()
}
}
第四种方式
class LazyThreadSafeSynchronized private constructor() {
companion object {
private var instance: LazyThreadSafeSynchronized? = null
@Synchronized
fun get(): LazyThreadSafeSynchronized {
if (instance == null)
instance = LazyThreadSafeSynchronized()
return instance!!
}
}
}
第五种方式
/**
* 定义的类本身就是单例类
*/
object PlainOldSingleton
动态代理之解决reified不足的问题
{
"code": 0,
"message": "ok",
"content": {
"id": 1,
"name": "Unknown",
"songs": [
{
"id": 0,
"name": "Rada"
},
{
"id": 1,
"name": "Olympic Dream"
},
{
"id": 2,
"name": "The Escapist"
}
]
}
}
Gson的扩展方法
// 通常情况下使用inline+reified解决泛型不被擦
inline fun <reified T : Any> Gson.fromJson(json: String): T {
return fromJson(json, T::class.java)
}
通过动态代理获取到Singer类型
interface Api {
fun getSingerFromJson(json: String): BaseResult<Singer>
}
object ApiFactory {
val api: Api by lazy {
Proxy.newProxyInstance(
ApiFactory.javaClass.classLoader,
arrayOf(Api::class.java)
) { proxy, method, args ->
// 获取方法的返回值类型
val responseType = method.genericReturnType
val adapter = Gson().getAdapter(TypeToken.get(responseType))
adapter.fromJson(args[0].toString())
} as Api
}
}
代码示例:
val text = File("result_singer.json").readText()
val result: BaseResult<Singer> = gson.fromJson(text)
BaseResult(code=0, message=ok, content={id=1.0, name=Unknown, songs=[{id=0.0, name=Rada}, {id=1.0, name=Olympic Dream}, {id=2.0, name=The Escapist}]})
代码示例
val result2: BaseResult<Singer> = ApiFactory.api.getSingerFromJson(text)
println(result2)
BaseResult(code=0, message=ok, content=Singer(id=1, name=Unknown, songs=[Song(id=0, name=Rada), Song(id=1, name=Olympic Dream), Song(id=2, name=The Escapist)]))
使用高阶函数替换java中的回调接口
java代码
public class TaskExecutor {
private OnCompletionListener onCompletionListener;
public interface OnCompletionListener {
void onDone(long time);
}
public void setListener(OnCompletionListener listener) {
this.onCompletionListener = listener;
}
public void execute() {
Executors.newSingleThreadExecutor().execute(() -> {
for (int i = 0; i < 5; i++) {
System.out.println("time num " + i);
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (onCompletionListener != null) {
onCompletionListener.onDone(new Date().getTime());
}
});
}
}
调用
val taskExecutor = TaskExecutor()
taskExecutor.setListener {
object : TaskExecutor.OnCompletionListener {
override fun onDone(time: Long) {
println("time = $time")
}
}
}
// taskExecutor.execute()
println()
taskExecutor.setListener {
TaskExecutor.OnCompletionListener { time -> println("time = $time") }
}
// taskExecutor.execute()
// println()
kotlin代码
class KTTaskExecutor {
// 定义lambda表达式
private var listener: (Long) -> Unit = {}
// 设置接口
fun setListener(e: (Long) -> Unit) {
this.listener = e
}
fun exec(e: (Long) -> Unit) {
this.listener = e
Executors.newSingleThreadExecutor().execute {
for (i in 1..5) {
println("index at $i")
}
Thread.sleep(500)
e(Date().time) // 调用函数并传入数据
}
}
}
未改造前
class Request(val url: String) {
public fun run(callback: Callback) {
async {
val readText = URL(url).readText()
println("${javaClass.simpleName} , $readText")
uiThread {
println("${javaClass.simpleName} , $readText")
callback.done(readText)
}
}
}
public interface Callback {
fun done(data: String)
}
}
改造后
class AdvRequest(val url: String) {
// 匿名接口,需要传入一个数据
var listener: (String) -> Unit = {}
private set
fun run(e: (String) -> Unit) {
async {
val readText = URL(url).readText()
println("${javaClass.simpleName} , $readText")
uiThread {
println("${javaClass.simpleName} , $readText")
e(readText)
}
}
}
}
调用
KTTaskExecutor().exec { time ->
println("kttime = $time")
}
btn_exec_net_req.onClick {
rl_loading2.visibility = View.VISIBLE
Request(AppConst.API_REQ_STARTS).run(object : Request.Callback {
override fun done(data: String) {
tv_result.text = data
rl_loading2.visibility = View.GONE
}
})
}
btn_exec_net_req2.onClick {
rl_loading2.visibility = View.VISIBLE
AdvRequest(AppConst.API_REQ_STARTS).run { e ->
tv_result.text = e
rl_loading2.visibility = View.GONE
}
}