<|start_filename|>DSL/src/main/kotlin/User.kt<|end_filename|>
/**
 * Created by tony on 2018/9/17.
 */
class User{

    var name:String?=null
    var password: String?=null
    var addresses:Address?=null

    override fun toString() = "name=$name,password=$password"
}

<|start_filename|>Basic/src/main/kotlin/Polymorphism.kt<|end_filename|>
/**
 * Created by tony on 2018/7/13.
 */
open class Base

class Child: Base()

fun Base.foo() = println("this is from base")

fun Child.foo() = println("this is from child")

fun executeFoo(base: Base) = base.foo()

fun main(args: Array<String>) {
    var base = Base()
    var child = Child()

    executeFoo(base)
    executeFoo(child)
}

<|start_filename|>Coroutines1/src/main/kotlin/WithContext.kt<|end_filename|>

import kotlinx.coroutines.*
import kotlinx.coroutines.withContext

/**
 * Created by tony on 2018/8/26.
 */

fun main(args: Array<String>) {

    GlobalScope.launch {

        val result1 = withContext(Dispatchers.Default) {

            delay(2000)
            1
        }

        val  result2 = withContext(Dispatchers.IO) {

            delay(1000)
            2
        }

        val  result = result1 + result2
        println(result)
    }

    Thread.sleep(5000)
}

<|start_filename|>Basic/src/main/kotlin/Infix2.kt<|end_filename|>
/**
 * Created by tony on 2018/6/4.
 */
class Infix2 {

    infix fun add(i: Int):Int {

        return 5 + i
    }

    fun printValue() {

        println(this add 10)
        println(add(10))
    }
}

fun main(args: Array<String>) {

    var infix2 = Infix2()

    infix2.printValue()
}

<|start_filename|>Dagger2/app2/src/main/java/com/kotlin/tutorial/dagger2/app2/domain/Address.kt<|end_filename|>
package com.kotlin.tutorial.dagger2.app2.domain

import javax.inject.Inject

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.dagger2.app2.domain.Address.kt
 * @author: <NAME>
 * @date: 2018-08-10 15:57
 * @version V1.0 <描述当前版本功能>
 */
class Address @Inject constructor(street: Street) {

    private val street:Street

    init {

        this.street = street
    }

    override fun toString(): String {
        return "address:" + street.toString()
    }
}

<|start_filename|>Retrofit/app1/src/main/java/com/kotlin/tutorial/retrofit/app1/model/UserEventModel.kt<|end_filename|>
package com.kotlin.tutorial.retrofit.app1.model

import java.io.Serializable

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.retrofit.domain.response.UserEventModel.java
 * @author: <NAME>
 * @date: 2018-06-18 21:21
 * @version V1.0 <描述当前版本功能>
 */
data class Event(var id: String,
                 var type: String,
                 var actor: Actor,
                 var repo: Repo,
                 var payload: Payload,
                 var public: Boolean,
                 var created_at: String) : Serializable

data class Actor(var id: String,
                 var login: String,
                 var display_login: String,
                 var gravatar_id: String,
                 var url: String,
                 var avatar_url: String) : Serializable

data class Repo(var id: String,
                var name: String,
                var url: String) : Serializable

data class Payload(var push_id: Long,
                   var size: Int,
                   var distinct_size: Int,
                   var ref: String,
                   var head: String,
                   var before: String,
                   var commits: List<Commit>) : Serializable

data class Commit(var sha: String,
                  var author: Author,
                  var message: String,
                  var distinct: Boolean,
                  var url: String) : Serializable

data class Author(var email:String,
                  var name:String) : Serializable


<|start_filename|>Dagger2/app1/src/main/java/com/kotlin/tutorial/dagger2/di/component/DemoComponent.kt<|end_filename|>
package com.kotlin.tutorial.dagger2.di.component

import com.kotlin.tutorial.dagger2.activity.Demo4InterfaceInjectActivity
import com.kotlin.tutorial.dagger2.di.module.DemoModule
import dagger.Component

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.dagger2.di.component.DemoComponent.kt
 * @author: <NAME>
 * @date: 2018-08-03 11:46
 * @version V1.0 <描述当前版本功能>
 */
@Component(modules = arrayOf(DemoModule::class))
interface DemoComponent {

    fun inject(activity: Demo4InterfaceInjectActivity)
}

<|start_filename|>Coroutines1/src/main/kotlin/RunBlocking.kt<|end_filename|>
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking

/**
 * Created by tony on 2018/8/26.
 */

fun main(args: Array<String>) = runBlocking {

    launch {
        delay(1000)
        println("Hello World!")
    }

    delay(2000)
}

<|start_filename|>AAC/app/src/main/java/com/kotlin/tutorial/aac/db/UserDatabase.kt<|end_filename|>
package com.kotlin.tutorial.aac.db

import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.aac.db.UserDatabase
 * @author: <NAME>
 * @date: 2019-11-09 16:36
 * @version: V1.0 <描述当前版本功能>
 */
@Database(
        entities = [User::class],
        version = 2
)
abstract class UserDatabase : RoomDatabase() {

    abstract fun userDao(): UserDao

    companion object {

        @Volatile
        private var database: UserDatabase? = null

        fun getInstance(context: Context): UserDatabase =
                database ?: synchronized(this) {
                    database ?: buildDatabase(context).also{ database = it }
                }

        private fun buildDatabase(context: Context) =
                Room.databaseBuilder(
                        context.applicationContext,
                        UserDatabase::class.java, "db")
                        .allowMainThreadQueries()
                        .build()
    }
}


<|start_filename|>Dagger2/app1/src/main/java/com/kotlin/tutorial/dagger2/activity/MainActivity.kt<|end_filename|>
package com.kotlin.tutorial.dagger2.activity

import android.content.Intent
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import com.kotlin.tutorial.dagger2.R
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        text1.setOnClickListener {

            val intent = Intent(this,Demo4InjectActivity::class.java)
            startActivity(intent)
        }

        text2.setOnClickListener {

            val intent = Intent(this,Demo4ModuleActivity::class.java)
            startActivity(intent)
        }

        text3.setOnClickListener {

            val intent = Intent(this,Demo4InterfaceInjectActivity::class.java)
            startActivity(intent)
        }

        text4.setOnClickListener {

            val intent = Intent(this,Demo4InjectWithParamActivity::class.java)
            startActivity(intent)
        }

        text5.setOnClickListener {

            val intent = Intent(this,Demo4ComponentBuilderActivity::class.java)
            startActivity(intent)
        }

    }
}


<|start_filename|>Coroutines2/app/src/main/java/com/kotlin/tutorial/coroutines/model/PM25Model.kt<|end_filename|>
package com.kotlin.tutorial.coroutines.model

import java.io.Serializable

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.coroutines.model.PM25Model.kt
 * @author: <NAME>
 * @date: 2018-06-20 01:43
 * @version V1.0 <描述当前版本功能>
 */
data class PM25Model(

        var aqi: Int = 0,
        var area: String = "",
        var pm2_5: Int = 0,
        var pm2_5_24h: Int = 0,
        var position_name: String = "",
        var primary_pollutant: String = "",
        var quality: String = "",
        var station_code: String = "",
        var time_point: String = ""
) : Serializable

<|start_filename|>AAC/app/src/main/java/com/kotlin/tutorial/aac/fragment/Fragment2.kt<|end_filename|>
package com.kotlin.tutorial.aac.fragment

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import com.kotlin.tutorial.aac.R
import com.kotlin.tutorial.aac.delegate.viewModelDelegate
import com.kotlin.tutorial.aac.viewmodel.SharedViewModel
import kotlinx.android.synthetic.main.fragment_2.*
import kotlinx.android.synthetic.main.fragment_2.view.*

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.aac.fragment.Fragment2
 * @author: <NAME>
 * @date: 2019-11-10 22:26
 * @version: V1.0 <描述当前版本功能>
 */
class Fragment2 : Fragment() {

    private val viewModel by viewModelDelegate(SharedViewModel::class)

    override fun onCreateView(
            inflater: LayoutInflater, container: ViewGroup?,
            savedInstanceState: Bundle?
    ): View? {
        val v = inflater.inflate(R.layout.fragment_2, container, false)

        v.button.setOnClickListener {
            viewModel.setText(edit.text.toString())
        }

        return v
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)

        viewModel.getText().observe(viewLifecycleOwner, Observer {
            text -> edit.setText(text)
        })
    }
}

<|start_filename|>Dagger2/app1/src/main/java/com/kotlin/tutorial/dagger2/activity/Demo4InterfaceInjectActivity.kt<|end_filename|>
package com.kotlin.tutorial.dagger2.activity

import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.widget.Toast
import com.kotlin.tutorial.dagger2.IService
import com.kotlin.tutorial.dagger2.di.component.DaggerDemoComponent
import javax.inject.Inject

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.dagger2.activity.Demo4InterfaceInjectActivity.kt
 * @author: <NAME>
 * @date: 2018-08-03 11:33
 * @version V1.0 <描述当前版本功能>
 */
class Demo4InterfaceInjectActivity: AppCompatActivity() {

    @Inject
    lateinit var service: IService

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        DaggerDemoComponent.create().inject(this)

        Toast.makeText(this,service.foo(), Toast.LENGTH_LONG).show()
    }
}

<|start_filename|>Basic/src/main/kotlin/Noinline.kt<|end_filename|>
/**
 * Created by tony on 2018/7/13.
 */
fun doSomething1() {
    println("do something with inline")
}

fun doSomething2() {
    println("do something with noinline")
}

inline fun noinlineExample(something1: () -> Unit, noinline something2: () -> Unit) {
    something1.invoke()
    something2.invoke()
}

fun main(args: Array<String>) {
    noinlineExample(
            ::doSomething1,
            ::doSomething2
    )
}

<|start_filename|>Basic/src/main/kotlin/Extension3.kt<|end_filename|>
/**
 * Created by tony on 2018/5/31.
 */
class Extension3

val Extension3.text:String
    get() =  "this is a text property"


fun main(args: Array<String>) {
    var extension3 = Extension3()

    println(extension3.text)
}

<|start_filename|>Basic/src/main/kotlin/Main.kt<|end_filename|>
/**
 * Created by tony on 2018-11-29.
 */
fun main() {
    println("Hello Kotlin")
}

<|start_filename|>Coroutines1/src/main/kotlin/ChildCoroutine4.kt<|end_filename|>

import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch

/**
 * Created by tony on 2018/9/9.
 */
fun main(args: Array<String>) {

    val job = GlobalScope.launch {

        val childJob = GlobalScope.launch(Dispatchers.Default + coroutineContext) {
            println("childJob: I am a child of the job coroutine, but with a different dispatcher")
            delay(1000)
            println("childJob: I will not execute this line if job is cancelled")
        }

        childJob.join()
    }
    Thread.sleep(500)
    job.cancel() // 取消请求
    Thread.sleep(2000)
}

<|start_filename|>AAC/app/src/main/java/com/kotlin/tutorial/aac/activity/Activity4.kt<|end_filename|>
package com.kotlin.tutorial.aac.activity


import android.os.Bundle
import android.view.View
import android.widget.ArrayAdapter
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders
import com.kotlin.tutorial.aac.R
import com.kotlin.tutorial.aac.viewmodel.FruitViewModel
import kotlinx.android.synthetic.main.activity_4.*

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.aac.activity.Activity4
 * @author: <NAME>
 * @date: 2019-11-09 11:53
 * @version: V1.0 <描述当前版本功能>
 */
class Activity4: AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_4)

        this.progressbar.visibility = View.VISIBLE

        val viewModel: FruitViewModel = ViewModelProviders.of(this).get(FruitViewModel::class.java)

        viewModel.getFruitList().observe(this, Observer {

            var adapter: ArrayAdapter<String> = ArrayAdapter(this,android.R.layout.simple_list_item_1,it)
            this.listView.adapter = adapter
            this.progressbar.visibility = View.INVISIBLE
        })

    }
}

<|start_filename|>Retrofit/app1/src/main/java/com/kotlin/tutorial/retrofit/app1/activity/MainActivity.kt<|end_filename|>
package com.kotlin.tutorial.retrofit.app1.activity

import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import com.kotlin.tutorial.retrofit.app1.R

import com.kotlin.tutorial.retrofit.app1.http.RetrofitManager
import com.safframework.lifecycle.RxLifecycle
import com.safframework.utils.RxJavaUtils

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        initData()
    }

    private fun initData() {

        RetrofitManager.get()
                .apiService()
                .publicEvent("fengzhizi715")
                .compose(RxLifecycle.bind(this).toLifecycleTransformer())
                .compose(RxJavaUtils.maybeToMain())
                .subscribe()
    }
}


<|start_filename|>Basic/src/main/kotlin/HigherOrderFunctions3.kt<|end_filename|>
/**
 * Created by tony on 2018/7/4.
 */
fun sum(type: String): (Int, Int) -> Int {
    val identity = { x: Int -> x }
    val square = { x: Int -> x * x }
    val cube = { x: Int -> x * x * x }

    return when (type) {

        "identity" -> return { a, b -> sum(a, b, identity) }
        "square" -> return { a, b -> sum(a, b, square) }
        "cube" -> { a, b -> sum(a, b, cube) }
        else -> { a, b -> sum(a, b, identity) }
    }
}

fun main(args: Array<String>) {
    var identityFunction = sum("identity")
    println(identityFunction(1,10))

    var squareFunction = sum("square")
    println(squareFunction(1,10))

    var cubeFunction = sum("cube")
    println(cubeFunction(1,10))
}

<|start_filename|>Coroutines1/src/main/kotlin/Async1.kt<|end_filename|>
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.async
import kotlinx.coroutines.delay

/**
 * Created by tony on 2018/8/26.
 */

fun main(args: Array<String>) {

    val deferred  = GlobalScope.async {

        delay(1000)
        println("Hello Coroutines!")
    }

    Thread.sleep(2000)
}

<|start_filename|>Benchmark/src/main/kotlin/benchmark/SequenceBenchmark.kt<|end_filename|>
package benchmark

import org.openjdk.jmh.annotations.*
import org.openjdk.jmh.runner.Runner
import org.openjdk.jmh.runner.options.OptionsBuilder
import java.util.concurrent.TimeUnit

/**
 * Created by tony on 2018-12-10.
 */
@BenchmarkMode(Mode.Throughput) // 基准测试的模式，采用整体吞吐量的模式
@Warmup(iterations = 3) // 预热次数
@Measurement(iterations = 10, time = 5, timeUnit = TimeUnit.SECONDS) // 测试参数，iterations = 10 表示进行10轮测试
@Threads(8) // 每个进程中的测试线程数
@Fork(2)  // 进行 fork 的次数，表示 JMH 会 fork 出两个进程来进行测试
@OutputTimeUnit(TimeUnit.MILLISECONDS) // 基准测试结果的时间类型
open class SequenceBenchmark {

    @Benchmark
    fun testSequence():Int {
        return sequenceOf(1,2,3,4,5,6,7,8,9,10)
                .map{ it * 2 }
                .filter { it % 3  == 0 }
                .map{ it+1 }
                .sum()
    }

    @Benchmark
    fun testList():Int {
        return listOf(1,2,3,4,5,6,7,8,9,10)
                .map{ it * 2 }
                .filter { it % 3  == 0 }
                .map{ it+1 }
                .sum()
    }
}

fun main() {
    val options = OptionsBuilder()
            .include(SequenceBenchmark::class.java.simpleName)
            .output("benchmark_sequence.log")
            .build()
    Runner(options).run()
}

<|start_filename|>Coroutines1/src/main/kotlin/Actor.kt<|end_filename|>
import kotlinx.coroutines.channels.actor
import kotlinx.coroutines.runBlocking

/**
 * Created by tony on 2018/9/10.
 */
fun main(args: Array<String>) = runBlocking<Unit> {

    val summer = actor<Int>(coroutineContext) {
        var sum = 0

        for (i in channel) { // 不断接收channel中的数据，这个channel是ActorScope的变量
            sum += i
            println("Sum = $sum")
        }
    }

    repeat(10) {

        i->summer.send(i+1) // 发送从1到10
    }

    summer.close()
}

<|start_filename|>Basic/src/main/kotlin/Infix1.kt<|end_filename|>
/**
 * Created by tony on 2018/6/4.
 */
infix fun Int.add(i:Int):Int = this + i

infix fun Int.加(i:Int):Int = this + i

fun main(args: Array<String>) {

    println(5 add 10)
    println(5 加 10)
}


<|start_filename|>Basic/src/main/java/Generic4.java<|end_filename|>
import java.util.ArrayList;
import java.util.List;

/**
 * Created by tony on 2019-06-23.
 */
public class Generic4 {

    public static void main(String[] args) {

        List<? super Animal> animals = new ArrayList<>();
        animals.add(new Dog());
    }
}


<|start_filename|>AAC/app/src/main/java/com/kotlin/tutorial/aac/viewmodel/FruitViewModel.kt<|end_filename|>
package com.kotlin.tutorial.aac.viewmodel

import android.os.Handler
import android.util.Log
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.aac.viewmodel.FruitViewModel
 * @author: <NAME>
 * @date: 2019-11-09 12:03
 * @version: V1.0 <描述当前版本功能>
 */
class FruitViewModel: ViewModel() {

    private var fruitList: MutableLiveData<List<String>>? = null
    private val handler:Handler = Handler()

    override fun onCleared() {
        super.onCleared()
        Log.d(TAG, "onCleared");
    }

    fun getFruitList(): LiveData<List<String>> {

        if (fruitList == null) {
            fruitList = MutableLiveData<List<String>>()
            loadFruits()
        }
        return fruitList as LiveData<List<String>>
    }

    /**
     * 模拟网络请求，延迟2.5s
     */
    private fun loadFruits(){
        handler.postDelayed({
            val list = ArrayList<String>()
            list.add("Apple")
            list.add("Banana")
            list.add("Orange")
            list.add("Pear")
            list.add("Watermelon")

            fruitList?.let {

                it.value = list
            }
        }, 2500)
    }

    companion object {
        private val TAG = FruitViewModel::class.java.simpleName
    }
}

<|start_filename|>Dagger2/app2/src/main/java/com/kotlin/tutorial/dagger2/app2/di/qualifier/Tony.kt<|end_filename|>
package com.kotlin.tutorial.dagger2.app2.di.qualifier

import javax.inject.Qualifier

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.dagger2.app2.di.qualifier.Tony.kt
 * @author: <NAME>
 * @date: 2018-08-13 17:44
 * @version V1.0 <描述当前版本功能>
 */
@Qualifier
annotation class Tony

<|start_filename|>Coroutines1/src/main/kotlin/Channel1.kt<|end_filename|>
import kotlinx.coroutines.*
import kotlinx.coroutines.channels.Channel

/**
 * Created by tony on 2018/9/9.
 */
fun main(args: Array<String>) = runBlocking {

    val channel = Channel<Int>()  //定义一个通道

    launch(Dispatchers.Default) {

        repeat(5) { // 重复5次发送消息，相当于 for(int i=0;i<5;i++)

            i ->
            delay(200)
            channel.send((i + 1) * (i + 1))
        }
    }

    launch(Dispatchers.Default) {

        repeat(5) {

            println(channel.receive())
        }
    }

    delay(2000)

    println("Receive Done!")
}

<|start_filename|>Basic/src/main/java/Generic3.java<|end_filename|>
import java.util.ArrayList;
import java.util.List;

/**
 * Created by tony on 2019-06-23.
 */
public class Generic3 {

    public static void main(String[] args) {

        List<? extends Animal> animals = new ArrayList<>();
        List<Dog> dogs = new ArrayList<>();
        animals = dogs;
    }
}


<|start_filename|>Coroutines2/app/src/main/java/com/kotlin/tutorial/coroutines/ext/View+Extension.kt<|end_filename|>
package com.kotlin.tutorial.coroutines.ext

import android.view.View
import kotlinx.coroutines.*
import kotlinx.coroutines.channels.actor

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.coroutines.ext.`View+Extension`.kt
 * @author: <NAME>
 * @date: 2018-09-02 14:27
 * @version: V1.0 <描述当前版本功能>
 */
interface JobHolder {
    val job: Job
}

val View.contextJob: Job
    get() = (context as? JobHolder)?.job ?: NonCancellable

fun View.onClick(time: Long = 600,action: suspend (View) -> Unit) {

    // launch one actor as a parent of the context job
    val eventActor = GlobalScope.actor<Unit>(contextJob + Dispatchers.Main ) {
        for (event in channel) {

            delay(time)
            action(this@onClick)
        }
    }

    // install a listener to activate this actor
    setOnClickListener {
        eventActor.offer(Unit)
    }
}

<|start_filename|>DSL/src/main/kotlin/Address.kt<|end_filename|>
/**
 * Created by tony on 2018/9/20.
 */
class Address {

    var province: String?=null
    var city: String?=null
    var street: String?=null

    override fun toString() = "province=$province,city=$city,street=$street"
}

<|start_filename|>Dagger2/app1/src/main/java/com/kotlin/tutorial/dagger2/domain/User.kt<|end_filename|>
package com.kotlin.tutorial.dagger2.domain

import javax.inject.Inject

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.dagger2.domain.User.kt
 * @author: <NAME>
 * @date: 2018-08-01 23:56
 * @version V1.0 <描述当前版本功能>
 */
class User @Inject constructor() {

    lateinit var param:String

    constructor(param:String) : this() {
        this.param = param
    }

    fun testInject() = "this is the first Inject"

    fun testModule() = "this is the second Inject"

    fun testInjectWithParam() =  "this is the Inject with parameter: $param"

    fun testComponentBuilder() = "this is the Inject with parameter: $param"
}

<|start_filename|>AAC/app/src/main/java/com/kotlin/tutorial/aac/activity/Activity5.kt<|end_filename|>
package com.kotlin.tutorial.aac.activity

import android.os.Bundle
import android.view.View
import android.widget.ArrayAdapter
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.Observer
import com.kotlin.tutorial.aac.R
import com.kotlin.tutorial.aac.delegate.viewModelDelegate
import com.kotlin.tutorial.aac.viewmodel.FruitViewModel
import kotlinx.android.synthetic.main.activity_4.*

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.aac.activity.Activity5
 * @author: <NAME>
 * @date: 2019-11-09 12:46
 * @version: V1.0 <描述当前版本功能>
 */
class Activity5: AppCompatActivity() {

    private val viewModel by viewModelDelegate(FruitViewModel::class)

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_4)

        this.progressbar.visibility = View.VISIBLE

        viewModel.getFruitList().observe(this, Observer {

            var adapter: ArrayAdapter<String> = ArrayAdapter(this,android.R.layout.simple_list_item_1,it)
            this.listView.adapter = adapter
            this.progressbar.visibility = View.INVISIBLE
        })

    }
}

<|start_filename|>Dagger2/app1/src/main/java/com/kotlin/tutorial/dagger2/di/component/UserComponent2.kt<|end_filename|>
package com.kotlin.tutorial.dagger2.di.component

import com.kotlin.tutorial.dagger2.activity.Demo4ModuleActivity
import com.kotlin.tutorial.dagger2.di.module.UserModule2
import dagger.Component

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.dagger2.di.component.UserComponent2.kt
 * @author: <NAME>
 * @date: 2018-08-02 01:02
 * @version V1.0 <描述当前版本功能>
 */
@Component(modules = arrayOf(UserModule2::class))
interface UserComponent2 {

    fun inject(activity: Demo4ModuleActivity)
}

<|start_filename|>Basic/src/main/kotlin/delegates/Delegate.kt<|end_filename|>
package delegates

/**
 * Created by tony on 2018/8/7.
 */
interface Marks {

    fun printMarks()
}

class StdMarks : Marks {

    override fun printMarks() = println("printed marks")
}

class ExcelMarks : Marks {

    override fun printMarks() = println("printed marks and export to excel")
}

interface Totals {

    fun printTotals()
}

class StdTotals : Totals {

    override fun printTotals() = println("calculated and printed totals")
}

class ExcelTotals : Totals {

    override fun printTotals() = println("calculated and printed totals and export to excel")
}

class Student(studentId: Int, marks: Marks, totals: Totals)
    : Marks by marks, Totals by totals

fun main(args: Array<String>) {

    val student1 = Student(1, StdMarks(), StdTotals()) // StdMarks、StdTotals 为 Student 被委托的类
    student1.printMarks()
    student1.printTotals()

    println("---------------------------")

    val student2 = Student(2, ExcelMarks(), ExcelTotals()) // ExcelMarks、ExcelTotals 为 Student 被委托的类
    student2.printMarks()
    student2.printTotals()
}

<|start_filename|>DSL/src/main/kotlin/Apply.kt<|end_filename|>
/**
 * Created by tony on 2018/9/17.
 */
fun main(args: Array<String>) {

    val user = User().apply {

        name = "Tony"  // 此处省略了this，完整的应该是this.name= "Tony"
        password = "<PASSWORD>"
    }

    println(user)
}

<|start_filename|>Dagger2/app2/src/main/java/com/kotlin/tutorial/dagger2/app2/di/module/UserModule3.kt<|end_filename|>
package com.kotlin.tutorial.dagger2.app2.di.module

import com.kotlin.tutorial.dagger2.app2.domain.User
import dagger.Module
import dagger.Provides
import javax.inject.Named

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.dagger2.app2.di.module.UserModule3.kt
 * @author: <NAME>
 * @date: 2018-08-10 17:58
 * @version V1.0 <描述当前版本功能>
 */
@Module
class UserModule3 {

    @Named("tony")
    @Provides
    fun provideTony() = User("Tony")


    @Named("monica")
    @Provides
    fun provideMonica() = User("Monica")
}

<|start_filename|>Dagger2/app1/src/main/java/com/kotlin/tutorial/dagger2/activity/Demo4InjectWithParamActivity.kt<|end_filename|>
package com.kotlin.tutorial.dagger2.activity

import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.widget.Toast
import com.kotlin.tutorial.dagger2.di.component.DaggerUserComponent3
import com.kotlin.tutorial.dagger2.di.module.UserModule3
import com.kotlin.tutorial.dagger2.domain.User
import javax.inject.Inject

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.dagger2.activity.Demo4InjectWithParamActivity.kt
 * @author: <NAME>
 * @date: 2018-08-03 12:57
 * @version V1.0 <描述当前版本功能>
 */
class Demo4InjectWithParamActivity: AppCompatActivity() {

    @Inject
    lateinit var user: User

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val userModule = UserModule3()
        userModule.param("this is a parameter")

        DaggerUserComponent3.builder().userModule3(userModule).build().inject(this)

        Toast.makeText(this,user.testInjectWithParam(), Toast.LENGTH_LONG).show()
    }
}

<|start_filename|>Dagger2/app3/src/main/java/com/kotlin/tutorial/dagger2/app3/di/component/StreetComponent2.kt<|end_filename|>
package com.kotlin.tutorial.dagger2.app3.di.component

import com.kotlin.tutorial.dagger2.app3.di.module.StreetModule
import com.kotlin.tutorial.dagger2.app3.domain.Street
import dagger.Component

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.dagger2.app3.di.component.StreetComponent2
 * @author: <NAME>
 * @date: 2019-12-27 01:27
 * @version: V1.0 <描述当前版本功能>
 */
@Component(modules = arrayOf(StreetModule::class))
interface StreetComponent2 {

    fun inject(street: Street)

    fun street(): Street
}

<|start_filename|>Dagger2/app2/src/main/java/com/kotlin/tutorial/dagger2/app2/domain/User.kt<|end_filename|>
package com.kotlin.tutorial.dagger2.app2.domain

import javax.inject.Inject

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.dagger2.app2.domain.User.kt
 * @author: <NAME>
 * @date: 2018-08-08 00:50
 * @version V1.0 <描述当前版本功能>
 */
class User @Inject constructor() {

    private lateinit var userName: String

    constructor(userName:String) : this() {
        this.userName = userName
    }

    fun testLazy() = "this is the Lazy Inject"

    fun printUserName() = "the userName is $userName"
}

<|start_filename|>Dagger2/app3/src/main/java/com/kotlin/tutorial/dagger2/app3/activity/Demo4ModuleIncludeActivity.kt<|end_filename|>
package com.kotlin.tutorial.dagger2.app3.activity

import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.widget.Toast
import com.kotlin.tutorial.dagger2.app3.di.component.DaggerAddressComponent1

import com.kotlin.tutorial.dagger2.app3.domain.Address
import javax.inject.Inject

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.dagger2.app3.activity.Demo4ModuleIncludeActivity.kt
 * @author: <NAME>
 * @date: 2018-08-23 19:03
 * @version: V1.0 <描述当前版本功能>
 */
class Demo4ModuleIncludeActivity : AppCompatActivity() {

    @Inject
    lateinit var address: Address

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        DaggerAddressComponent1.create().inject(this)

        Toast.makeText(this,address.toString(), Toast.LENGTH_LONG).show()
    }
}

<|start_filename|>Dagger2/app1/src/main/java/com/kotlin/tutorial/dagger2/di/module/UserModule2.kt<|end_filename|>
package com.kotlin.tutorial.dagger2.di.module

import com.kotlin.tutorial.dagger2.domain.User
import dagger.Module
import dagger.Provides

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.dagger2.di.module.UserModule2.ktt
 * @author: <NAME>
 * @date: 2018-08-02 00:59
 * @version V1.0 <描述当前版本功能>
 */
@Module
class UserModule2 {

    @Provides
    fun provideUser() = User()
}

<|start_filename|>Coroutines2/app/src/main/java/com/kotlin/tutorial/coroutines/model/ZipObject.kt<|end_filename|>
package com.kotlin.tutorial.coroutines.model

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.coroutines.model.ZipObject.java
 * @author: <NAME>
 * @date: 2018-06-20 10:44
 * @version V1.0 <描述当前版本功能>
 */
data class ZipObject(

        var pm2_5_quality: String?,
        var pm2_5: Int?,
        var pm2_5_24h: Int?,

        var so2: Int?,
        var so2_24h: Int?
)

<|start_filename|>Basic/src/main/kotlin/SAM.kt<|end_filename|>
/**
 * Created by tony on 2018/7/10.
 */
fun main(args: Array<String>) {

    val runnable = Runnable{

        println("test")
    }

    Thread (runnable).start()
}

<|start_filename|>DSL/src/main/kotlin/Dependency.kt<|end_filename|>
/**
 * Created by tony on 2018/9/24.
 */
class Dependency {

    fun compile(library: String) {
        println("$library")
    }

    operator fun invoke(action: Dependency.() -> Unit) {
        action()
    }
}

fun main(args: Array<String>) {

    val dependencies = Dependency()

    dependencies{

        compile("com.safframework.log:saf-log:1.5.4")  // 此处省略了this指代的是dependencies，完整的应该是 this.compile("com.safframework.log:saf-log:1.5.4")
        compile("com.safframework.log:saf-logginginterceptor:1.3.1")
    }
}

<|start_filename|>Dagger2/app1/src/main/java/com/kotlin/tutorial/dagger2/IService.kt<|end_filename|>
package com.kotlin.tutorial.dagger2

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.dagger2.IService.java
 * @author: <NAME>
 * @date: 2018-08-03 11:37
 * @version V1.0 <描述当前版本功能>
 */
interface IService {

    fun foo():String
}

<|start_filename|>DSL/src/main/kotlin/TestUserWrapper.kt<|end_filename|>
/**
 * Created by tony on 2018/9/20.
 */
fun main(args: Array<String>) {

    val user =  user{

        name = "Tony"
        password = "<PASSWORD>"
        address {

            province = "Jiangsu"
            city = "Suzhou"
            street = "Renming Road"
        }
    }

    println(user.addresses)
}

<|start_filename|>Basic/src/main/kotlin/Recursive.kt<|end_filename|>
/**
 * Created by tony on 2018/7/27.
 */
fun sum(n: Int, result: Int): Int = if (n <= 0) result else sum(n-1,result+n)

fun main(args: Array<String>) {
    println(sum(100000,0))
}

<|start_filename|>Dagger2/app2/src/main/java/com/kotlin/tutorial/dagger2/app2/di/module/AddressModule.kt<|end_filename|>
package com.kotlin.tutorial.dagger2.app2.di.module

import com.kotlin.tutorial.dagger2.app2.domain.Address
import com.kotlin.tutorial.dagger2.app2.domain.Street
import dagger.Module
import dagger.Provides

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.dagger2.app3.di.module.AddressModule.kt
 * @author: <NAME>
 * @date: 2018-08-10 15:58
 * @version V1.0 <描述当前版本功能>
 */
@Module
class AddressModule {

    @Provides
    fun provideAddress(street: Street) = Address(street)
}

<|start_filename|>Basic/src/main/kotlin/classes/DataClass1.kt<|end_filename|>
package classes

/**
 * Created by tony on 2018/8/15.
 */
data class Address(var street:String)

data class User(var name:String,var password:String,var address: Address)

fun main(args: Array<String>) {
    val user1 = User("tony","<PASSWORD>", Address("renming"))

    val user2 = user1.copy()
    println(user2)

    println(user1.address===user2.address) // 判断 data class 的 copy 是否为浅拷贝，如果二者的address指向的内存地址相同则为浅拷贝，反之为深拷贝

    val user3 = user1.copy("monica")
    println(user3)

    val user4 = user1.copy(password = "<PASSWORD>")
    println(user4)
}

<|start_filename|>Basic/src/main/kotlin/generic/Generic3.kt<|end_filename|>
package generic

import java.util.ArrayList

/**
 * Created by tony on 2019-06-23.
 */
fun main() {

    var animals: List<Animal> = ArrayList()
    val dogs = ArrayList<Dog>()
    animals = dogs
}

<|start_filename|>AAC/app/src/main/java/com/kotlin/tutorial/aac/db/UserDao.kt<|end_filename|>
package com.kotlin.tutorial.aac.db

import androidx.lifecycle.LiveData
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.Query

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.aac.db.UserDao
 * @author: <NAME>
 * @date: 2019-11-09 16:35
 * @version: V1.0 <描述当前版本功能>
 */
@Dao
interface UserDao {

    @Insert
    fun insert(obj: User): Long

    @Query("SELECT * FROM users")
    fun getAll(): LiveData<List<User>>

    @Query("SELECT Count(*) FROM users")
    fun getCount(): Int

    @Query("DELETE FROM users")
    fun deleteAll()
}

<|start_filename|>Dagger2/app2/src/main/java/com/kotlin/tutorial/dagger2/app2/activity/Demo4CustomerQualifierActivity.kt<|end_filename|>
package com.kotlin.tutorial.dagger2.app2.activity

import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.widget.Toast
import com.kotlin.tutorial.dagger2.app2.R
import com.kotlin.tutorial.dagger2.app2.di.component.DaggerUserComponent4
import com.kotlin.tutorial.dagger2.app2.di.qualifier.Monica
import com.kotlin.tutorial.dagger2.app2.di.qualifier.Tony
import com.kotlin.tutorial.dagger2.app2.domain.User
import kotlinx.android.synthetic.main.activity_demo_4_qualifier.*
import javax.inject.Inject

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.dagger2.app2.activity.Demo4CustomerQualifierActivity.kt
 * @author: <NAME>
 * @date: 2018-08-13 17:48
 * @version V1.0 <描述当前版本功能>
 */
class Demo4CustomerQualifierActivity : AppCompatActivity() {

    @Inject
    @field:Tony
    lateinit var tony: User

    @Inject
    @field:Monica
    lateinit var monica: User

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_demo_4_qualifier)

        DaggerUserComponent4.create().inject(this);

        text1.setOnClickListener {

            Toast.makeText(this@Demo4CustomerQualifierActivity,tony.printUserName(), Toast.LENGTH_LONG).show()
        }

        text2.setOnClickListener {

            Toast.makeText(this@Demo4CustomerQualifierActivity,monica.printUserName(), Toast.LENGTH_LONG).show()
        }
    }
}

<|start_filename|>Dagger2/app2/src/main/java/com/kotlin/tutorial/dagger2/app2/di/component/UserComponent4.kt<|end_filename|>
package com.kotlin.tutorial.dagger2.app2.di.component

import com.kotlin.tutorial.dagger2.app2.activity.Demo4CustomerQualifierActivity
import com.kotlin.tutorial.dagger2.app2.di.module.UserModule4
import dagger.Component

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.dagger2.app2.di.component.UserComponent4.kt
 * @author: <NAME>
 * @date: 2018-08-13 17:46
 * @version V1.0 <描述当前版本功能>
 */
@Component(modules = arrayOf(UserModule4::class))
interface UserComponent4 {

    fun inject(activity: Demo4CustomerQualifierActivity)
}

<|start_filename|>Basic/src/main/kotlin/classes/Color.kt<|end_filename|>
package classes

/**
 * Created by tony on 2018/8/20.
 */
enum class Color constructor(var colorName: String, var value: Int) {

    RED("红色", 1), GREEN("绿色", 2), BLUE("蓝色", 3)
}

<|start_filename|>Benchmark/src/main/kotlin/benchmark/CoroutinesBenchmark.kt<|end_filename|>
package benchmark

import io.reactivex.Observable
import kotlinx.coroutines.runBlocking
import org.openjdk.jmh.annotations.*
import org.openjdk.jmh.runner.Runner
import org.openjdk.jmh.runner.options.OptionsBuilder
import java.util.concurrent.TimeUnit
import java.util.concurrent.atomic.AtomicInteger


/**
 * Created by tony on 2018-12-11.
 */
@BenchmarkMode(Mode.Throughput) // 基准测试的模式，采用整体吞吐量的模式
@Warmup(iterations = 3) // 预热次数
@Measurement(iterations = 10, time = 5, timeUnit = TimeUnit.SECONDS) // 测试参数，iterations = 10 表示进行10轮测试
@Threads(8) // 每个进程中的测试线程数
@Fork(2)  // 进行 fork 的次数，表示 JMH 会 fork 出两个进程来进行测试
@OutputTimeUnit(TimeUnit.MILLISECONDS) // 基准测试结果的时间类型
@State(Scope.Thread) // 为每个线程独享
open class CoroutinesBenchmark {

    var counter1 = AtomicInteger()
    var counter2 = AtomicInteger()

    @Setup
    fun prepare() {
        counter1.set(0)
        counter2.set(0)
    }

    fun calculate(counter:AtomicInteger): Double {
        val result = ArrayList<Int>()

        for (i in 0 until 10_000) {

            result.add(counter.incrementAndGet())
        }

        return result.asSequence().filter { it % 3 ==0 }.map { it *2 + 1 }.average()
    }

    @Benchmark
    fun testCoroutines() = runBlocking {
        calculate(counter1)
    }

    @Benchmark
    fun testRxJava() = Observable.fromCallable { calculate(counter2) }.blockingFirst()

}

fun main() {
    val options = OptionsBuilder()
            .include(CoroutinesBenchmark::class.java.simpleName)
            .output("benchmark_coroutines.log")
            .build()
    Runner(options).run()
}

<|start_filename|>Basic/src/main/kotlin/Invoke.kt<|end_filename|>
/**
 * Created by tony on 2018/7/2.
 */
class InvokeClass{

    var sum:Int = 0

    operator fun invoke(param: Int){

        sum += param
        println("print in invoke method, param is $param, the sum = $sum")
    }

    operator fun invoke(param1: Int, param2: Int): InvokeClass{

        sum += param1 + param2

        println("print in invoke method, param1 is $param1, param2 is $param2, the sum = $sum")

        return this
    }
}


fun main(args: Array<String>) {

    val obj = InvokeClass()

    obj.invoke(4)
    obj(4)
    obj(5,6)(7,8)(9)

    println(obj.sum)
}

<|start_filename|>Dagger2/app1/src/main/java/com/kotlin/tutorial/dagger2/di/module/UserModule4.kt<|end_filename|>
package com.kotlin.tutorial.dagger2.di.module

import com.kotlin.tutorial.dagger2.domain.User
import dagger.Module
import dagger.Provides

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.dagger2.di.module.UserModule4.java
 * @author: <NAME>
 * @date: 2018-08-02 17:13
 * @version V1.0 <描述当前版本功能>
 */
@Module
class UserModule4 {

    @Provides
    fun provideUser(param:String) = User(param)
}

<|start_filename|>Coroutines1/src/main/kotlin/Channel5.kt<|end_filename|>
import kotlinx.coroutines.*
import kotlinx.coroutines.channels.Channel

/**
 * Created by tony on 2018/9/11.
 */
fun main(args: Array<String>) = runBlocking<Unit>{

    val channel = Channel<Int>(2) // 创建带有缓冲区的 channel

    launch(kotlin.coroutines.coroutineContext) {
        repeat(6) {
            delay(50)
            println("Sending $it")
            channel.send(it)
        }
    }

    launch {

        delay(1000)
        repeat(6) {
            println("Receive ${channel.receive()}")
        }
    }

    delay(20000)
}

<|start_filename|>Basic/src/main/kotlin/classes/Constructor1.kt<|end_filename|>
package classes

/**
 * Created by tony on 2018/8/10.
 */
class Constructor1 {

    init {

        println("test")
    }

    fun foo() = println("this is foo function")

}

fun main(args: Array<String>) {
    val obj = Constructor1()
    obj.foo()
}

<|start_filename|>Dagger2/app2/src/main/java/com/kotlin/tutorial/dagger2/app2/di/component/AddressComponent.kt<|end_filename|>
package com.kotlin.tutorial.dagger2.app2.di.component

import com.kotlin.tutorial.dagger2.app2.activity.Demo4RecursiveInjectActivity
import com.kotlin.tutorial.dagger2.app2.di.module.StreetModule
import com.kotlin.tutorial.dagger2.app2.di.module.AddressModule
import dagger.Component

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.dagger2.app2.di.component.AddressComponent.kt
 * @author: <NAME>
 * @date: 2018-08-10 16:20
 * @version V1.0 <描述当前版本功能>
 */
@Component(modules = arrayOf(AddressModule::class,StreetModule::class))
interface AddressComponent {

    fun inject(activity: Demo4RecursiveInjectActivity)
}

<|start_filename|>Basic/src/main/kotlin/TailRecursive.kt<|end_filename|>
/**
 * Created by tony on 2018/7/27.
 */
tailrec fun sumWithTailrec(n: Int, result: Int): Int = if (n <= 0) result else sumWithTailrec(n-1,result+n)

fun main(args: Array<String>) {
    println(sumWithTailrec(100000,0))
}

<|start_filename|>DSL/src/test/kotlin/AssertionTest.kt<|end_filename|>

import org.junit.Test

/**
 * Created by tony on 2018/9/25.
 */
class AssertionTest {

    @Test
    fun unitTestingWorks(){

        val result = Assertion(10)

        result isEqualTo 10
        result isDifferentFrom 11
    }
}

<|start_filename|>Coroutines1/src/main/kotlin/ChildCoroutine3.kt<|end_filename|>
import kotlinx.coroutines.*

/**
 * Created by tony on 2018/9/9.
 */
fun main(args: Array<String>) {

    val job = GlobalScope.launch {

        val childJob = GlobalScope.launch(Dispatchers.Default) {
            println("childJob: I am a child of the request coroutine, but with a different dispatcher")
            delay(1000)
            println("childJob: I will not execute this line if job is cancelled")
        }

        childJob.join()
    }
    Thread.sleep(500)
    job.cancel() // 取消请求
    Thread.sleep(2000)
}

<|start_filename|>Basic/src/main/kotlin/classes/SealedClass.kt<|end_filename|>
package classes

/**
 * Created by tony on 2018/8/20.
 */
sealed class Mammal(val name: String)

class Dog(dogName: String) : Mammal(dogName)
class Horse(horseName:String) :Mammal(horseName)
class Human(humanName: String, val job: String) : Mammal(humanName)

fun greetMammal(mammal: Mammal) = when (mammal) {
    is Dog -> "Hello ${mammal.name}"
    is Horse -> "Hello ${mammal.name}"
    is Human -> "Hello ${mammal.name}, You're working as a ${mammal.job}"
}

fun main(args: Array<String>) {
    println(greetMammal(Dog("wangwang")))
    println(greetMammal(Horse("chitu")))
    println(greetMammal(Human("tony", "coder")))
}

<|start_filename|>Coroutines1/src/main/kotlin/Yield.kt<|end_filename|>
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.yield

/**
 * Created by tony on 2018-11-30.
 */

fun main(args: Array<String>) = runBlocking {

    val job1 = launch {

        println(1)
        yield()
        println(3)
        yield()
        println(5)
    }

    val job2 = launch {

        println(2)
        yield()
        println(4)
        yield()
        println(6)
    }

    println(0)

    // 无论是否调用以下两句，上面两个协程都会运行
    job1.join()
    job2.join()
}

<|start_filename|>Dagger2/app1/src/main/java/com/kotlin/tutorial/dagger2/di/module/UserModule3.kt<|end_filename|>
package com.kotlin.tutorial.dagger2.di.module

import com.kotlin.tutorial.dagger2.domain.User
import dagger.Module
import dagger.Provides

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.dagger2.di.module.UserModule3.kt
 * @author: <NAME>
 * @date: 2018-08-03 13:03
 * @version V1.0 <描述当前版本功能>
 */
@Module
class UserModule3 {

    lateinit var param: String

    fun param(param: String) {
        this.param = param
    }

    @Provides
    fun provideUser() = User(param)
}

<|start_filename|>Basic/src/main/kotlin/generic/Generic4.kt<|end_filename|>
package generic

/**
 * Created by tony on 2019-06-23.
 */
abstract class Printer<in E> {

    abstract fun print(value: E): Unit
}

class AnimalPrinter: Printer<Animal>() {

    override fun print(animal: Animal) {
        println("this is animal")
    }
}

class DogPrinter : Printer<Dog>() {

    override fun print(dog: Dog) {
        println("this is dog")
    }
}

fun main() {

    val animalPrinter = AnimalPrinter()
    animalPrinter.print(Animal())

    val dogPrinter = DogPrinter()
    dogPrinter.print(Dog())
}

<|start_filename|>Basic/src/main/kotlin/MethodReference.kt<|end_filename|>

import java.util.*

/**
 * Created by tony on 2018/7/10.
 */
fun main(args: Array<String>) {
    val u1 = User("tony")
    val u2 = User("cafei")
    val u3 = User("aaron")

    val users = Arrays.asList(u1, u2, u3)

    Collections.sort(users, Comparator.comparing(User::getName))
}

<|start_filename|>Dagger2/app2/src/main/java/com/kotlin/tutorial/dagger2/app2/activity/Demo4RecursiveInjectActivity.kt<|end_filename|>
package com.kotlin.tutorial.dagger2.app2.activity

import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.widget.Toast
import com.kotlin.tutorial.dagger2.app2.di.component.DaggerAddressComponent
import com.kotlin.tutorial.dagger2.app2.domain.Address
import javax.inject.Inject

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.dagger2.app2.activity.Demo4RecursiveInjectActivity.kt
 * @author: <NAME>
 * @date: 2018-08-10 15:53
 * @version V1.0 <描述当前版本功能>
 */
class Demo4RecursiveInjectActivity : AppCompatActivity() {

    @Inject
    lateinit var address: Address

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        DaggerAddressComponent.create().inject(this)

        Toast.makeText(this,address.toString(), Toast.LENGTH_LONG).show()
    }
}

<|start_filename|>Basic/src/main/java/Dog.java<|end_filename|>
/**
 * Created by tony on 2019-06-23.
 */
public class Dog extends Animal{
}

class Animal {
}


<|start_filename|>Coroutines1/src/main/kotlin/CoroutineDispatchers2.kt<|end_filename|>
import kotlinx.coroutines.*

/**
 * Created by tony on 2018/9/10.
 */
fun main(args: Array<String>) = runBlocking(Dispatchers.Default) {

    val jobs = ArrayList<Job>()

    jobs += launch(Dispatchers.Unconfined) { // 无限制
        println("'Unconfined': I'm working in thread ${Thread.currentThread().name}")
        delay(500)
        println("'Unconfined': After delay in thread ${Thread.currentThread().name}")
    }

    jobs += launch(coroutineContext) { // 使用父级的上下文，也就是 runBlocking 的上下文
        println("'coroutineContext': I'm working in thread ${Thread.currentThread().name}")
    }

    jobs += launch(Dispatchers.Default) {
        println("'Dispatchers.Default': I'm working in thread ${Thread.currentThread().name}")
    }

    jobs += launch {
        println("'default': I'm working in thread ${Thread.currentThread().name}")
    }

    jobs += launch(newSingleThreadContext("MyThread")) { // 创建自己的新线程
        println("'MyThread': I'm working in thread ${Thread.currentThread().name}")
    }

    jobs.forEach { it.join() }
}

<|start_filename|>Basic/src/main/kotlin/delegates/Derived.kt<|end_filename|>
package delegates

/**
 * Created by tony on 2019-01-13.
 */
// 创建接口
interface Base {
    fun print()
}

// 实现此接口的被委托的类
class BaseImpl(val x: Int) : Base {
    override fun print() { print(x) }
}

// 通过关键字 by 完成委托，Derived 相当于代理类
class Derived(b: Base) : Base by b

fun main(args: Array<String>) {
    val base = BaseImpl(10)
    Derived(base).print() // 输出 10
}

<|start_filename|>Coroutines1/src/main/kotlin/ChildCoroutine2.kt<|end_filename|>
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking

/**
 * Created by tony on 2018/9/9.
 */
fun main(args: Array<String>) = runBlocking {

    val job = launch {

        val job1 = launch(coroutineContext)  {

            println("job1 is running")
            delay(1000)
            println("job1 is done")
        }

        val job2 = launch(coroutineContext) {

            println("job2 is running")
            delay(1500)
            println("job2 is done")
        }

        val job3 = launch(coroutineContext) {

            println("job3 is running")
            delay(2000)
            println("job3 is done")
        }

        job1.join()
        job2.join()
        job3.join()
    }

    job.join()

    println("all the jobs is complete")
}

<|start_filename|>Basic/src/main/kotlin/delegates/User.kt<|end_filename|>
package delegates

/**
 * Created by tony on 2018/8/7.
 */
class User(val id: Int) {

    var name: String by DatabaseDelegate("name", id) // 使用委托属性
    var password: String by DatabaseDelegate("password", id) // 使用委托属性
}

<|start_filename|>Basic/src/main/kotlin/delegates/TestDelegateProperties.kt<|end_filename|>
package delegates

/**
 * Created by tony on 2018/8/7.
 */
fun main(args: Array<String>) {

    val tony = User(1)

    println("tony.password="+tony.password)

    println("---------------------------")

    tony.password = "<PASSWORD>"

    println("---------------------------")

    println("tony.password="+tony.password)
}

<|start_filename|>Dagger2/app3/src/main/java/com/kotlin/tutorial/dagger2/app3/di/module/AddressModule1.kt<|end_filename|>
package com.kotlin.tutorial.dagger2.app3.di.module

import com.kotlin.tutorial.dagger2.app3.domain.Address
import com.kotlin.tutorial.dagger2.app3.domain.Street
import dagger.Module
import dagger.Provides

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.dagger2.app2.di.module.AddressModule.kt
 * @author: <NAME>
 * @date: 2018-08-10 15:58
 * @version V1.0 <描述当前版本功能>
 */
@Module(includes = arrayOf(StreetModule::class))
class AddressModule1 {

    @Provides
    fun provideAddress(street: Street) = Address(street)
}

<|start_filename|>Basic/src/main/kotlin/generic/Generic2.kt<|end_filename|>
package generic

import java.lang.reflect.ParameterizedType

/**
 * Created by tony on 2019-06-23.
 */
object Generic2 {

    @JvmStatic
    fun main(args: Array<String>) {

        val child = GenericChild()
        child.printType()
    }
}

open class Father<T>

class GenericChild : Father<String>() {

    fun printType() {

        val genType = javaClass.genericSuperclass
        println(genType)
        val params = (genType as ParameterizedType).actualTypeArguments[0]
        println(params)
    }
}

<|start_filename|>Basic/src/main/kotlin/classes/OutterAndNested.kt<|end_filename|>
package classes

/**
 * Created by tony on 2018/8/9.
 */
class Outter1 {

    val str:String = "this property is from outter1 class"

    class Nested {

        fun foo() = println("")
    }
}

fun main(args: Array<String>) {
    Outter1.Nested().foo()
}

<|start_filename|>Basic/src/main/kotlin/FunctionType.kt<|end_filename|>
/**
 * Created by tony on 2018/7/6.
 */
fun main(args: Array<String>) {

    val sum = {
        x: Int, y: Int -> x + y
    }

    println(sum(3, 5)) // 8
    println(sum(4, 6)) // 10
}

<|start_filename|>Dagger2/app3/src/main/java/com/kotlin/tutorial/dagger2/app3/di/component/AddressComponent2.kt<|end_filename|>
package com.kotlin.tutorial.dagger2.app3.di.component

import com.kotlin.tutorial.dagger2.app3.activity.Demo4ComponentDependenciesActivity
import dagger.Component

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.dagger2.app3.di.component.AddressComponent2
 * @author: <NAME>
 * @date: 2019-12-27 01:24
 * @version: V1.0 <描述当前版本功能>
 */
@Component(dependencies = arrayOf(StreetComponent2::class))
interface AddressComponent2 {

    fun inject(activity: Demo4ComponentDependenciesActivity)
}

<|start_filename|>Coroutines1/src/main/kotlin/Delay.kt<|end_filename|>
import kotlinx.coroutines.*

/**
 * Created by tony on 2018-11-30.
 */

fun main(args: Array<String>) = runBlocking{

    println("1: current thread is ${Thread.currentThread().name}")

    GlobalScope.launch {

        println("3: current thread is ${Thread.currentThread().name}")

        delay(1000L)

        println("4: current thread is ${Thread.currentThread().name}")
    }

    println("2: current thread is ${Thread.currentThread().name}")

    Thread.sleep(2000L)

    println("5: current thread is ${Thread.currentThread().name}")
}

<|start_filename|>Dagger2/app2/src/main/java/com/kotlin/tutorial/dagger2/app2/activity/Demo4LazyActivity.kt<|end_filename|>
package com.kotlin.tutorial.dagger2.app2.activity

import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.widget.Toast
import com.kotlin.tutorial.dagger2.app2.di.component.DaggerUserComponent1
import com.kotlin.tutorial.dagger2.app2.domain.User
import com.safframework.log.L
import dagger.Lazy
import javax.inject.Inject

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.dagger2.app2.activity.Demo4LazyActivity.kt
 * @author: <NAME>
 * @date: 2018-08-08 00:43
 * @version V1.0 <描述当前版本功能>
 */
class Demo4LazyActivity : AppCompatActivity() {

    @Inject
    lateinit var lazyUser:Lazy<User>

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        DaggerUserComponent1.create().inject(this)

        initData()

        L.i(lazyUser.get().toString())
        L.i(lazyUser.get().toString())
    }

    private fun initData() {

        Toast.makeText(this,lazyUser.get().testLazy(), Toast.LENGTH_LONG).show()
    }
}

<|start_filename|>AAC/app/src/main/java/com/kotlin/tutorial/aac/activity/Activity7.kt<|end_filename|>
package com.kotlin.tutorial.aac.activity

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.kotlin.tutorial.aac.R
import com.kotlin.tutorial.aac.fragment.Fragment1
import com.kotlin.tutorial.aac.fragment.Fragment2

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.aac.activity.Activity7
 * @author: <NAME>
 * @date: 2019-11-10 22:14
 * @version: V1.0 <描述当前版本功能>
 */
class Activity7: AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_7)

        supportFragmentManager.beginTransaction()
                .add(R.id.frame1, Fragment1())
                .add(R.id.frame2, Fragment2())
                .commit()
    }

}

<|start_filename|>Basic/src/main/kotlin/classes/Constructor3.kt<|end_filename|>
package classes

/**
 * Created by tony on 2018/8/10.
 */
class Constructor3(str:String) {

    init {

        println("$str")
    }

    constructor(str1: String, str2: String):this(str1) { // 调用主构造函数以及初始化块

        println("$str1 $str2")
    }

    fun foo() = println("this is foo function")

}

fun main(args: Array<String>) {
    val obj = Constructor3("hello","world")
    obj.foo()
}

<|start_filename|>Basic/src/main/java/dynamicproxy/DynamicProxyDemo.java<|end_filename|>
package dynamicproxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * Created by tony on 2018/6/5.
 */
public class DynamicProxyDemo {

    public static void main(String[] args) {

        BaseImpl baseImpl = new BaseImpl(10);                 // 创建委托对象
        ProxyHandler handler = new ProxyHandler(baseImpl);       // 创建调用处理器对象
        Base proxy = (Base) Proxy.newProxyInstance(BaseImpl.class.getClassLoader(),
                BaseImpl.class.getInterfaces(), handler);        // 动态生成代理对象
        proxy.print();                                           // 通过代理对象调用方法
    }
}

interface Base{
    void print();
}

/**
 * 委托类
 */
class BaseImpl implements Base {

    private int x;

    public BaseImpl(int x) {
        this.x = x;
    }

    public void print(){
        System.out.println(x);
    }
}

/**
 * 代理类的调用处理器
 */
class ProxyHandler implements InvocationHandler {

    private Base b;

    public ProxyHandler(Base base){
        this.b = base;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {

        return method.invoke(b, args);
    }
}


<|start_filename|>Basic/src/main/kotlin/Args2.kt<|end_filename|>
/**
 * Created by tony on 2018/7/26.
 */
fun main(args: Array<String>) {
    val array = arrayOf("java","kotlin","scala","groovy")
    val list = toList(*array)
    println(list)
}

<|start_filename|>Coroutines1/src/main/kotlin/CoroutineContext+Job.kt<|end_filename|>
import kotlinx.coroutines.*

/**
 * Created by tony on 2018/9/9.
 */
fun main(args: Array<String>) = runBlocking<Unit> {

    val job = Job() // 创建一个 job 对象来管理生命周期

    launch(coroutineContext+job)  {

        delay(500)
        println("job1 is done")
    }

    launch(coroutineContext+job) {

        delay(1000)
        println("job2 is done")
    }

    launch(Dispatchers.Default+job) {

        delay(1500)
        println("job3 is done")
    }

    launch(Dispatchers.Default+job) {

        delay(2000)
        println("job4 is done")
    }

    launch(Dispatchers.Default+job) {

        delay(2500)
        println("job5 is done")
    }

    delay(1800)
    println("Cancelling the job!")
    job.cancel() // 取消任务
}

<|start_filename|>Basic/src/main/java/TestSingleton1.java<|end_filename|>
import classes.Singleton1;

/**
 * Created by tony on 2019-02-28.
 */
public class TestSingleton1 {

    public static void main(String[] args) {

        Singleton1.INSTANCE.printlnHelloWorld();
    }
}


<|start_filename|>Basic/src/main/kotlin/LocalFunction.kt<|end_filename|>
/**
 * Created by tony on 2018/7/27.
 */
data class Person(var name:String,var password:String)

fun validate(person: Person):Boolean {

    /**
     * 验证单个字符串输入的方法
     */
    fun validateInput(input: String?) {

        if (input == null || input.isEmpty()) {
            throw IllegalArgumentException("must not be empty")
        }
    }

    validateInput(person.name)
    validateInput(person.password)
    return true
}

fun printPerson(person:Person) {
    val name = person.name
    val password = <PASSWORD>

    fun print() {
        println("name=$name,password=$password") // print() 函数直接访问了它外部函数 printPerson() 的局部变量。
    }

    print()
}

fun main(args: Array<String>) {
    val user1 = Person("tony","123456")
    println(validate(user1))
    printPerson(user1)

    val user2 = Person("tom","")
    println(validate(user2))
}

<|start_filename|>Basic/src/main/kotlin/classes/DataClass2.kt<|end_filename|>
package classes

import com.google.gson.Gson

/**
 * Created by tony on 2019-08-10.
 */
abstract class Message{
    abstract var action:String
}

data class PingMsg(override var action:String="ping"):Message()

data class PongMsg(override var action:String="pong"):Message()

data class AskMsg(override var action:String="ask",val body:Map<String,String>):Message()

fun main() {
    val gson = Gson()

    println(gson.toJson(PingMsg()))

    val map = mutableMapOf<String,String>()
    map.put("param1","tt")
    map.put("param2","qq")
    val msg = AskMsg(body = map)

    println(gson.toJson(msg))
}

<|start_filename|>AAC/app/src/main/java/com/kotlin/tutorial/aac/fragment/Fragment1.kt<|end_filename|>
package com.kotlin.tutorial.aac.fragment

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import com.kotlin.tutorial.aac.R
import com.kotlin.tutorial.aac.delegate.viewModelDelegate
import com.kotlin.tutorial.aac.viewmodel.SharedViewModel
import kotlinx.android.synthetic.main.fragment_1.*
import kotlinx.android.synthetic.main.fragment_1.view.*

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.aac.fragment.Fragment1
 * @author: <NAME>
 * @date: 2019-11-10 22:20
 * @version: V1.0 <描述当前版本功能>
 */
class Fragment1 : Fragment() {

    private val viewModel by viewModelDelegate(SharedViewModel::class)

    override fun onCreateView(
            inflater: LayoutInflater, container: ViewGroup?,
            savedInstanceState: Bundle?
    ): View? {
        val v = inflater.inflate(R.layout.fragment_1, container, false)

        v.button.setOnClickListener {
            viewModel.setText(edit.text.toString())
        }

        return v
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)

        viewModel.getText().observe(viewLifecycleOwner, Observer {
            text -> edit.setText(text)
        })
    }
}

<|start_filename|>Coroutines1/src/main/kotlin/CoroutineScope.kt<|end_filename|>
import kotlinx.coroutines.*

/**
 * Created by tony on 2018-11-30.
 */

fun main(args: Array<String>) {

    GlobalScope.launch {

        val result1 = withContext(Dispatchers.Default) {

            delay(2000)
            1
        }

        val  result2 = coroutineScope {

            delay(1000)
            2
        }

        val  result = result1 + result2
        println(result)
    }

    Thread.sleep(5000)
}

<|start_filename|>Retrofit/app2/src/main/java/com/kotlin/tutorial/retrofit/app2/model/SO2Model.kt<|end_filename|>
package com.kotlin.tutorial.retrofit.app2.model

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.retrofit.app2.model.SO2Model.java
 * @author: <NAME>
 * @date: 2018-06-20 01:44
 * @version V1.0 <描述当前版本功能>
 */
class SO2Model {

    var aqi: Int = 0
    var area: String? = null
    var so2: Int = 0
    var so2_24h: Int = 0
    var position_name: String? = null
    var primary_pollutant: String? = null
    var quality: String? = null
    var station_code: String? = null
    var time_point: String? = null
}

<|start_filename|>Dagger2/app2/src/main/java/com/kotlin/tutorial/dagger2/app2/di/module/UserModule4.kt<|end_filename|>
package com.kotlin.tutorial.dagger2.app2.di.module

import com.kotlin.tutorial.dagger2.app2.di.qualifier.Monica
import com.kotlin.tutorial.dagger2.app2.di.qualifier.Tony
import com.kotlin.tutorial.dagger2.app2.domain.User
import dagger.Module
import dagger.Provides

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.dagger2.app2.di.module.UserModule4.kt
 * @author: <NAME>
 * @date: 2018-08-13 17:45
 * @version V1.0 <描述当前版本功能>
 */
@Module
class UserModule4 {

    @Tony
    @Provides
    fun provideTony() = User("Tony")


    @Monica
    @Provides
    fun provideMonica() = User("Monica")
}

<|start_filename|>AAC/app/src/main/java/com/kotlin/tutorial/aac/db/User.kt<|end_filename|>
package com.kotlin.tutorial.aac.db

import androidx.room.Entity
import androidx.room.PrimaryKey

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.aac.db.User
 * @author: <NAME>
 * @date: 2019-11-09 16:32
 * @version: V1.0 <描述当前版本功能>
 */
@Entity(tableName = "users")
data class User(val name: String) {

    @PrimaryKey(autoGenerate = true)
    var id: Long = 0
}

<|start_filename|>Coroutines1/src/main/kotlin/NonCancellable.kt<|end_filename|>
import kotlinx.coroutines.*

/**
 * Created by tony on 2019-10-13.
 */

fun main() {

    val job =  GlobalScope.launch {

        withContext(NonCancellable) {

            delay(2000)
            println("this code can not be cancel")
        }
    }

    job.cancel()

    Thread.sleep(5000)
}

<|start_filename|>AAC/app/src/main/java/com/kotlin/tutorial/aac/activity/Activity6.kt<|end_filename|>
package com.kotlin.tutorial.aac.activity

import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.Observer
import com.kotlin.tutorial.aac.R
import com.kotlin.tutorial.aac.db.User
import com.kotlin.tutorial.aac.db.UserDatabase
import kotlinx.android.synthetic.main.activity_6.*

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.aac.activity.Activity6
 * @author: <NAME>
 * @date: 2019-11-09 16:29
 * @version: V1.0 <描述当前版本功能>
 */
class Activity6: AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_6)

        bindClickListeners()
    }

    private fun bindClickListeners() {

        val userDao = UserDatabase.getInstance(applicationContext).userDao()
        val usersLiveData = userDao.getAll()

        val observer = Observer<List<User>> { userList ->

            Log.i(TAG,"Count=${userList.count()}")
            userList.forEach {
                val msg = "$it (id=${it.id})"
                Log.i(TAG, msg)
            }
        }

        observe.setOnClickListener {
            toast("observe")
            usersLiveData.observe(this, observer)
        }

        unobserve.setOnClickListener {
            toast("unobserve")
            usersLiveData.removeObserver(observer)
        }

        add.setOnClickListener {
            toast("add")
            val userCount = userDao.getCount()
            userDao.insert(User("User ${userCount + 1}"))
        }

        delete.setOnClickListener {
            toast("delete")
            userDao.deleteAll()
        }
    }

    private fun toast(msg: String) {
        val sb = StringBuilder()
        sb.append("\n$msg")

        Toast.makeText(this,sb.toString(),Toast.LENGTH_LONG).show()
    }

    companion object {
        private val TAG = Activity6::class.java.simpleName
    }
}

<|start_filename|>Basic/src/main/java/Generic1.java<|end_filename|>
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

/**
 * Created by tony on 2019-06-17.
 */
public class Generic1 {

    static class InnerClass<T> {

    }

    public static void main(String[] args) {

        InnerClass<Integer> innerClass = new InnerClass<Integer>(){

        }; // 匿名内部类的声明在编译时进行，实例化在运行时进行

        Type typeClass = innerClass.getClass().getGenericSuperclass();
        System.out.println(typeClass);

        if (typeClass instanceof ParameterizedType) {
            Type actualType = ((ParameterizedType)typeClass).getActualTypeArguments()[0];

            System.out.println(actualType);
        }
    }
}


<|start_filename|>Dagger2/app2/src/main/java/com/kotlin/tutorial/dagger2/app2/di/component/UserComponent1.kt<|end_filename|>
package com.kotlin.tutorial.dagger2.app2.di.component

import com.kotlin.tutorial.dagger2.app2.activity.Demo4LazyActivity
import dagger.Component

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.dagger2.app2.di.component.UserComponent1.kt
 * @author: <NAME>
 * @date: 2018-08-08 01:00
 * @version V1.0 <描述当前版本功能>
 */
@Component
interface UserComponent1 {

    fun inject(activity: Demo4LazyActivity)
}

<|start_filename|>Dagger2/app1/src/main/java/com/kotlin/tutorial/dagger2/di/module/DemoModule.kt<|end_filename|>
package com.kotlin.tutorial.dagger2.di.module

import com.kotlin.tutorial.dagger2.DemoService
import com.kotlin.tutorial.dagger2.IService
import dagger.Module
import dagger.Provides

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.dagger2.di.module.DemoModule.kt
 * @author: <NAME>
 * @date: 2018-08-03 11:42
 * @version V1.0 <描述当前版本功能>
 */
@Module
class DemoModule {

    @Provides
    fun provideDemoService():IService {

        return DemoService()
    }
}


<|start_filename|>AAC/app/src/main/java/com/kotlin/tutorial/aac/livedata/MyLiveData.kt<|end_filename|>
package com.kotlin.tutorial.aac.livedata
import android.util.Log
import androidx.lifecycle.LiveData
import java.util.concurrent.atomic.AtomicInteger


/**
 *
 * @FileName:
 *          com.kotlin.tutorial.aac.livedata.MyLiveData
 * @author: <NAME>
 * @date: 2019-11-08 23:06
 * @version: V1.0 <描述当前版本功能>
 */
class MyLiveData : LiveData<AtomicInteger>() {

    var atomicInteger:AtomicInteger = AtomicInteger(0)

    override fun onActive() {
        super.onActive()
        Log.d(TAG, "onActive")
    }

    override fun onInactive() {
        super.onInactive()
        Log.d(TAG, "onInactive")
    }

    override fun setValue(value: AtomicInteger?) {
        super.setValue(value)
        Log.d(TAG, "$value")
    }

    fun updateValue(value: AtomicInteger?) {
        value?.let {
            it.incrementAndGet()
            setValue(value)
        }
    }

    companion object {
        private val TAG = MyLiveData::class.java.simpleName
    }
}

<|start_filename|>Retrofit/app1/src/main/java/com/kotlin/tutorial/retrofit/app1/api/APIService.kt<|end_filename|>
package com.kotlin.tutorial.retrofit.app1.api

import com.kotlin.tutorial.retrofit.app1.model.Event
import io.reactivex.Maybe
import retrofit2.http.GET
import retrofit2.http.Path

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.retrofit.app1.api.APIService.java
 * @author: <NAME>
 * @date: 2018-06-18 19:28
 * @version V1.0 <描述当前版本功能>
 */
interface APIService {

    companion object {

        const val API_BASE_SERVER_URL = "https://api.github.com/"
    }

    @GET("users/{username}/events/public")
    fun publicEvent(@Path("username")userName:String): Maybe<List<Event>>
}

<|start_filename|>AAC/app/src/main/java/com/kotlin/tutorial/aac/delegate/ViewModelDelegate.kt<|end_filename|>
package com.kotlin.tutorial.aac.delegate

import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProviders
import kotlin.reflect.KClass
import kotlin.reflect.KProperty

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.aac.delegate.ViewModelDelegate
 * @author: <NAME>
 * @date: 2019-11-09 12:43
 * @version: V1.0 <描述当前版本功能>
 */
class ViewModelDelegate<out T : ViewModel>(private val clazz: KClass<T>, private val fromActivity: Boolean) {

    private var viewModel: T? = null

    operator fun getValue(thisRef: AppCompatActivity, property: KProperty<*>) = buildViewModel(activity = thisRef)

    operator fun getValue(thisRef: Fragment, property: KProperty<*>) = if (fromActivity)
        buildViewModel(activity = thisRef.activity as? AppCompatActivity
                ?: throw IllegalStateException("Activity must be as BaseActivity"))
    else buildViewModel(fragment = thisRef)

    private fun buildViewModel(activity: AppCompatActivity? = null, fragment: Fragment? = null): T {
        if (viewModel != null) return viewModel!!

        activity?.let {
            viewModel = ViewModelProviders.of(it).get(clazz.java)
        } ?: fragment?.let {
            viewModel = ViewModelProviders.of(it).get(clazz.java)
        } ?: throw IllegalStateException("Activity or Fragment is null! ")

        return viewModel!!
    }
}

fun <T : ViewModel> AppCompatActivity.viewModelDelegate(clazz: KClass<T>) = ViewModelDelegate(clazz, true)

fun <T : ViewModel> Fragment.viewModelDelegate(clazz: KClass<T>, fromActivity: Boolean = true) = ViewModelDelegate(clazz, fromActivity)

<|start_filename|>Basic/src/main/kotlin/delegates/DatabaseDelegate.kt<|end_filename|>
package delegates

import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty

/**
 * Created by tony on 2018/8/7.
 */
class DatabaseDelegate<in R, T>(private val field: String, private val id: Int) : ReadWriteProperty<R, T> {

    override fun getValue(thisRef: R, property: KProperty<*>): T = queryForValue(field, id) as T

    override fun setValue(thisRef: R, property: KProperty<*>, value: T) {
        update(field, id, value)
    }
}

class NoRecordFoundException(id: Int) : Exception("No record found for id $id")

val data = arrayOf<MutableMap<String, Any?>>(
        mutableMapOf(
                "id" to 1,
                "name" to "Tony",
                "password" to "<PASSWORD>"
        ),
        mutableMapOf(
                "id" to 2,
                "name" to "Monica",
                "password" to "<PASSWORD>"
        )
)

fun queryForValue(field: String, id: Int): Any {

    val value = data.firstOrNull { it["id"] == id }?.get(field) ?: throw NoRecordFoundException(id)
    println("loaded value $value for field \"$field\" of record $id")
    return value
}


fun update(field: String, id: Int, value: Any?) {

    println("updating field \"$field\" of record $id to value $value")

    data.firstOrNull { it["id"] == id }
            ?.put(field, value)
            ?: throw NoRecordFoundException(id)
}



<|start_filename|>Basic/src/main/kotlin/classes/CompanionObject.kt<|end_filename|>
package classes

/**
 * Created by tony on 2018/8/21.
 */
class Student {

    companion object {

        private var username = "Tony"
        private var marks = "A"

        fun printMarks() = "The ${this.username}'s mark is ${this.marks}"

        fun changeMarks(marks:String){
            this.marks = marks
        }
    }
}

fun main(args: Array<String>) {
    Student.changeMarks("B")
    println(Student.printMarks())

    Student.changeMarks("C")
    println(Student.printMarks())
}

<|start_filename|>Basic/src/main/kotlin/Args3.kt<|end_filename|>
/**
 * Created by tony on 2018/7/26.
 */
fun <T> toList2(vararg items: T, str: String): List<String> {
    val result = ArrayList<String>()
    for (item in items)
        result.add(item.toString())

    result.add(str)
    return result
}

fun main(args: Array<String>) {
    val array = arrayOf("java", "kotlin", "scala", "groovy")
    val list = toList2(*array, str = "tony")
    println(list)
}

<|start_filename|>Basic/src/main/kotlin/generic/Generic1.kt<|end_filename|>
package generic

import java.lang.reflect.ParameterizedType

/**
 * Created by tony on 2019-06-17.
 */

object Generic1 {

    open class InnerClass<T>

    @JvmStatic
    fun main(args: Array<String>) {

        val innerClass = object : InnerClass<Int>() {

        } // 匿名内部类的声明在编译时进行，实例化在运行时进行

        val typeClass = innerClass.javaClass.genericSuperclass
        println(typeClass)

        if (typeClass is ParameterizedType) {

            val actualType = typeClass.actualTypeArguments[0]
            println(actualType)
        }
    }
}

<|start_filename|>Dagger2/app2/src/main/java/com/kotlin/tutorial/dagger2/app2/di/component/UserComponent2.kt<|end_filename|>
package com.kotlin.tutorial.dagger2.app2.di.component

import com.kotlin.tutorial.dagger2.app2.activity.Demo4ProviderInjectActivity
import dagger.Component

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.dagger2.app2.di.component.UserComponent2.kt
 * @author: <NAME>
 * @date: 2018-08-10 17:07
 * @version V1.0 <描述当前版本功能>
 */
@Component
interface UserComponent2 {

    fun inject(activity: Demo4ProviderInjectActivity)
}

<|start_filename|>Coroutines1/src/main/kotlin/Async3.kt<|end_filename|>
import kotlinx.coroutines.*

/**
 * Created by tony on 2018/8/30.
 */

fun main(args: Array<String>) {

    GlobalScope.launch {

        val result1 = async {

            delay(2000)
            1
        }

        val  result2 = async(start= CoroutineStart.LAZY) {

            delay(1000)
            2
        }

        val  result = result1.await() + result2.await()
        println(result)
    }

    Thread.sleep(5000)
}

<|start_filename|>Basic/src/main/kotlin/Sequence.kt<|end_filename|>
/**
 * Created by tony on 2018-12-02.
 */
fun main() {

    listOf(5, 12, 8, 33)
            .asSequence()
            .filter { it > 10 }
            .forEach(::println)

    println("-------------------")

    sequenceOf(5, 12, 8, 33)
            .filter { it>10 }
            .forEach (::println)
}

<|start_filename|>Benchmark/src/main/kotlin/benchmark/InlineBenchmark.kt<|end_filename|>
package benchmark

import org.openjdk.jmh.annotations.*
import org.openjdk.jmh.runner.Runner
import org.openjdk.jmh.runner.options.OptionsBuilder
import java.util.concurrent.TimeUnit

/**
 * Created by tony on 2018-12-10.
 */
@BenchmarkMode(Mode.Throughput) // 基准测试的模式，采用整体吞吐量的模式
@Warmup(iterations = 3) // 预热次数
@Measurement(iterations = 10, time = 5, timeUnit = TimeUnit.SECONDS) // 测试参数，iterations = 10 表示进行10轮测试
@Threads(8) // 每个进程中的测试线程数
@Fork(2)  // 进行 fork 的次数，表示 JMH 会 fork 出两个进程来进行测试
@OutputTimeUnit(TimeUnit.MILLISECONDS) // 基准测试结果的时间类型
open class InlineBenchmark {

    fun nonInlined(block: () -> Unit) { // 不用内联的函数
        block()
    }

    inline fun inlined(block: () -> Unit) { // 使用内联的函数
        block()
    }

    @Benchmark
    fun testNonInlined() {
        nonInlined {
            println("")
        }
    }

    @Benchmark
    fun testInlined() {
        inlined {
            println("")
        }
    }

}

fun main() {
    val options = OptionsBuilder()
            .include(InlineBenchmark::class.java.simpleName)
            .output("benchmark_inline.log")
            .build()
    Runner(options).run()
}

<|start_filename|>DSL/src/main/kotlin/UserWrapper.kt<|end_filename|>
/**
 * Created by tony on 2018/9/20.
 */
class UserWrapper{

    private val address = Address()

    var name:String?=null
    var password: String?=null

    fun address(init: Address.() -> Unit):Address { // 类似于 apply 函数，返回 address 对象本身

        address.init()
        return address
    }

    internal fun getAddress() = address
}

fun user(init: UserWrapper.() -> Unit):User {

    val wrapper = UserWrapper()
    wrapper.init()

    val user = User()

    user.name = wrapper.name
    user.password = <PASSWORD>
    user.addresses = wrapper.getAddress()

    return user
}



<|start_filename|>Basic/src/main/java/proxy/ProxyDemo.java<|end_filename|>
package proxy;

/**
 * Created by tony on 2018/6/5.
 */
public class ProxyDemo {

    public static void main(String args[]){

        BaseImpl impl = new BaseImpl(10);
        Proxy p = new Proxy(impl);
        p.print();
    }
}

interface Base{

    void print();
}

/**
 * 委托类
 */
class BaseImpl implements Base {

    private int x;

    public BaseImpl(int x) {
        this.x = x;
    }

    public void print(){
        System.out.println(x);
    }
}

class Proxy implements Base {

    private Base b;

    public Proxy(Base base){
        this.b = base;
    }
    public void print(){

        b.print();
    }
}

<|start_filename|>Basic/src/main/java/Color.java<|end_filename|>
/**
 * Created by tony on 2018/8/20.
 */
public enum Color {

    RED("红色", 1), GREEN("黄色", 2), BLUE("蓝色", 3);

    String colorName;
    int value;

    Color(String colorName, int value){
        this.colorName = colorName;
        this.value = value;
    }
}


<|start_filename|>Basic/src/main/kotlin/HigherOrderFunctions2.kt<|end_filename|>
/**
 * Created by tony on 2018/6/14.
 */
fun sum(a: Int, b: Int, term: (Int) -> Int): Int {
    var sum = 0
    for (i in a..b) {
        sum += term(i)
    }
    return sum
}

fun main(args: Array<String>) {
    val identity = { x: Int -> x }
    val square = { x: Int -> x * x }
    val cube = { x: Int -> x * x * x }

    println(sum(1, 10, identity)) //  55
    println(sum(1, 10, square))   //  385
    println(sum(1, 10, cube))     //  3025
}

<|start_filename|>Dagger2/app1/src/main/java/com/kotlin/tutorial/dagger2/di/component/UserComponent1.kt<|end_filename|>
package com.kotlin.tutorial.dagger2.di.component

import com.kotlin.tutorial.dagger2.activity.Demo4InjectActivity
import dagger.Component

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.dagger2.di.component.UserComponent1.kt
 * @author: <NAME>
 * @date: 2018-08-02 00:21
 * @version V1.0 <描述当前版本功能>
 */
@Component
interface UserComponent1 {

    fun inject(activity: Demo4InjectActivity)
}

<|start_filename|>Dagger2/app1/src/main/java/com/kotlin/tutorial/dagger2/DemoService.kt<|end_filename|>
package com.kotlin.tutorial.dagger2

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.dagger2.DemoService.kt
 * @author: <NAME>
 * @date: 2018-08-03 11:38
 * @version V1.0 <描述当前版本功能>
 */
class DemoService:IService{

    override fun foo() = "this is from DemoService"
}

<|start_filename|>Basic/src/main/kotlin/classes/OutterAndInner.kt<|end_filename|>
package classes

/**
 * Created by tony on 2018/8/9.
 */
class Outter2 {

    val str:String = "this property is from outter2 class"

    inner class Inner {

        fun foo() = println("$str")
    }
}

fun main(args: Array<String>) {
    Outter2().Inner().foo()
}

<|start_filename|>Basic/src/main/kotlin/classes/Constructor2.kt<|end_filename|>
package classes

/**
 * Created by tony on 2018/8/16.
 */
class Constructor2 constructor() {

    init {

        println("test")
    }

    fun foo() = println("this is foo function")

}

fun main(args: Array<String>) {
    val obj = Constructor2()
    obj.foo()
}

<|start_filename|>Dagger2/app3/src/main/java/com/kotlin/tutorial/dagger2/app3/domain/Street.kt<|end_filename|>
package com.kotlin.tutorial.dagger2.app3.domain

import javax.inject.Inject

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.dagger2.app3.domain.Street.kt
 * @author: <NAME>
 * @date: 2018-08-10 16:14
 * @version V1.0 <描述当前版本功能>
 */
class Street @Inject constructor(streetName:String) {

    private val streetName: String

    init {
        this.streetName = streetName
    }

    override fun toString(): String {

        return streetName
    }
}

<|start_filename|>Coroutines1/src/main/kotlin/ChildCoroutine1.kt<|end_filename|>
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch

/**
 * Created by tony on 2018/9/9.
 */
fun main(args: Array<String>) {

    // 创建一个协程，并在内部再创建两个协程
    val job = GlobalScope.launch {

        // 第一个使用不同的上下文
        val job1 = GlobalScope.launch {

            println("job1: I have my own context and execute independently!")
            delay(1000)
            println("job1: I am not affected by cancellation of the job")
        }

        // 第二个继承父级上下文
        val job2 = launch(coroutineContext) {

            println("job2: I am a child of the job coroutine")
            delay(1000)
            println("job2: I will not execute this line if my parent job is cancelled")
        }

        job1.join()
        job2.join()
    }

    Thread.sleep(500)

    job.cancel() // 取消job

    Thread.sleep(2000)
}

<|start_filename|>Dagger2/app3/src/main/java/com/kotlin/tutorial/dagger2/app3/di/component/AddressComponent1.kt<|end_filename|>
package com.kotlin.tutorial.dagger2.app3.di.component

import com.kotlin.tutorial.dagger2.app3.activity.Demo4ModuleIncludeActivity
import com.kotlin.tutorial.dagger2.app3.di.module.AddressModule1
import dagger.Component

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.dagger2.app3.di.component.AddressComponent1.kt
 * @author: <NAME>
 * @date: 2018-08-10 16:20
 * @version V1.0 <描述当前版本功能>
 */
@Component(modules = arrayOf(AddressModule1::class))
interface AddressComponent1 {

    fun inject(activity: Demo4ModuleIncludeActivity)
}

<|start_filename|>Basic/src/main/kotlin/classes/Singleton2.kt<|end_filename|>
package classes

/**
 * 线程安全的懒汉模式
 * Created by tony on 2019-01-04.
 */
class Singleton2 private constructor() {

    companion object {
        val instance: Singleton2 by lazy { Singleton2() }
    }

    fun printlnHelloWorld() = println("hello world")
}

fun main(args: Array<String>) {

    val obj1 = Singleton2.instance
    val obj2 = Singleton2.instance
    println (obj1 === obj2)

    Singleton2.instance.printlnHelloWorld()
}

<|start_filename|>Dagger2/app1/src/main/java/com/kotlin/tutorial/dagger2/activity/Demo4ComponentBuilderActivity.kt<|end_filename|>
package com.kotlin.tutorial.dagger2.activity

import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.widget.Toast
import com.kotlin.tutorial.dagger2.di.component.DaggerUserComponent4
import com.kotlin.tutorial.dagger2.domain.User
import javax.inject.Inject

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.dagger2.activity.Demo4ComponentBuilderActivity.kt
 * @author: <NAME>
 * @date: 2018-08-02 16:34
 * @version V1.0 <描述当前版本功能>
 */
class Demo4ComponentBuilderActivity: AppCompatActivity() {

    @Inject
    lateinit var user: User

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        DaggerUserComponent4.builder().param("this is a parameter").build().inject(this)

        Toast.makeText(this,user.testComponentBuilder(), Toast.LENGTH_LONG).show()
    }
}

<|start_filename|>Basic/src/main/kotlin/Extension2.kt<|end_filename|>
/**
 * Created by tony on 2018/5/30.
 */
class Extension2 {
    fun test() = println("this is from test()")
}

fun Extension2.test() = println("this is from extension function")

fun main(args: Array<String>) {
    var extension2 = Extension2()

    extension2.test()
}

<|start_filename|>DSL/src/test/kotlin/Assertion.kt<|end_filename|>
import org.junit.Assert

/**
 * Created by tony on 2018/9/25.
 */
class Assertion<T>(private val target: T) {

    infix fun isEqualTo(other: T) {
        Assert.assertEquals(other, target)
    }

    infix fun isDifferentFrom(other: T) {
        Assert.assertNotEquals(other, target)
    }
}

<|start_filename|>Coroutines1/src/main/kotlin/Async2.kt<|end_filename|>
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.async
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch

/**
 * Created by tony on 2018/8/27.
 */

fun main(args: Array<String>) {

    GlobalScope.launch {

        val result1 = async {

            delay(2000)
            1
        }

        val  result2 = async {

            delay(1000)
            2
        }

        val  result = result1.await() + result2.await()
        println(result)
    }

    Thread.sleep(5000)
}

<|start_filename|>Dagger2/app2/src/main/java/com/kotlin/tutorial/dagger2/app2/activity/MainActivity.kt<|end_filename|>
package com.kotlin.tutorial.dagger2.app2.activity

import android.content.Intent
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import com.kotlin.tutorial.dagger2.app2.R
import kotlinx.android.synthetic.main.activity_main.*

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.dagger2.app2.activity.MainActivity.kt
 * @author: <NAME>
 * @date: 2018-08-07 21:19
 * @version V1.0 <描述当前版本功能>
 */
class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        text1.setOnClickListener {

            val intent = Intent(this,Demo4RecursiveInjectActivity::class.java)
            startActivity(intent)
        }

        text2.setOnClickListener {

            val intent = Intent(this, Demo4LazyActivity::class.java)
            startActivity(intent)
        }

        text3.setOnClickListener {

            val intent = Intent(this, Demo4ProviderInjectActivity::class.java)
            startActivity(intent)
        }

        text4.setOnClickListener {

            val intent = Intent(this, Demo4QualifierActivity::class.java)
            startActivity(intent)
        }

        text5.setOnClickListener {

            val intent = Intent(this, Demo4CustomerQualifierActivity::class.java)
            startActivity(intent)
        }

    }
}

<|start_filename|>Retrofit/app1/src/main/java/com/kotlin/tutorial/retrofit/app1/http/RetrofitManager.kt<|end_filename|>
package com.kotlin.tutorial.retrofit.app1.http

import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import java.util.concurrent.TimeUnit
import com.safframework.http.interceptor.LoggingInterceptor
import com.kotlin.tutorial.retrofit.app1.api.APIService
import retrofit2.converter.gson.GsonConverterFactory

import kotlin.jvm.java

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.retrofit.app1.http.RetrofitManager.java
 * @author: <NAME>
 * @date: 2018-06-18 19:19
 * @version V1.0 <描述当前版本功能>
 */
class RetrofitManager private constructor() {

    private val apiService: APIService

    private val okhttpClient: OkHttpClient

    init {

        val builder = OkHttpClient.Builder()

        //设置超时
        builder.writeTimeout((5 * 1000).toLong(), TimeUnit.MILLISECONDS)
        builder.readTimeout((5 * 1000).toLong(), TimeUnit.MILLISECONDS)
        builder.connectTimeout((5 * 1000).toLong(), TimeUnit.MILLISECONDS)

        val loggingInterceptor = LoggingInterceptor.Builder()
                .loggable(true) // TODO: 发布到生产环境需要改成false
                .request()
                .requestTag("Request")
                .response()
                .responseTag("Response")
                .build()

        //设置拦截器
        builder.addInterceptor(loggingInterceptor)

        okhttpClient = builder.build()

        mRetrofit = Retrofit.Builder()
                .baseUrl(APIService.API_BASE_SERVER_URL)
                .addConverterFactory(GsonConverterFactory.create()) //设置 gson 转换器
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) // 设置 RxJava2 适配器
                .client(okhttpClient)
                .build()

        apiService = mRetrofit.create(APIService::class.java)
    }

    fun retrofit(): Retrofit = mRetrofit

    fun apiService(): APIService = apiService

    fun okhttpClient(): OkHttpClient = okhttpClient

    private object Holder {
        val MANAGER = RetrofitManager()
    }

    companion object {

        private lateinit var mRetrofit: Retrofit

        @JvmStatic
        fun get(): RetrofitManager {

            return Holder.MANAGER
        }
    }
}

<|start_filename|>Basic/src/main/kotlin/Lambda.kt<|end_filename|>
/**
 * Created by tony on 2018/7/11.
 */
fun main(args: Array<String>) {
    listOf(5, 12, 8, 33)
            .filter { it > 10 }
            .forEach { println(it) }
}

<|start_filename|>Basic/src/main/kotlin/HigherOrderFunctions1.kt<|end_filename|>
/**
 * Created by tony on 2018/7/3.
 */
fun main(args: Array<String>) {
    val sum = {
        x: Int, y: Int -> x + y
    }

    println(sum(3, 5))
    println(sum(4,6))

    println(sum.invoke(4,6))
}

<|start_filename|>Retrofit/app2/src/main/java/com/kotlin/tutorial/retrofit/app2/config/Constant.kt<|end_filename|>
package com.kotlin.tutorial.retrofit.app2.config

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.retrofit.app2.config.Constant.java
 * @author: <NAME>
 * @date: 2018-06-20 14:27
 * @version V1.0 <描述当前版本功能>
 */
object Constant {

    val CITY_ID = "苏州"
    val TOKEN = "<KEY>"
}

<|start_filename|>Coroutines1/src/main/kotlin/Channel3.kt<|end_filename|>

import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.channels.ReceiveChannel
import kotlinx.coroutines.channels.consumeEach
import kotlinx.coroutines.channels.produce
import kotlinx.coroutines.runBlocking

/**
 * Created by tony on 2018/9/10.
 */
fun produce1() = GlobalScope.produce(Dispatchers.Default) {

    repeat(5) { // 发送从0到4
        i-> send(i)
    }
}

fun produce2(numbers: ReceiveChannel<Int>) = GlobalScope.produce(Dispatchers.Default) {

    for (x in numbers) {
        send((x * x))
    }
}

fun produce3(numbers: ReceiveChannel<Int>) = GlobalScope.produce(Dispatchers.Default) {

    for (x in numbers) {
        send(x+1)
    }
}

fun main(args: Array<String>) = runBlocking<Unit> {

    val numbers = produce1()
    val squares = produce2(numbers)
    val adds = produce3(squares)

    adds.consumeEach(::println)

    println("Receive Done!")

    // 消费完消息之后，关闭所有的produce
    adds.cancel()
    squares.cancel()
    numbers.cancel()
}

<|start_filename|>Coroutines2/app/src/main/java/com/kotlin/tutorial/coroutines/activity/MainActivity.kt<|end_filename|>
package com.kotlin.tutorial.coroutines.activity

import android.content.Intent
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.widget.Toast
import com.kotlin.tutorial.coroutines.R
import com.kotlin.tutorial.coroutines.ext.onClick
import kotlinx.android.synthetic.main.activity_main.*

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.coroutines.activity.MainActivity.kt
 * @author: <NAME>
 * @date: 2018-09-02 14:13
 * @version: V1.0 <描述当前版本功能>
 */
class MainActivity : AppCompatActivity() {

    private var count = 0

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        text1.onClick {

            Toast.makeText(this@MainActivity, "${count++}", Toast.LENGTH_SHORT).show()
        }

        text2.setOnClickListener{

            val intent = Intent(this,Demo4RetrofitActivity::class.java)
            startActivity(intent)
        }
    }
}

<|start_filename|>Dagger2/app3/src/main/java/com/kotlin/tutorial/dagger2/app3/activity/Demo4ComponentDependenciesActivity.kt<|end_filename|>
package com.kotlin.tutorial.dagger2.app3.activity

import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.widget.Toast
import com.kotlin.tutorial.dagger2.app3.di.component.DaggerAddressComponent2
import com.kotlin.tutorial.dagger2.app3.di.component.DaggerStreetComponent2
import com.kotlin.tutorial.dagger2.app3.domain.Address
import javax.inject.Inject

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.dagger2.app3.activity.Demo4ModuleDependenciesActivity
 * @author: <NAME>
 * @date: 2019-12-27 01:23
 * @version: V1.0 <描述当前版本功能>
 */
class Demo4ComponentDependenciesActivity: AppCompatActivity() {

    @Inject
    lateinit var address: Address

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val streetComponent2 = DaggerStreetComponent2.builder().build()
        DaggerAddressComponent2.builder().streetComponent2(streetComponent2).build().inject(this)

        Toast.makeText(this,address.toString(), Toast.LENGTH_LONG).show()
    }

}

<|start_filename|>Basic/src/main/kotlin/classes/Singleton1.kt<|end_filename|>
package classes

/**
 * 饿汉模式
 * Created by tony on 2018/8/21.
 */
object Singleton1 {

    fun printlnHelloWorld() = println("hello world")
}

fun main(args: Array<String>) {
    Singleton1.printlnHelloWorld()
}

<|start_filename|>Coroutines2/app/src/main/java/com/kotlin/tutorial/coroutines/config/Constant.kt<|end_filename|>
package com.kotlin.tutorial.coroutines.config

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.coroutines.config.Constant.java
 * @author: <NAME>
 * @date: 2018-06-20 14:27
 * @version V1.0 <描述当前版本功能>
 */
object Constant {

    val CITY_ID = "苏州"
    val TOKEN = "<KEY>"
}

<|start_filename|>Basic/src/main/kotlin/classes/Constructor4.kt<|end_filename|>
package classes

/**
 * Created by tony on 2018-12-03.
 */
class Constructor4(str:String) {

    init { // 初始化块

        println("$str"+1)
    }

    init { // 初始化块

        println("$str"+2)
    }

    constructor(str1: String, str2: String):this(str1) { // 调用主构造函数以及按照顺序调用多个初始化块

        println("$str1 $str2")
    }

    init { // 初始化块

        println("$str"+3)
    }

    fun foo() = println("this is foo function")

}

fun main(args: Array<String>) {
    val obj = Constructor4("hello","world")
    obj.foo()
}

<|start_filename|>Coroutines1/src/main/kotlin/Select.kt<|end_filename|>
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.cancelChildren
import kotlinx.coroutines.channels.ReceiveChannel
import kotlinx.coroutines.channels.produce
import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.selects.select
import kotlin.coroutines.CoroutineContext

/**
 * Created by tony on 2018/9/10.
 */
fun produce1(context: CoroutineContext) = GlobalScope.produce<String>(context) {

    while (true) {
        delay(400)
        send("Tony")
    }
}

fun produce2(context: CoroutineContext) = GlobalScope.produce<String>(context) {

    while (true) {
        delay(600)
        send("Monica")
    }
}

suspend fun selectProduces(channel1: ReceiveChannel<String>, channel2: ReceiveChannel<String>) {

    select<Unit> {

        channel1.onReceive {
            println("This is $it")
        }

        channel2.onReceive {
            println("This is $it")
        }
    }
}

fun main(args: Array<String>) = runBlocking {

    val tony = produce1(coroutineContext)
    val monica = produce2(coroutineContext)

    repeat(10) {
        selectProduces(tony, monica)
    }

    coroutineContext.cancelChildren() // 关闭子协程
}

<|start_filename|>Basic/src/main/kotlin/Extension1.kt<|end_filename|>
import java.util.regex.Pattern

/**
 * Created by tony on 2018/5/30.
 */
fun String.checkEmail(): Boolean {
    val emailPattern = "[a-zA-Z0-9][a-zA-Z0-9._-]{2,16}[a-zA-Z0-9]@[a-zA-Z0-9]+.[a-zA-Z0-9]+"
    return Pattern.matches(emailPattern, this)
}

fun main(args: Array<String>) {
    println("<EMAIL>".checkEmail())
}



<|start_filename|>AAC/app/src/main/java/com/kotlin/tutorial/aac/activity/Activity3.kt<|end_filename|>
package com.kotlin.tutorial.aac.activity

import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.Observer
import com.kotlin.tutorial.aac.R
import com.kotlin.tutorial.aac.livedata.MyLiveData
import kotlinx.android.synthetic.main.activity_3.*
import java.util.concurrent.atomic.AtomicInteger


/**
 *
 * @FileName:
 *          com.kotlin.tutorial.aac.activity.Activity3
 * @author: <NAME>
 * @date: 2019-03-01 14:00
 * @version: V1.0 <描述当前版本功能>
 */
class Activity3: AppCompatActivity() {

    var data = MyLiveData()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_3)

        text.setOnClickListener {

            data.updateValue(data.atomicInteger)
        }

        data.observe(this, Observer<AtomicInteger> { t ->
            text.text = "点击次数：$t" //更新控件中的数据
            Log.d(TAG, "数据改变...$t")
        })

    }

    companion object {
        private val TAG = Activity3::class.java.simpleName
    }
}

<|start_filename|>DSL/src/main/kotlin/Invoke.kt<|end_filename|>
/**
 * Created by tony on 2018/9/24.
 */
operator fun String.invoke(fn: String.() -> Unit) {
    fn(this)
}

fun main(args: Array<String>) {

    "hello dsl" { // 此处省略了.invoke

        println(this)
    }
}

<|start_filename|>Dagger2/app1/src/main/java/com/kotlin/tutorial/dagger2/di/component/UserComponent4.kt<|end_filename|>
package com.kotlin.tutorial.dagger2.di.component

import com.kotlin.tutorial.dagger2.activity.Demo4ComponentBuilderActivity
import com.kotlin.tutorial.dagger2.di.module.UserModule4
import dagger.BindsInstance
import dagger.Component


/**
 *
 * @FileName:
 *          com.kotlin.tutorial.dagger2.di.component.UserComponent311.kt
 * @author: <NAME>
 * @date: 2018-08-02 16:36
 * @version V1.0 <描述当前版本功能>
 */
@Component(modules = arrayOf(UserModule4::class))
interface UserComponent4 {

    fun inject(activity: Demo4ComponentBuilderActivity)

    @Component.Builder
    interface Builder {

        fun build():UserComponent4

        @BindsInstance
        fun param(param: String): Builder
    }
}

<|start_filename|>Coroutines1/src/main/kotlin/Channel2.kt<|end_filename|>
import kotlinx.coroutines.*
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.channels.ClosedReceiveChannelException

/**
 * Created by tony on 2018/9/9.
 */
fun main(args: Array<String>) = runBlocking {

    val channel = Channel<Int>()  //定义一个通道
    launch(Dispatchers.Default) {

        repeat(5) {

            i ->
            delay(200)
            channel.send((i+1) * (i+1))

            if (i==2) { // 发送3次后关闭

                channel.close()
            }
        }
    }

    launch(Dispatchers.Default) {

        repeat(5) {

            try {
                println(channel.receive())
            }catch (e: ClosedReceiveChannelException){
                println("There is a ClosedReceiveChannelException.") // channel 异常则打印
            }
        }
    }

    delay(2000)

    println("Receive Done!")
}

<|start_filename|>Basic/src/main/kotlin/generic/Animal.kt<|end_filename|>
package generic

/**
 * Created by tony on 2019-06-24.
 */
open class Animal

class Dog : Animal()

<|start_filename|>Retrofit/app2/src/main/java/com/kotlin/tutorial/retrofit/app2/api/APIService.kt<|end_filename|>
package com.kotlin.tutorial.retrofit.app2.api

import com.kotlin.tutorial.retrofit.app2.model.PM25Model
import com.kotlin.tutorial.retrofit.app2.model.SO2Model
import io.reactivex.Maybe
import retrofit2.http.GET
import retrofit2.http.Query

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.retrofit.app1.ap2.APIService.java
 * @author: <NAME>
 * @date: 2018-06-18 19:28
 * @version V1.0 <描述当前版本功能>
 */
interface APIService {
    
    companion object {

        val API_BASE_SERVER_URL = "http://www.pm25.in/"
    }

    @GET("api/querys/pm2_5.json")
    fun pm25(@Query("city") cityId: String, @Query("token") token: String): Maybe<List<PM25Model>>

    @GET("api/querys/so2.json")
    fun so2(@Query("city") cityId: String, @Query("token") token: String): Maybe<List<SO2Model>>

}

<|start_filename|>Basic/src/main/java/User.java<|end_filename|>

/**
 * Created by tony on 2018/7/10.
 */
public class User {

    private String name;

    public User(String name) {

        this.name = name;
    }

    public String getName() {
        return name;
    }

    @Override
    public String toString() {
        return name;
    }
}


<|start_filename|>Coroutines1/src/main/kotlin/Launch.kt<|end_filename|>
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
/**
 * Created by tony on 2018/8/26.
 */

fun main(args: Array<String>) {

    val job = GlobalScope.launch {

        delay(1000)
        println("Hello Coroutines!")
    }

    Thread.sleep(2000)
}

<|start_filename|>DSL/src/main/kotlin/Receiver.kt<|end_filename|>
/**
 * Created by tony on 2018/9/17.
 */
fun main(args: Array<String>) {

    val sum1 = {
        x: Int, y: Int -> x + y
    }

    val sum2: Int.(Int) -> Int = {
        this + it
    }

    println(sum1(3,5))
    println(3.sum2(5))
}

<|start_filename|>Basic/src/main/kotlin/Nothing.kt<|end_filename|>
/**
 * Created by tony on 2018/7/26.
 */
fun doForever(): Nothing {
    while(true) {
        println("do something...")
    }
}

fun main(args: Array<String>) {
    doForever()
    println("done")
}

<|start_filename|>AAC/app/src/main/java/com/kotlin/tutorial/aac/viewmodel/SharedViewModel.kt<|end_filename|>
package com.kotlin.tutorial.aac.viewmodel

import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.aac.viewmodel.SharedViewModel
 * @author: <NAME>
 * @date: 2019-11-10 22:18
 * @version: V1.0 <描述当前版本功能>
 */
class SharedViewModel : ViewModel() {

    private val text : MutableLiveData<CharSequence> = MutableLiveData()

    fun setText(input: CharSequence) {
        text.value = input
    }

    fun getText() = text
}

<|start_filename|>Coroutines2/app/src/main/java/com/kotlin/tutorial/coroutines/activity/Demo4RetrofitActivity.kt<|end_filename|>
package com.kotlin.tutorial.coroutines.activity

import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import com.kotlin.tutorial.coroutines.R
import com.kotlin.tutorial.coroutines.config.Constant
import com.kotlin.tutorial.coroutines.http.RetrofitManager
import com.kotlin.tutorial.coroutines.model.PM25Model
import com.kotlin.tutorial.coroutines.model.SO2Model
import com.kotlin.tutorial.coroutines.model.ZipObject
import kotlinx.android.synthetic.main.activity_demo_4_retrofit.*
import kotlinx.coroutines.*

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.coroutines.activity.Demo4RetrofitActivity.ktt
 * @author: <NAME>
 * @date: 2018-09-02 14:14
 * @version: V1.0 <描述当前版本功能>
 */
class Demo4RetrofitActivity: AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_demo_4_retrofit)

        initData()
    }

    private fun initData() {

        val apiService = RetrofitManager.get().apiService()

        GlobalScope.async(Dispatchers.Default) {

            var pm25List:List<PM25Model>?=null
            var pm25Model:PM25Model? = null

            try { // 由于每小时token请求数的限制，可能会导致接口不返回数据。如果不返回数据，则使用默认的PM25Model
                pm25List = apiService.pm25(Constant.CITY_ID, Constant.TOKEN).await()
                pm25List.forEach {

                    if ("南门" == it.position_name) {

                        pm25Model = it
                    }
                }
            } catch (e: Exception) {
                pm25Model = PM25Model()
            }


            var so2List:List<SO2Model>? = null
            var so2Model:SO2Model? = null

            try { // 由于每小时token请求数的限制，可能会导致接口不返回数据。如果不返回数据，则使用默认的SO2Model
                so2List = apiService.so2(Constant.CITY_ID, Constant.TOKEN).await()
                so2List.forEach {

                    if ("南门" == it.position_name) {

                        so2Model = it
                    }
                }
            } catch (e: Exception) {
                so2Model = SO2Model()
            }

            val zipObject = ZipObject(pm25Model?.quality,
                    pm25Model?.pm2_5,
                    pm25Model?.pm2_5_24h,
                    so2Model?.so2,
                    so2Model?.so2_24h)

            withContext(Dispatchers.Main) {

                quality.setText("空气质量指数：" + zipObject.pm2_5_quality)        // 如果为空，表示使用了默认值
                pm2_5.setText("PM2.5 1小时内平均：" + zipObject.pm2_5)             // 如果为0，表示使用了默认值
                pm2_5_24h.setText("PM2.5 24小时滑动平均：" + zipObject.pm2_5_24h)  // 如果为0，表示使用了默认值

                so2.setText("二氧化硫1小时平均：" + zipObject.so2)  // 如果为0，表示使用了默认值
                so2_24h.setText("二氧化硫24小时滑动平均：" + zipObject.so2_24h) // 如果为0，表示使用了默认值
            }
        }
    }
}

<|start_filename|>Basic/src/main/kotlin/Args1.kt<|end_filename|>
/**
 * Created by tony on 2018/7/26.
 */
fun <T> toList(vararg items: T): List<T> {
    val result = ArrayList<T>()
    for (item in items)
        result.add(item)
    return result
}

fun main(args: Array<String>) {
    val list = toList("java","kotlin","scala","groovy")
    println(list)
}

<|start_filename|>Retrofit/app2/src/main/java/com/kotlin/tutorial/retrofit/app2/model/ZipObject.kt<|end_filename|>
package com.kotlin.tutorial.retrofit.app2.model

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.retrofit.app2.model.ZipObject.java
 * @author: <NAME>
 * @date: 2018-06-20 10:44
 * @version V1.0 <描述当前版本功能>
 */
data class ZipObject(

        var pm2_5_quality: String,
        var pm2_5: Int,
        var pm2_5_24h: Int,

        var so2: Int,
        var so2_24h: Int
)

<|start_filename|>Dagger2/app3/src/main/java/com/kotlin/tutorial/dagger2/app3/activity/MainActivity.kt<|end_filename|>
package com.kotlin.tutorial.dagger2.app3.activity

import android.content.Intent
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import com.kotlin.tutorial.dagger2.app3.R
import kotlinx.android.synthetic.main.activity_main.*

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.dagger2.app3.activity.MainActivity.kt
 * @author: <NAME>
 * @date: 2018-08-07 21:19
 * @version V1.0 <描述当前版本功能>
 */
class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        text1.setOnClickListener {

            val intent = Intent(this,Demo4ModuleIncludeActivity::class.java)
            startActivity(intent)
        }

        text2.setOnClickListener {

            val intent = Intent(this,Demo4ComponentDependenciesActivity::class.java)
            startActivity(intent)
        }
    }
}

<|start_filename|>Dagger2/app1/src/main/java/com/kotlin/tutorial/dagger2/di/component/UserComponent3.kt<|end_filename|>
package com.kotlin.tutorial.dagger2.di.component

import com.kotlin.tutorial.dagger2.activity.Demo4InjectWithParamActivity
import com.kotlin.tutorial.dagger2.di.module.UserModule3
import dagger.Component

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.dagger2.di.component.UserComponent3.kt
 * @author: <NAME>
 * @date: 2018-08-03 12:59
 * @version V1.0 <描述当前版本功能>
 */
@Component(modules = arrayOf(UserModule3::class))
interface UserComponent3 {

    fun inject(activity: Demo4InjectWithParamActivity)
}

<|start_filename|>Coroutines1/src/main/kotlin/Channel4.kt<|end_filename|>

import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking

/**
 * Created by tony on 2018/9/10.
 */
fun main(args: Array<String>) = runBlocking<Unit>{

    val channel = Channel<Int>(2) // 创建带有缓冲区的 channel

    launch(coroutineContext) {
        repeat(6) {
            println("Sending $it")
            channel.send(it)
        }
    }

    launch {
        repeat(6) {

            println("Receive ${channel.receive()}")
        }
    }
}

<|start_filename|>Basic/src/main/java/Generic2.java<|end_filename|>
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

/**
 * Created by tony on 2019-06-23.
 */
public class Generic2 {

    public static void main(String[] args) {

        GenericChild child = new GenericChild();
        child.printType();
    }
}

class Father<T> {}

class GenericChild extends Father<String>{

    public void printType() {

        Type genType = getClass().getGenericSuperclass();
        System.out.println(genType);
        Type params = ((ParameterizedType) genType).getActualTypeArguments()[0];
        System.out.println(params);
    }
}


<|start_filename|>Dagger2/app1/src/main/java/com/kotlin/tutorial/dagger2/activity/Demo4InjectActivity.kt<|end_filename|>
package com.kotlin.tutorial.dagger2.activity

import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.widget.Toast
import com.kotlin.tutorial.dagger2.di.component.DaggerUserComponent1
import com.kotlin.tutorial.dagger2.domain.User
import javax.inject.Inject

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.dagger2.activity.Demo4InjectActivity.ktt
 * @author: <NAME>
 * @date: 2018-08-02 00:06
 * @version V1.0 <描述当前版本功能>
 */
class Demo4InjectActivity: AppCompatActivity() {

    @Inject
    lateinit var user: User

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        DaggerUserComponent1.create().inject(this)
//        DaggerUserComponent1.builder().build().inject(this)

        Toast.makeText(this,user.testInject(),Toast.LENGTH_LONG).show()
    }
}

<|start_filename|>Coroutines1/src/main/kotlin/Async4.kt<|end_filename|>
import kotlinx.coroutines.*

/**
 * Created by tony on 2019-08-22.
 */

fun main() {

    GlobalScope.launch {

        val  result = async{

            delay(2000)
            1
        }

        result.invokeOnCompletion {

            if (it!=null){

                println("exception: ${it.message}")
            } else {

                println("result is complete")
            }
        }

        result.cancelAndJoin()

        println(result.await())
    }

    Thread.sleep(5000)
}

<|start_filename|>Basic/src/main/kotlin/Lazy.kt<|end_filename|>
/**
 * Created by tony on 2018/7/13.
 */
val str: String by lazy{
    println("aaron")
    println("cafei")
    "tony"  // 最后一行为返回值
}

fun main(args: Array<String>) {
    println(str)
    println("-----------")
    println(str)
}

<|start_filename|>Coroutines2/app/src/main/java/com/kotlin/tutorial/coroutines/api/APIService.kt<|end_filename|>
package com.kotlin.tutorial.coroutines.api


import com.kotlin.tutorial.coroutines.model.PM25Model
import com.kotlin.tutorial.coroutines.model.SO2Model
import kotlinx.coroutines.Deferred
import retrofit2.http.GET
import retrofit2.http.Query

/**
 *
 * @FileName:
 *          com.kotlin.tutorial.coroutines.api.APIService.kt
 * @author: <NAME>
 * @date: 2018-06-18 19:28
 * @version V1.0 <描述当前版本功能>
 */
interface APIService {

    companion object {

        val API_BASE_SERVER_URL = "http://www.pm25.in/"
    }

    @GET("api/querys/pm2_5.json")
    fun pm25(@Query("city") cityId: String, @Query("token") token: String): Deferred<List<PM25Model>>

    @GET("api/querys/so2.json")
    fun so2(@Query("city") cityId: String, @Query("token") token: String): Deferred<List<SO2Model>>

}