├── .gitignore ├── .idea ├── .gitignore ├── compiler.xml ├── dictionaries ├── gradle.xml ├── jarRepositories.xml ├── misc.xml └── vcs.xml ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── fish │ │ └── kotlindemo │ │ └── ExampleInstrumentedTest.kt │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── fish │ │ │ └── kotlindemo │ │ │ ├── MainActivity.kt │ │ │ ├── SecondActivity.kt │ │ │ ├── app │ │ │ └── MyApp.kt │ │ │ ├── cancelexception │ │ │ ├── CancelDemo.kt │ │ │ ├── DebugJava.java │ │ │ ├── ExceptionDemo.kt │ │ │ ├── JobDemo.kt │ │ │ └── ThreadDemo.kt │ │ │ ├── channel │ │ │ ├── ChannelDemo.kt │ │ │ └── TestChannel.kt │ │ │ ├── classobject │ │ │ ├── ConTest.kt │ │ │ ├── ConTest1.kt │ │ │ ├── JavaConTest.java │ │ │ ├── JavaParent.java │ │ │ ├── KotlinInter.kt │ │ │ ├── KtOuter.kt │ │ │ ├── KtParent.kt │ │ │ ├── Start.java │ │ │ └── Start.kt │ │ │ ├── common │ │ │ ├── CommonDemo.kt │ │ │ └── Test.kt │ │ │ ├── coroutine │ │ │ ├── CoroutineJJ.kt │ │ │ ├── Me.kt │ │ │ ├── TestCoroutine.kt │ │ │ └── TestJava.java │ │ │ ├── coroutinebus │ │ │ └── Bus.kt │ │ │ ├── coroutinedispatch │ │ │ ├── CoroutineDispatch.kt │ │ │ └── DebugCoroutine.kt │ │ │ ├── coroutineraw │ │ │ ├── CoroutineRaw.kt │ │ │ └── StartLaunch.kt │ │ │ ├── coroutinestory │ │ │ ├── JavaStudent.java │ │ │ ├── StudentCoroutine.kt │ │ │ ├── StudentInfo.java │ │ │ └── TeacherInfo.java │ │ │ ├── coroutinesuspend │ │ │ ├── CoroutineGraph.kt │ │ │ └── CoroutineSuspend.kt │ │ │ ├── coroutinethreadpool │ │ │ ├── DebugPool.kt │ │ │ └── Pool.kt │ │ │ ├── datastore │ │ │ ├── DataStoreActivity.kt │ │ │ ├── LoginInfoSerializer.kt │ │ │ ├── MyDataStore.kt │ │ │ ├── Test.kt │ │ │ └── UserPreferencesSerializer.kt │ │ │ ├── diffjava │ │ │ └── Diff.kt │ │ │ ├── flow │ │ │ ├── FlowBuffer.kt │ │ │ ├── FlowDemo.kt │ │ │ └── Test.kt │ │ │ ├── flowoperand │ │ │ ├── FlowOperand.kt │ │ │ ├── FlowOperandAll.kt │ │ │ ├── LiveDataDemo.kt │ │ │ └── Test.java │ │ │ ├── fragment │ │ │ └── dialogFragment │ │ │ │ ├── FishFragmentActivity.kt │ │ │ │ ├── FishPureFragment.kt │ │ │ │ ├── MyDialogFragment.kt │ │ │ │ └── MyView.kt │ │ │ ├── funclass │ │ │ ├── ClassFun.kt │ │ │ ├── ExpandFun.kt │ │ │ ├── HighOrderFun.kt │ │ │ ├── InlineFun.kt │ │ │ ├── ObjectExpression.kt │ │ │ ├── Start.kt │ │ │ ├── TestJava.java │ │ │ └── UpFun.kt │ │ │ ├── inner │ │ │ ├── InnerJava.java │ │ │ ├── TestInner.kt │ │ │ └── TmpDemo.kt │ │ │ ├── lifecycleAndCoroutine │ │ │ ├── MyFlow.kt │ │ │ ├── MyLifecycle.kt │ │ │ ├── MyVM.kt │ │ │ └── ThirdActivity.kt │ │ │ ├── mutablesharedflow │ │ │ └── MutableSharedFlowDemo.kt │ │ │ ├── object │ │ │ ├── EasyJavaInterface.java │ │ │ ├── JavaAbClass.java │ │ │ ├── JavaAbClass2.java │ │ │ ├── JavaInterface.java │ │ │ ├── JavaSingleton.java │ │ │ ├── JavaStatic.java │ │ │ ├── ObjectCompanion.kt │ │ │ ├── ObjectDeclaration.kt │ │ │ ├── ObjectExpression.kt │ │ │ ├── Start.kt │ │ │ └── TestJava.java │ │ │ ├── repository │ │ │ └── MyRepo.kt │ │ │ ├── select │ │ │ ├── SelectDebug.kt │ │ │ └── SelectDemo.kt │ │ │ ├── sequence │ │ │ ├── Java8Stream.java │ │ │ └── SequenceDemo.kt │ │ │ ├── service │ │ │ └── MyService.kt │ │ │ ├── ui │ │ │ ├── TestData.java │ │ │ ├── dashboard │ │ │ │ ├── DashboardFragment.kt │ │ │ │ └── DashboardViewModel.kt │ │ │ ├── home │ │ │ │ ├── HomeFragment.kt │ │ │ │ └── HomeViewModel.kt │ │ │ └── notifications │ │ │ │ ├── NotificationsFragment.kt │ │ │ │ └── NotificationsViewModel.kt │ │ │ ├── varclass │ │ │ ├── FunTest.kt │ │ │ ├── Start.kt │ │ │ ├── TestJava.java │ │ │ ├── TestJavaActivity.java │ │ │ ├── VarTest.kt │ │ │ └── VarTestClass.kt │ │ │ └── vm │ │ │ ├── MyViewModel.kt │ │ │ └── MyViewModel2.kt │ ├── proto │ │ ├── login_info.proto │ │ └── user_prefs.proto │ └── res │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ ├── ic_dashboard_black_24dp.xml │ │ ├── ic_home_black_24dp.xml │ │ ├── ic_launcher_background.xml │ │ └── ic_notifications_black_24dp.xml │ │ ├── layout │ │ ├── activity_datastore.xml │ │ ├── activity_main.xml │ │ ├── activity_second.xml │ │ ├── activity_third.xml │ │ ├── fragment_dashboard.xml │ │ ├── fragment_home.xml │ │ ├── fragment_notifications.xml │ │ └── layout_fragment.xml │ │ ├── menu │ │ └── bottom_nav_menu.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── navigation │ │ └── mobile_navigation.xml │ │ ├── values-night │ │ └── themes.xml │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── themes.xml │ └── test │ └── java │ └── com │ └── fish │ └── kotlindemo │ └── ExampleUnitTest.kt ├── build.gradle ├── config.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/caches 5 | /.idea/libraries 6 | /.idea/modules.xml 7 | /.idea/workspace.xml 8 | /.idea/navEditor.xml 9 | /.idea/assetWizardSettings.xml 10 | .DS_Store 11 | /build 12 | /captures 13 | .externalNativeBuild 14 | .cxx 15 | local.properties 16 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/dictionaries: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 19 | 20 | -------------------------------------------------------------------------------- /.idea/jarRepositories.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 14 | 15 | 19 | 20 | 24 | 25 | 29 | 30 | 34 | 35 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 18 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # KotlinDemo 2 | 博客附带的源码集合 3 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'com.android.application' 3 | id 'kotlin-android' 4 | id "com.google.protobuf" 5 | } 6 | 7 | android { 8 | compileSdkVersion 31 9 | buildToolsVersion "30.0.3" 10 | 11 | defaultConfig { 12 | applicationId "com.fish.kotlindemo" 13 | minSdkVersion 21 14 | targetSdkVersion 30 15 | versionCode 1 16 | versionName "1.0" 17 | 18 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 19 | } 20 | 21 | buildTypes { 22 | release { 23 | minifyEnabled false 24 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 25 | } 26 | } 27 | compileOptions { 28 | sourceCompatibility JavaVersion.VERSION_1_8 29 | targetCompatibility JavaVersion.VERSION_1_8 30 | } 31 | kotlinOptions { 32 | jvmTarget = '1.8' 33 | } 34 | buildFeatures { 35 | viewBinding true 36 | } 37 | } 38 | 39 | dependencies { 40 | 41 | implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" 42 | implementation 'androidx.core:core-ktx:1.3.1' 43 | implementation 'androidx.appcompat:appcompat:1.2.0' 44 | implementation 'com.google.android.material:material:1.2.1' 45 | implementation 'androidx.constraintlayout:constraintlayout:2.0.1' 46 | implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.2.0' 47 | implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0' 48 | implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1' 49 | implementation 'androidx.navigation:navigation-fragment-ktx:2.3.0' 50 | implementation 'androidx.navigation:navigation-ui-ktx:2.3.0' 51 | testImplementation 'junit:junit:4.+' 52 | androidTestImplementation 'androidx.test.ext:junit:1.1.2' 53 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' 54 | 55 | implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.0") 56 | implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' 57 | implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.4.1' 58 | 59 | implementation("androidx.datastore:datastore-preferences:1.0.0") 60 | implementation("androidx.datastore:datastore:1.0.0") 61 | implementation "com.google.protobuf:protobuf-javalite:3.18.0" 62 | 63 | } 64 | 65 | protobuf { 66 | protoc { 67 | artifact = "com.google.protobuf:protoc:3.14.0" 68 | } 69 | 70 | // Generates the java Protobuf-lite code for the Protobufs in this project. See 71 | // https://github.com/google/protobuf-gradle-plugin#customizing-protobuf-compilation 72 | // for more information. 73 | generateProtoTasks { 74 | all().each { task -> 75 | task.builtins { 76 | java { 77 | option 'lite' 78 | } 79 | } 80 | } 81 | } 82 | } -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /app/src/androidTest/java/com/fish/kotlindemo/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo 2 | 3 | import androidx.test.platform.app.InstrumentationRegistry 4 | import androidx.test.ext.junit.runners.AndroidJUnit4 5 | 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | import org.junit.Assert.* 10 | 11 | /** 12 | * Instrumented test, which will execute on an Android device. 13 | * 14 | * See [testing documentation](http://d.android.com/tools/testing). 15 | */ 16 | @RunWith(AndroidJUnit4::class) 17 | class ExampleInstrumentedTest { 18 | @Test 19 | fun useAppContext() { 20 | // Context of the app under test. 21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext 22 | assertEquals("com.fish.kotlindemo", appContext.packageName) 23 | } 24 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 13 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo 2 | 3 | import android.content.ComponentName 4 | import android.content.Intent 5 | import android.os.Bundle 6 | import android.util.Log 7 | import android.widget.Toast 8 | import androidx.appcompat.app.AppCompatActivity 9 | import androidx.lifecycle.lifecycleScope 10 | import androidx.navigation.findNavController 11 | import androidx.navigation.ui.AppBarConfiguration 12 | import androidx.navigation.ui.setupActionBarWithNavController 13 | import androidx.navigation.ui.setupWithNavController 14 | import com.fish.kotlindemo.coroutineraw.startLaunch 15 | import com.fish.kotlindemo.coroutinestory.JavaStudent 16 | import com.fish.kotlindemo.coroutinestory.StudentCoroutine 17 | import com.fish.kotlindemo.coroutinestory.StudentInfo 18 | import com.fish.kotlindemo.coroutinestory.TeacherInfo 19 | import com.fish.kotlindemo.coroutinesuspend.getStuInfo 20 | import com.fish.kotlindemo.databinding.ActivityMainBinding 21 | import com.fish.kotlindemo.datastore.DataStoreActivity 22 | import com.fish.kotlindemo.flowoperand.LiveDataDemo 23 | import com.fish.kotlindemo.lifecycleAndCoroutine.ThirdActivity 24 | import com.fish.kotlindemo.repository.MyRepo 25 | import com.fish.kotlindemo.vm.MyViewModel 26 | import com.google.android.material.bottomnavigation.BottomNavigationView 27 | import kotlinx.coroutines.Dispatchers 28 | import kotlinx.coroutines.GlobalScope 29 | import kotlinx.coroutines.launch 30 | import kotlin.concurrent.thread 31 | 32 | class MainActivity : AppCompatActivity() { 33 | 34 | private lateinit var binding: ActivityMainBinding 35 | 36 | override fun onCreate(savedInstanceState: Bundle?) { 37 | super.onCreate(savedInstanceState) 38 | 39 | binding = ActivityMainBinding.inflate(layoutInflater) 40 | setContentView(binding.root) 41 | 42 | val navView: BottomNavigationView = binding.navView 43 | 44 | val navController = findNavController(R.id.nav_host_fragment_activity_main) 45 | // Passing each menu ID as a set of Ids because each 46 | // menu should be considered as top level destinations. 47 | val appBarConfiguration = AppBarConfiguration(setOf( 48 | R.id.navigation_home, R.id.navigation_dashboard, R.id.navigation_notifications)) 49 | setupActionBarWithNavController(navController, appBarConfiguration) 50 | navView.setupWithNavController(navController) 51 | 52 | binding.btnJava.setOnClickListener { 53 | var javaStudent = JavaStudent() 54 | // var studentInfo = javaStudent.getWithoutThread(999) 55 | // Toast.makeText(this, "学生姓名:${studentInfo?.name ?:"空"}", Toast.LENGTH_LONG).show() 56 | // javaStudent.getStuInfoAsync(999) { 57 | // runOnUiThread { 58 | // Toast.makeText(this, "学生姓名:${it?.name ?: "空"}", Toast.LENGTH_LONG).show() 59 | // } 60 | // } 61 | 62 | javaStudent.getTeachInfoAsync(999, object : JavaStudent.Callback { 63 | override fun onCallback(teacherInfo: TeacherInfo?) { 64 | runOnUiThread { 65 | Toast.makeText(binding.root.context, 66 | "老师姓名:${teacherInfo?.name ?: "空"}", 67 | Toast.LENGTH_LONG).show() 68 | } 69 | } 70 | 71 | override fun onCallback(studentInfo: StudentInfo?) { 72 | TODO("Not yet implemented") 73 | } 74 | }) 75 | } 76 | 77 | binding.btnKotlin.setOnClickListener { 78 | var student = StudentCoroutine() 79 | student.getTeachInfo(this@MainActivity, 999) 80 | } 81 | 82 | binding.btnRaw.setOnClickListener { 83 | startLaunch() 84 | val liveDataDemo = LiveDataDemo() 85 | liveDataDemo.test0() 86 | } 87 | 88 | //点击UI 89 | binding.btnDelay.setOnClickListener { 90 | GlobalScope.launch(Dispatchers.Main) { 91 | //在主线程执行协程 92 | Log.d("fish", "before suspend thread:${Thread.currentThread()}") 93 | //执行挂起函数 94 | getStuInfo() 95 | } 96 | binding.btnDelay.postDelayed({ 97 | //延迟2s在主线程执行打印 98 | Log.d("fish", "post thread:${Thread.currentThread()}") 99 | }, 2000) 100 | } 101 | 102 | //分发 103 | binding.btnDispatch.setOnClickListener { 104 | // var dispatch = CoroutineDispatch(binding.root.context) 105 | //// dispatch.showStuInfo() 106 | //// dispatch.showStuInfoV2() 107 | //// dispatch.launch1() 108 | // dispatch.launch2() 109 | // 110 | // var pool = Pool(binding.root.context) 111 | // pool.showStuName() 112 | 113 | GlobalScope.launch(Dispatchers.Main) { 114 | Toast.makeText(binding.root.context, 115 | "老师姓名2", 116 | Toast.LENGTH_LONG).show() 117 | 118 | val throwable = Throwable("just test") 119 | var thread = Thread.currentThread() 120 | thread.uncaughtExceptionHandler.uncaughtException(thread, throwable) 121 | 122 | Toast.makeText(binding.root.context, 123 | "老师姓名3", 124 | Toast.LENGTH_LONG).show() 125 | } 126 | } 127 | 128 | binding.btnMvi.setOnClickListener { 129 | val jump = Intent(this@MainActivity, SecondActivity::class.java) 130 | startActivity(jump) 131 | } 132 | 133 | binding.btnLifeCoroutine.setOnClickListener { 134 | val jump = Intent(this@MainActivity, ThirdActivity::class.java) 135 | startActivity(jump) 136 | } 137 | 138 | binding.btnDs.setOnClickListener { 139 | startActivity(Intent(this@MainActivity, DataStoreActivity::class.java)) 140 | } 141 | } 142 | } -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/SecondActivity.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo 2 | 3 | import android.os.Bundle 4 | import android.widget.Toast 5 | import androidx.appcompat.app.AppCompatActivity 6 | import androidx.fragment.app.DialogFragment 7 | import androidx.lifecycle.Lifecycle 8 | import androidx.lifecycle.flowWithLifecycle 9 | import androidx.lifecycle.lifecycleScope 10 | import androidx.lifecycle.repeatOnLifecycle 11 | import com.fish.kotlindemo.databinding.ActivitySecondBinding 12 | import com.fish.kotlindemo.lifecycleAndCoroutine.MyFlow 13 | import com.fish.kotlindemo.vm.MyViewModel2 14 | import kotlinx.coroutines.* 15 | import kotlinx.coroutines.flow.collect 16 | import java.lang.Exception 17 | 18 | class SecondActivity : AppCompatActivity() { 19 | 20 | private lateinit var binding: ActivitySecondBinding 21 | override fun onCreate(savedInstanceState: Bundle?) { 22 | super.onCreate(savedInstanceState) 23 | binding = ActivitySecondBinding.inflate(layoutInflater) 24 | setContentView(binding.root) 25 | 26 | binding.btnStartLifecycle.setOnClickListener { 27 | lifecycleScope.launch(Dispatchers.Main) { 28 | try { 29 | delay(5000) 30 | } catch (e : Exception) { 31 | println(e.localizedMessage) 32 | } 33 | println("hello world") 34 | } 35 | 36 | // val vm = MyViewModel2() 37 | // vm.test() 38 | // vm.livedata3.observe(this) { 39 | // Toast.makeText(this, it, Toast.LENGTH_SHORT).show() 40 | // } 41 | // vm.update() 42 | 43 | } 44 | 45 | lifecycleScope.launchWhenResumed { 46 | MyFlow().flow.collect { 47 | println("collect when $it") 48 | } 49 | 50 | 51 | // println("fuck...") 52 | // lifecycleScope.launch(Dispatchers.IO) { 53 | // var count = 0 54 | // while (true) { 55 | // delay(1000) 56 | // println("collect ${count++}") 57 | // } 58 | // } 59 | // println("fuck2...") 60 | 61 | 62 | } 63 | 64 | // val dialogFragment = DialogFragment() 65 | // dialogFragment.show(supportFragmentManager, "hello") 66 | 67 | println("111") 68 | lifecycleScope.launch(Dispatchers.Main) { 69 | repeatOnLifecycle(Lifecycle.State.STARTED) { 70 | MyFlow().flow.collect { 71 | println("collect repeat $it") 72 | } 73 | MyFlow().flow.flowWithLifecycle(lifecycle, Lifecycle.State.STARTED) 74 | } 75 | println("222") 76 | 77 | } 78 | 79 | 80 | } 81 | 82 | override fun onStart() { 83 | super.onStart() 84 | } 85 | 86 | override fun onResume() { 87 | super.onResume() 88 | } 89 | 90 | override fun onDestroy() { 91 | super.onDestroy() 92 | } 93 | 94 | object Fuck:JJ() 95 | } 96 | 97 | open class JJ { 98 | fun lishi(){} 99 | } 100 | 101 | sealed class MainState { 102 | 103 | object Idle : JJ() 104 | object Loading : MainState() 105 | data class Users(val user: List) : MainState() 106 | data class Error(val error: String) : MainState() 107 | } -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/app/MyApp.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.app 2 | 3 | import android.app.Application 4 | import androidx.core.app.NotificationManagerCompat 5 | import androidx.lifecycle.* 6 | import com.fish.kotlindemo.repository.MyRepo 7 | import kotlinx.coroutines.* 8 | 9 | 10 | val Application.scope: CoroutineScope 11 | get() { 12 | return CoroutineScope(SupervisorJob() + Dispatchers.IO) 13 | } 14 | 15 | 16 | class MyApp:Application() { 17 | override fun onCreate() { 18 | super.onCreate() 19 | MyRepo().bind(this) 20 | 21 | // System.setProperty("kotlinx.coroutines.scheduler.core.pool.size", "20") 22 | // 23 | // System.setProperty("kotlinx.coroutines.io.parallelism", "40") 24 | 25 | 26 | ProcessLifecycleOwner.get().lifecycleScope.launch { 27 | delay(1000) 28 | } 29 | 30 | ProcessLifecycleOwner.get().lifecycle.addObserver(object : DefaultLifecycleObserver { 31 | override fun onStart(owner: LifecycleOwner) { 32 | super.onStart(owner) 33 | println("foreground") 34 | checkPermission() 35 | } 36 | 37 | override fun onStop(owner: LifecycleOwner) { 38 | super.onStop(owner) 39 | println("background") 40 | } 41 | }) 42 | } 43 | 44 | fun checkPermission() { 45 | val notify = NotificationManagerCompat.from(this).areNotificationsEnabled(); 46 | println("notify:$notify") 47 | } 48 | } 49 | 50 | 51 | -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/cancelexception/CancelDemo.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.cancelexception 2 | 3 | import kotlinx.coroutines.* 4 | 5 | class CancelDemo { 6 | fun testCancel() { 7 | runBlocking() { 8 | var job1 = launch(Dispatchers.IO) { 9 | println("job1 start") 10 | Thread.sleep(200) 11 | var count = 0 12 | while (count < 1000000000) { 13 | count++ 14 | } 15 | println("job1 end count:$count") 16 | } 17 | Thread.sleep(100) 18 | println("start cancel job1") 19 | //取消job(取消协程) 20 | job1.cancel() 21 | println("end cancel job1") 22 | } 23 | } 24 | 25 | fun testCancel2() { 26 | runBlocking() { 27 | var job1 = launch(Dispatchers.IO) { 28 | println("job1 start") 29 | Thread.sleep(80) 30 | var count = 0 31 | //判断协程的状态,若是活跃则继续循环 32 | //isActive = coroutineContext[Job]?.isActive ?: true 33 | while (count < 1000000000 && isActive) { 34 | count++ 35 | } 36 | println("job1 end count:$count") 37 | } 38 | Thread.sleep(100) 39 | println("start cancel job1") 40 | //取消job(取消协程) 41 | job1.cancel() 42 | println("end cancel job1") 43 | } 44 | } 45 | 46 | fun testCancel3() { 47 | runBlocking() { 48 | var job1 = launch(Dispatchers.IO) { 49 | Thread.sleep(3000) 50 | println("coroutine isActive:$isActive")//① 51 | } 52 | Thread.sleep(100) 53 | println("start cancel job1") 54 | //取消job(取消协程) 55 | job1.cancel() 56 | println("end cancel job1") 57 | } 58 | } 59 | 60 | fun testCancel4() { 61 | runBlocking() { 62 | var job1 = launch(Dispatchers.IO) { 63 | //协程挂起 64 | println("job1 start") 65 | try { 66 | delay(3000) 67 | } catch (e : Exception) { 68 | println("delay exception:$e") 69 | } 70 | println("coroutine isActive:$isActive")//① 71 | } 72 | Thread.sleep(100) 73 | println("start cancel job1") 74 | //取消job(取消协程) 75 | job1.cancel() 76 | println("end cancel job1") 77 | } 78 | } 79 | 80 | fun testCancel5() { 81 | runBlocking() { 82 | var job1 = launch(Dispatchers.IO) { 83 | try { 84 | //挂起函数 85 | } catch (e : Exception) { 86 | println("delay exception:$e") 87 | } 88 | if (!isActive) { 89 | println("cancel") 90 | } 91 | } 92 | } 93 | } 94 | } 95 | 96 | fun main(args: Array) { 97 | var demo = CancelDemo() 98 | demo.testCancel4() 99 | Thread.sleep(1000000) 100 | } -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/cancelexception/DebugJava.java: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.cancelexception; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | import androidx.annotation.NonNull; 9 | 10 | public class DebugJava { 11 | 12 | class Human { 13 | 14 | } 15 | 16 | class Man extends Human{ 17 | 18 | } 19 | 20 | private void testList() { 21 | List humans = new ArrayList(); 22 | List humanj = new ArrayList(); 23 | humanj.add(new Man()); 24 | } 25 | 26 | 27 | class MyHandler implements Thread.UncaughtExceptionHandler { 28 | @Override 29 | public void uncaughtException(@NonNull @NotNull Thread t, @NonNull @NotNull Throwable e) { 30 | System.out.println(e.getLocalizedMessage()); 31 | } 32 | } 33 | 34 | 35 | private void testEx() { 36 | // Thread.setDefaultUncaughtExceptionHandler(new MyHandler()); 37 | new Thread(new Runnable() { 38 | @Override 39 | public void run() { 40 | System.out.println("java"); 41 | try { 42 | throw new RuntimeException("fuck exception"); 43 | } catch (Exception e) { 44 | 45 | } 46 | Thread thread = Thread.currentThread(); 47 | Throwable throwable = new Throwable("just test"); 48 | thread.getUncaughtExceptionHandler().uncaughtException(thread, throwable); 49 | while (true) { 50 | try { 51 | Thread.sleep(1000); 52 | } catch (InterruptedException e) { 53 | e.printStackTrace(); 54 | } 55 | System.out.println("jj test"); 56 | } 57 | } 58 | }).start(); 59 | 60 | try { 61 | Thread.sleep(2000); 62 | } catch (InterruptedException e) { 63 | e.printStackTrace(); 64 | } 65 | System.out.println("java main running..."); 66 | } 67 | 68 | public static void main(String args[]) { 69 | DebugJava debugJava = new DebugJava(); 70 | debugJava.testEx(); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/cancelexception/ExceptionDemo.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.cancelexception 2 | 3 | import kotlinx.coroutines.* 4 | 5 | class ExceptionDemo { 6 | fun testException() { 7 | runBlocking { 8 | try { 9 | var job1 = launch(Dispatchers.IO) { 10 | println("job1 start") 11 | //异常 12 | 1 / 0 13 | println("job1 end") 14 | } 15 | } catch (e: Exception) { 16 | } 17 | } 18 | } 19 | 20 | fun testException2() { 21 | runBlocking { 22 | var job1 = launch(Dispatchers.IO) { 23 | try { 24 | println("job1 start") 25 | //异常 26 | 1 / 0 27 | println("job1 end") 28 | } catch (e: Exception) { 29 | println("e=$e") 30 | } 31 | } 32 | } 33 | } 34 | 35 | //创建处理异常对象 36 | val exceptionHandler = CoroutineExceptionHandler { _, exception -> 37 | println("handle exception:$exception") 38 | } 39 | 40 | fun testException3() { 41 | runBlocking { 42 | //声明协程作用域 43 | var scope = CoroutineScope(Job()) 44 | var job1 = scope.launch(Dispatchers.IO) { 45 | println("job1 start") 46 | //异常 47 | 1 / 0 48 | println("job1 end") 49 | } 50 | } 51 | } 52 | 53 | fun testException4() { 54 | runBlocking { 55 | //声明协程作用域 56 | var rootJob = Job() 57 | var scope = CoroutineScope(rootJob) 58 | var job1 = scope.launch(Dispatchers.IO + exceptionHandler) { 59 | println("job1 start") 60 | //异常 61 | 1 / 0 62 | println("job1 end") 63 | } 64 | 65 | job1.join() 66 | //检查父Job 状态 67 | println("rootJob isActive:${rootJob.isActive}") 68 | } 69 | } 70 | 71 | fun testException5() { 72 | runBlocking { 73 | //声明协程作用域 74 | var rootJob = Job() 75 | var scope = CoroutineScope(rootJob) 76 | var job1 = scope.launch(Dispatchers.IO + exceptionHandler) { 77 | println("job1 start") 78 | Thread.sleep(100) 79 | //异常 80 | 1 / 0 81 | println("job1 end") 82 | } 83 | 84 | var job2 = scope.launch { 85 | println("job2 start") 86 | Thread.sleep(200) 87 | //检查jo2状态 88 | println("jo2 isActive:$isActive") 89 | } 90 | 91 | job1.join() 92 | //检查父Job 状态 93 | println("rootJob isActive:${rootJob.isActive}") 94 | } 95 | } 96 | 97 | fun testException6() { 98 | runBlocking { 99 | //声明协程作用域 100 | var rootJob = SupervisorJob() 101 | var scope = CoroutineScope(rootJob) 102 | var job1 = scope.launch(Dispatchers.IO + exceptionHandler) { 103 | println("job1 start") 104 | Thread.sleep(100) 105 | //异常 106 | 1 / 0 107 | println("job1 end") 108 | } 109 | 110 | var job2 = scope.launch { 111 | println("job2 start") 112 | Thread.sleep(200) 113 | //检查jo2状态 114 | println("jo2 isActive:$isActive") 115 | } 116 | 117 | job1.join() 118 | //检查父Job 状态 119 | println("rootJob isActive:${rootJob.isActive}") 120 | } 121 | } 122 | 123 | fun testException7() { 124 | runBlocking { 125 | //声明协程作用域 126 | var rootJob = SupervisorJob() 127 | var scope = CoroutineScope(rootJob) 128 | var job1 = scope.launch(Dispatchers.IO + exceptionHandler) { 129 | println("job1 start") 130 | Thread.sleep(2000) 131 | println("job1 end") 132 | } 133 | 134 | var job2 = scope.launch { 135 | println("job2 start") 136 | Thread.sleep(1000) 137 | //检查jo2状态 138 | println("jo2 isActive:$isActive") 139 | } 140 | 141 | Thread.sleep(300) 142 | job1.cancel() 143 | //检查父Job 状态 144 | println("rootJob isActive:${rootJob.isActive}") 145 | } 146 | } 147 | 148 | fun testException8() { 149 | runBlocking { 150 | //声明协程作用域 151 | var rootJob = SupervisorJob() 152 | var scope = CoroutineScope(rootJob) 153 | var job1 = scope.launch(Dispatchers.IO + exceptionHandler) { 154 | println("job1 start") 155 | Thread.sleep(2000) 156 | println("jo1 isActive:$isActive") 157 | } 158 | 159 | var job2 = scope.launch { 160 | println("job2 start") 161 | Thread.sleep(1000) 162 | //检查jo2状态 163 | println("jo2 isActive:$isActive") 164 | } 165 | 166 | Thread.sleep(300) 167 | rootJob.cancel() 168 | //检查父Job 状态 169 | println("rootJob isActive:${rootJob.isActive}") 170 | } 171 | } 172 | } 173 | 174 | fun main(args: Array) { 175 | var demo = ExceptionDemo() 176 | demo.testException8() 177 | Thread.sleep(1000000) 178 | } -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/cancelexception/JobDemo.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.cancelexception 2 | 3 | import kotlinx.coroutines.* 4 | import java.lang.RuntimeException 5 | 6 | class JobDemo { 7 | fun testJob() { 8 | //父Job 9 | var rootJob: Job? = null 10 | runBlocking { 11 | //启动子Job 12 | var job1 = launch { 13 | println("job1") 14 | } 15 | //启动子Job 16 | var job2 = launch { 17 | println("job2") 18 | } 19 | rootJob = coroutineContext[Job] 20 | job1.join() 21 | job2.join() 22 | } 23 | } 24 | 25 | fun testJob2() { 26 | runBlocking {//父Job==rootJob 27 | //启动子Job 28 | var job1 = launch { 29 | println("job1") 30 | Thread.sleep(200000) 31 | } 32 | // //启动子Job 33 | var job2 = launch { 34 | println("job2") 35 | Thread.sleep(200000) 36 | } 37 | Thread.sleep(200) 38 | job1.cancel("") 39 | } 40 | } 41 | } 42 | 43 | fun main(args: Array) { 44 | var jobDemo = JobDemo() 45 | jobDemo.testJob2() 46 | 47 | Thread.sleep(200000) 48 | } -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/cancelexception/ThreadDemo.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.cancelexception 2 | 3 | import java.lang.Exception 4 | import kotlin.concurrent.thread 5 | 6 | class ThreadDemo { 7 | fun testStop() { 8 | //构造线程 9 | var t1 = thread { 10 | var count = 0 11 | println("thread start") 12 | //检测是否被中断 13 | while (count < 100000000 && !Thread.interrupted()) { 14 | count++ 15 | } 16 | println("thread end count:$count") 17 | } 18 | //等待线程运行 19 | Thread.sleep(10) 20 | println("interrupt t1 start") 21 | t1.interrupt() 22 | println("interrupt t1 end") 23 | } 24 | 25 | fun testException() { 26 | try { 27 | //开启线程 28 | thread { 29 | 1/0 30 | } 31 | } catch (e : Exception) { 32 | println("e:$e") 33 | } 34 | } 35 | 36 | fun testException2() { 37 | thread { 38 | try { 39 | 1/0 40 | } catch (e : Exception) { 41 | println("e:$e") 42 | } 43 | } 44 | } 45 | 46 | fun testException3() { 47 | try { 48 | //开启线程 49 | var t1 = thread(false){ 50 | 1/0 51 | } 52 | t1.name = "myThread" 53 | //设置 54 | t1.setUncaughtExceptionHandler { t, e -> 55 | println("${t.name} exception:$e") 56 | } 57 | t1.start() 58 | } catch (e : Exception) { 59 | println("e:$e") 60 | } 61 | } 62 | 63 | 64 | } 65 | 66 | fun main(args : Array) { 67 | var threadDemo = ThreadDemo() 68 | // threadDemo.testStop() 69 | threadDemo.testException3() 70 | } -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/channel/ChannelDemo.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.channel 2 | 3 | import com.fish.kotlindemo.common.CommonDemo 4 | import kotlinx.coroutines.GlobalScope 5 | import kotlinx.coroutines.async 6 | import kotlinx.coroutines.channels.BufferOverflow 7 | import kotlinx.coroutines.channels.Channel 8 | import kotlinx.coroutines.channels.Channel.Factory.CONFLATED 9 | import kotlinx.coroutines.channels.actor 10 | import kotlinx.coroutines.channels.produce 11 | import kotlinx.coroutines.launch 12 | import kotlinx.coroutines.runBlocking 13 | import java.util.concurrent.ArrayBlockingQueue 14 | import java.util.concurrent.BlockingQueue 15 | import kotlin.concurrent.thread 16 | 17 | class ChannelDemo { 18 | 19 | fun testChannel() { 20 | //协程1 21 | var deferred= GlobalScope.async { 22 | //假装在加工数据 23 | Thread.sleep(2000) 24 | "Hello fishforest" 25 | } 26 | //协程2 27 | GlobalScope.launch { 28 | var result = deferred.await() 29 | println("get result from coroutine1: $result") 30 | } 31 | } 32 | 33 | fun testChannel2() { 34 | //阻塞队列 35 | var queue = ArrayBlockingQueue(5) 36 | //协程1 37 | GlobalScope.launch { 38 | var count = 0 39 | while (true) { 40 | //假装在加工数据 41 | Thread.sleep(1000) 42 | queue.put("fish ${count++}") 43 | } 44 | } 45 | 46 | //协程2 47 | GlobalScope.launch { 48 | while (true) { 49 | Thread.sleep(1000) 50 | println("get result from coroutine1:${queue.take()}") 51 | } 52 | } 53 | } 54 | 55 | //默认类型 56 | fun testChannel3() { 57 | //定义Channel 58 | var channel = Channel() 59 | //协程1 60 | GlobalScope.launch { 61 | var count = 0 62 | while (true) { 63 | //假装在加工数据 64 | Thread.sleep(1000) 65 | var sendStr = "fish ${count++}" 66 | println("send $sendStr") 67 | channel.send("$sendStr") 68 | } 69 | } 70 | 71 | //协程2 72 | GlobalScope.launch { 73 | while (true) { 74 | Thread.sleep(1000) 75 | println("receive:${channel.receive()}") 76 | } 77 | } 78 | } 79 | 80 | //混合类型 81 | fun testChannel4() { 82 | //定义Channel 83 | var channel = Channel(CONFLATED) 84 | //协程1 85 | GlobalScope.launch { 86 | var count = 0 87 | while (true) { 88 | var sendStr = "fish ${count++}" 89 | println("send $sendStr") 90 | channel.send("$sendStr") 91 | } 92 | } 93 | 94 | //协程2 95 | GlobalScope.launch { 96 | while (true) { 97 | println("receive:${channel.receive()}") 98 | } 99 | } 100 | } 101 | 102 | //缓冲类型 103 | fun testChannel5() { 104 | //定义Channel 105 | var channel = Channel(Channel.BUFFERED) 106 | //协程1 107 | GlobalScope.launch { 108 | var count = 0 109 | while (true) { 110 | var sendStr = "fish ${count++}" 111 | println("send $sendStr") 112 | channel.send("$sendStr") 113 | } 114 | } 115 | 116 | //协程2 117 | GlobalScope.launch { 118 | while (true) { 119 | println("receive:${channel.receive()}") 120 | } 121 | } 122 | } 123 | 124 | //无限类型 125 | fun testChannel6() { 126 | //定义Channel 127 | var channel = Channel(Channel.UNLIMITED) 128 | //协程1 129 | GlobalScope.launch { 130 | var count = 0 131 | while (true) { 132 | var sendStr = "fish ${count++}" 133 | println("send $sendStr") 134 | channel.send("$sendStr") 135 | break; 136 | } 137 | } 138 | 139 | //协程2 140 | GlobalScope.launch { 141 | while (true) { 142 | println("receive:${channel.receive()}") 143 | } 144 | } 145 | } 146 | 147 | //produce 148 | fun testProduce() { 149 | //返回接收者 150 | var receiveChannel = GlobalScope.produce { 151 | // 152 | for (x in 1..5) { 153 | var sendStr = "fish $x" 154 | println("send $sendStr") 155 | send("$sendStr") 156 | } 157 | } 158 | //接收数据 159 | GlobalScope.launch { 160 | while (true) { 161 | println("job2 receive:${receiveChannel.receive()}") 162 | } 163 | println("job2 end") 164 | } 165 | GlobalScope.launch { 166 | while (true) { 167 | println("job3 receive:${receiveChannel.receive()}") 168 | } 169 | println("job3 end") 170 | } 171 | } 172 | 173 | fun testActor() { 174 | //返回发送者 175 | var sendChannel = GlobalScope.actor { 176 | // 177 | for (x in 1..5) { 178 | println("job1 receive:${receive()}") 179 | } 180 | println("actor end") 181 | } 182 | //发送者 183 | GlobalScope.launch { 184 | while (true) { 185 | sendChannel.send("send from job2") 186 | } 187 | println("job2 end") 188 | } 189 | GlobalScope.launch { 190 | sendChannel.send("send from job3") 191 | } 192 | } 193 | } 194 | 195 | 196 | fun main(args: Array) { 197 | var demo = ChannelDemo() 198 | demo.testActor() 199 | Thread.sleep(1000000) 200 | } -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/channel/TestChannel.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.channel 2 | 3 | import kotlinx.coroutines.channels.* 4 | 5 | class TestChannel { 6 | fun test(blcok:(String)->Int) { 7 | blcok("hello") 8 | } 9 | } 10 | 11 | fun main(args: Array) { 12 | var demo = TestChannel() 13 | demo.test { 14 | 13 15 | } 16 | Thread.sleep(1000000) 17 | } -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/classobject/ConTest.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.classobject 2 | 3 | import com.fish.kotlindemo.varclass.name 4 | 5 | //构造函数测试 6 | //主构造函数 7 | class ConTest constructor(name: String, age: Int) { 8 | var studentName: String? = null 9 | var studentAge: Int = 0 10 | var studentScore: Float = 0.0f 11 | 12 | //初始化 13 | init { 14 | studentName = name 15 | studentAge = age 16 | println("studentName:$studentName") 17 | } 18 | //次构造函数 19 | constructor(name: String, age: Int, score: Float) : this(name, age) { 20 | studentScore = score 21 | println("studentScore:$studentScore") 22 | } 23 | } -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/classobject/ConTest1.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.classobject 2 | 3 | class ConTest1 constructor(var name: String, var age: Int) { 4 | var studentScore: Float = 0.0f 5 | 6 | //次构造函数 7 | constructor(name: String, age: Int, score: Float) : this(name, age) { 8 | studentScore = score 9 | println("studentScore:$studentScore") 10 | } 11 | } 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/classobject/JavaConTest.java: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.classobject; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | 5 | import kotlin.jvm.internal.Intrinsics; 6 | 7 | public class JavaConTest { 8 | private String name; 9 | private int age; 10 | private float score; 11 | 12 | //构造函数1 13 | public JavaConTest(String name, int age) { 14 | this.name = name; 15 | this.age = age; 16 | } 17 | //构造函数2 18 | public JavaConTest(String name, int age, float score) { 19 | this(name, age); 20 | this.score = score; 21 | } 22 | } -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/classobject/JavaParent.java: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.classobject; 2 | 3 | //基类 4 | public class JavaParent { 5 | public String name; 6 | 7 | public void setName(String name) { 8 | this.name = name; 9 | } 10 | } 11 | 12 | class JavaSon extends JavaParent { 13 | //重写属性 14 | public String name; 15 | 16 | //重写方法 17 | @Override 18 | public void setName(String name) { 19 | super.setName(name); 20 | System.out.println("name:" + this.name); 21 | } 22 | } 23 | 24 | interface JavaInter { 25 | void printInter(); 26 | } 27 | 28 | class JavaClass implements JavaInter { 29 | @Override 30 | public void printInter() { 31 | } 32 | } 33 | 34 | class Outer { 35 | private String name; 36 | //成员方法 37 | private void printName() { 38 | System.out.println("name:" + name); 39 | } 40 | 41 | private static String staticName; 42 | static void printStaticName() { 43 | } 44 | 45 | //非静态内部类 46 | class Inner { 47 | public void testInner() { 48 | //访问外部类方法 49 | printName(); 50 | //访问外部类属性 51 | name = "fish"; 52 | } 53 | } 54 | 55 | //静态内部类 56 | static class StaticInner { 57 | public void testInner() { 58 | //访问静态方法 59 | printStaticName(); 60 | //访问静态属性 61 | staticName = "fish"; 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/classobject/KotlinInter.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.classobject 2 | 3 | interface KotlinInterA { 4 | fun test() { 5 | println("interface A") 6 | } 7 | } 8 | interface KotlinInterB { 9 | fun test() { 10 | println("interface B") 11 | } 12 | } 13 | class TestInter() : KotlinInterA, KotlinInterB { 14 | override fun test() { 15 | //选择调用父类函数 16 | super.test() 17 | super.test() 18 | } 19 | } -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/classobject/KtOuter.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.classobject 2 | 3 | private val staticName: String? = null 4 | fun printStaticName() {} 5 | 6 | class KtOuter { 7 | private var name: String? = null 8 | //成员方法 9 | private fun printName() { 10 | println("name:$name") 11 | } 12 | 13 | //嵌套类 14 | class Inner { 15 | fun testInner() { 16 | //访问全局函数 17 | printStaticName() 18 | } 19 | } 20 | 21 | //内部类 22 | inner class RealInner { 23 | fun testInner() { 24 | //访问外部类函数和属性 25 | printName() 26 | name = "fish" 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/classobject/KtParent.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.classobject 2 | 3 | //基类 4 | open class KtParent(age: Int) { 5 | open var name: String? = null 6 | 7 | open fun printName() { 8 | println("name:$name") 9 | } 10 | } 11 | 12 | class KtSon constructor(age: Int) : KtParent(age) { 13 | override var name: String? = null 14 | 15 | override fun printName() { 16 | super.printName() 17 | println("in KtSon") 18 | } 19 | } 20 | 21 | interface KtInter { 22 | fun printInter(); 23 | } 24 | 25 | class KotlinClass : KtInter { 26 | override fun printInter() { 27 | } 28 | } 29 | 30 | class KotlinClassInter : KtInter, KtParent(18) { 31 | override fun printInter() { 32 | TODO("Not yet implemented") 33 | } 34 | } -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/classobject/Start.java: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.classobject; 2 | 3 | class Start { 4 | private void test() { 5 | //构造非静态内部类 6 | Outer.Inner inner = new Outer().new Inner(); 7 | inner.testInner(); 8 | 9 | //构造静态内部类 10 | Outer.StaticInner staticInner = new Outer.StaticInner(); 11 | staticInner.testInner(); 12 | } 13 | } -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/classobject/Start.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.classobject 2 | 3 | fun main(array : Array) { 4 | // //错误 5 | // var javaContest = JavaConTest(); 6 | // //正确 7 | // var javaContest = JavaConTest("fish", 18) 8 | 9 | var conTest = ConTest("fish", 18) 10 | println("name:${conTest.studentName}") 11 | 12 | //次构造函数调用 13 | var conTest2 = ConTest("fish", 18, 88f) 14 | 15 | //主构造函数声明成员变量 16 | var conTest1 = ConTest1("fish", 18) 17 | println("name:${conTest1.name} age:${conTest1.age}") 18 | 19 | //嵌套类构造 20 | var inner = KtOuter.Inner() 21 | inner.testInner() 22 | 23 | //内部类构造 24 | var realInner = KtOuter().RealInner() 25 | realInner.testInner() 26 | 27 | var testInter = TestInter() 28 | testInter.test() 29 | } -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/common/CommonDemo.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.common 2 | 3 | import com.fish.kotlindemo.cancelexception.CancelDemo 4 | import kotlinx.coroutines.* 5 | 6 | class CommonDemo { 7 | fun testBlock() { 8 | println("before runBlocking thread:${Thread.currentThread()}") 9 | //① 10 | runBlocking() { 11 | 12 | println("I'm runBlocking start thread:${Thread.currentThread()}") 13 | Thread.sleep(2000) 14 | println("I'm runBlocking end") 15 | } 16 | //② 17 | println("after runBlocking:${Thread.currentThread()}") 18 | } 19 | 20 | fun testBlock2() { 21 | var name = runBlocking { 22 | "fish" 23 | } 24 | println("name $name") 25 | } 26 | 27 | fun testBlock3() { 28 | println("before runBlocking thread:${Thread.currentThread()}") 29 | //① 30 | runBlocking(Dispatchers.IO) { 31 | println("I'm runBlocking start thread:${Thread.currentThread()}") 32 | Thread.sleep(2000) 33 | println("I'm runBlocking end") 34 | } 35 | //② 36 | println("after runBlocking:${Thread.currentThread()}") 37 | } 38 | 39 | fun testLaunch() { 40 | var job = GlobalScope.launch { 41 | 42 | println("hello job1 start")//① 43 | Thread.sleep(2000) 44 | println("hello job1 end")//② 45 | 46 | } 47 | println("continue...")//③ 48 | } 49 | 50 | fun testLaunch2() { 51 | runBlocking { 52 | var job = GlobalScope.launch { 53 | 54 | println("hello job1 start")//① 55 | Thread.sleep(10000) 56 | println("hello job1 end")//② 57 | } 58 | //等待协程执行完成 59 | job.join() 60 | 61 | println("continue...")//③ 62 | 63 | } 64 | } 65 | 66 | fun testAsync() { 67 | runBlocking { 68 | //启动协程 69 | var job = GlobalScope.async { 70 | 71 | println("job1 start") 72 | Thread.sleep(10000) 73 | //返回值 74 | "fish" 75 | } 76 | //等待协程执行结束,并返回协程结果 77 | var result = job.await() 78 | println("result:$result") 79 | } 80 | } 81 | 82 | fun testAsyncEx() { 83 | runBlocking { 84 | //启动协程 85 | var job = GlobalScope.async { 86 | 87 | println("job1 start") 88 | Thread.sleep(5000) 89 | //返回值 90 | 1/0 91 | } 92 | //等待协程执行结束,并返回协程结果 93 | var result = job.await() 94 | println("result:$result") 95 | } 96 | } 97 | 98 | fun testDelay() { 99 | GlobalScope.launch { 100 | println("before getName") 101 | var name = getUserName() 102 | println("after getName name:$name") 103 | } 104 | } 105 | 106 | suspend fun getUserName():String { 107 | return withContext(Dispatchers.IO) { 108 | //模拟网络获取 109 | Thread.sleep(2000) 110 | "fish" 111 | } 112 | } 113 | 114 | fun testDelay2() { 115 | GlobalScope.launch { 116 | 117 | println("before delay") 118 | //协程挂起20s 119 | delay(20000) 120 | 121 | println("after delay") 122 | } 123 | } 124 | } 125 | 126 | fun main(args: Array) { 127 | var demo = CommonDemo() 128 | demo.testDelay2() 129 | Thread.sleep(1000000) 130 | } -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/common/Test.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.common 2 | 3 | import kotlinx.coroutines.* 4 | import kotlin.contracts.InvocationKind 5 | import kotlin.contracts.contract 6 | import kotlin.coroutines.ContinuationInterceptor 7 | import kotlin.coroutines.CoroutineContext 8 | import kotlin.coroutines.EmptyCoroutineContext 9 | import kotlin.coroutines.coroutineContext 10 | 11 | class Test { 12 | } -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/coroutine/CoroutineJJ.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.coroutine 2 | 3 | import kotlin.concurrent.thread 4 | import kotlin.coroutines.Continuation 5 | import kotlin.coroutines.intrinsics.suspendCoroutineUninterceptedOrReturn 6 | import kotlin.coroutines.suspendCoroutine 7 | import kotlin.math.log 8 | 9 | class CoroutineJJ { 10 | fun test1(block:(Int)->String) { 11 | test{ 12 | c:Int -> 13 | "" 14 | } 15 | 16 | } 17 | 18 | fun test3(block: (Continuation) -> Any?) { 19 | 20 | } 21 | 22 | fun test(block: (Int) -> String) { 23 | block.invoke(3) 24 | block(3) 25 | 26 | suspend { 27 | 28 | } 29 | } 30 | 31 | } -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/coroutine/Me.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.coroutine 2 | 3 | import kotlinx.coroutines.Dispatchers 4 | import kotlinx.coroutines.coroutineScope 5 | import kotlinx.coroutines.withContext 6 | import kotlin.concurrent.thread 7 | import kotlin.coroutines.* 8 | 9 | 10 | fun launchMee(block: suspend () -> T) { 11 | var coroutine = block.createCoroutine(object : Continuation { 12 | override val context: CoroutineContext 13 | get() = EmptyCoroutineContext 14 | 15 | override fun resumeWith(result: Result) { 16 | println("result:$result") 17 | } 18 | }) 19 | coroutine.resume(Unit); 20 | } 21 | 22 | suspend fun loadDataFuck1(): String { 23 | var tt = suspendCoroutine { continuation -> 24 | thread { 25 | Thread.sleep(1000) 26 | continuation.resume("ok3333") 27 | } 28 | // Thread.sleep(1000) 29 | // continuation.resume("ok3333") 30 | println("after thread2:${Thread.currentThread()}") 31 | } 32 | println("switch tt") 33 | return tt 34 | } 35 | 36 | suspend fun loadMe() : String { 37 | return withContext(Dispatchers.IO) { 38 | println("hello world") 39 | "fish" 40 | } 41 | } 42 | 43 | fun main(args: Array) { 44 | println("1") 45 | launchMee { 46 | println("before fuck") 47 | var result = loadDataFuck1() 48 | println("after fuck: $result") 49 | } 50 | // 51 | // launchMee { 52 | // var jj = loadMe() 53 | // println("jj $jj") 54 | // } 55 | println("2") 56 | 57 | Thread.sleep(200000) 58 | } -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/coroutine/TestCoroutine.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.coroutine 2 | 3 | import android.os.Looper 4 | import com.fish.kotlindemo.funclass.testUpFun1 5 | import com.fish.kotlindemo.varclass.name 6 | import com.fish.kotlindemo.varclass.test 7 | import kotlinx.coroutines.* 8 | import kotlinx.coroutines.intrinsics.startCoroutineCancellable 9 | import kotlin.concurrent.thread 10 | import kotlin.coroutines.* 11 | 12 | class TestCoroutine { 13 | fun test() { 14 | println("start block") 15 | runBlocking { 16 | // delay(10000) 17 | println("blocking") 18 | // test1() 19 | var defer = async { 20 | println("jj") 21 | } 22 | //┳┏②③④⑶⒔⑴⑴⑴⑴22②②⑵⑵⑵🀄︎ 23 | defer.await() 24 | defer.cancel() 25 | println("jj me") 26 | println("after") 27 | } 28 | println("end bock") 29 | thread { 30 | Thread.sleep(1000000) 31 | } 32 | } 33 | 34 | fun test1() { 35 | println("launch start:${Thread.currentThread()}") 36 | var job = GlobalScope.launch(Dispatchers.IO) { 37 | println("launching before :${Thread.currentThread()}") 38 | withContext(Dispatchers.Default) { 39 | println("with context: : ${Thread.currentThread()}") 40 | withContext(Dispatchers.Default) { 41 | println("with context2: : ${Thread.currentThread()}") 42 | withContext(Dispatchers.Default) { 43 | println("with context3: : ${Thread.currentThread()}") 44 | withContext(Dispatchers.Default) { 45 | println("with context4: : ${Thread.currentThread()}") 46 | withContext(Dispatchers.Default) { 47 | println("with context5: : ${Thread.currentThread()}") 48 | withContext(Dispatchers.Default) { 49 | println("with context6: : ${Thread.currentThread()}") 50 | withContext(Dispatchers.Default) { 51 | println("with context7: : ${Thread.currentThread()}") 52 | } 53 | } 54 | } 55 | } 56 | } 57 | } 58 | } 59 | 60 | println("launching after:${Thread.currentThread()}") 61 | } 62 | println("launch end ${Thread.currentThread()}") 63 | thread { 64 | Thread.sleep(1000000) 65 | } 66 | } 67 | } 68 | 69 | fun test(block: (Int) -> String) { 70 | block.invoke(3) 71 | } 72 | 73 | fun test2() { 74 | GlobalScope.launch() { 75 | fuck() 76 | println("${Thread.currentThread()}") 77 | } 78 | 79 | Thread.sleep(100000) 80 | } 81 | 82 | fun fuck() { 83 | println("fuck begin") 84 | Thread.sleep(1000) 85 | println("fuck end") 86 | } 87 | 88 | fun launchMe(block: suspend () -> T) { 89 | var coroutine = block.createCoroutine(object : Continuation { 90 | override val context: CoroutineContext 91 | get() = EmptyCoroutineContext 92 | 93 | override fun resumeWith(result: Result) { 94 | println("result:$result") 95 | } 96 | }) 97 | coroutine.resume(Unit) 98 | } 99 | 100 | suspend fun loadDataFuck():String { 101 | var tt = suspendCoroutine { continuation -> 102 | // thread { 103 | // println("start thread:${Thread.currentThread()}") 104 | // Thread.sleep(2000) 105 | // println("after thread") 106 | // continuation.resume("ok3333") 107 | // } 108 | continuation.resume("ok3333") 109 | println("after thread2:${Thread.currentThread()}") 110 | } 111 | 112 | return tt 113 | } 114 | 115 | suspend inline fun loadData2() { 116 | thread { 117 | 118 | } 119 | name 120 | } 121 | 122 | fun test3() { 123 | GlobalScope.launch(Dispatchers.Default) { 124 | println("delay before ${Thread.currentThread()}") 125 | delay(2000) 126 | println("delay after ${Thread.currentThread()}") 127 | } 128 | // 129 | Thread.sleep(300) 130 | GlobalScope.launch(Dispatchers.Default) { 131 | println("delay before2 ${Thread.currentThread()}") 132 | while (true) { 133 | 134 | } 135 | } 136 | 137 | GlobalScope.launch(Dispatchers.Default) { 138 | println("delay before3 ${Thread.currentThread()}") 139 | while (true) { 140 | 141 | } 142 | } 143 | 144 | // GlobalScope.launch(Dispatchers.IO) { 145 | // println("delay before1 ${Thread.currentThread()}") 146 | // delay(300000) 147 | // println("delay after1 ${Thread.currentThread()}") 148 | // } 149 | // 150 | // GlobalScope.launch(Dispatchers.Default) { 151 | // println("delay before2 ${Thread.currentThread()}") 152 | // delay(3000000) 153 | // println("delay after2 ${Thread.currentThread()}") 154 | // } 155 | } 156 | 157 | fun test4() { 158 | GlobalScope.launch { 159 | var jj = getData("flush") 160 | println("jj $jj") 161 | } 162 | } 163 | 164 | suspend fun getData(url: String): String = withContext(Dispatchers.IO) { 165 | println("url:$url") 166 | delay(1000) 167 | "jjj" 168 | } 169 | 170 | 171 | fun main(args: Array) { 172 | var testCoroutine = TestCoroutine() 173 | // testCoroutine.test() 174 | // testCoroutine.test1() 175 | 176 | //// test() 177 | // test4() 178 | // test2() 179 | // test3() 180 | 181 | launchMe { 182 | println("before suspend") 183 | var tt = loadDataFuck() 184 | println("after suspend tt:$tt") 185 | } 186 | // 187 | // var coroutineJJ = CoroutineJJ() 188 | // coroutineJJ.test2() 189 | 190 | thread { 191 | Thread.sleep(1000000) 192 | } 193 | 194 | } 195 | 196 | 197 | -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/coroutine/TestJava.java: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.coroutine; 2 | 3 | import com.fish.kotlindemo.coroutinesuspend.CoroutineSuspendKt; 4 | 5 | class TestJava { 6 | public static void main(String args[]) { 7 | TestJava testJava = new TestJava(); 8 | testJava.stt(); 9 | } 10 | 11 | private void test() { 12 | CoroutineJJ coroutineJJ = new CoroutineJJ(); 13 | // coroutineJJ.test2(new Continuation() { 14 | // @NotNull 15 | // @Override 16 | // public CoroutineContext getContext() { 17 | // return null; 18 | // } 19 | // 20 | // @Override 21 | // public void resumeWith(@NotNull Object o) { 22 | // 23 | // } 24 | // }); 25 | } 26 | 27 | private void stt() { 28 | TestJava tt; 29 | lable: 30 | { 31 | int a = 5; 32 | tt = new TestJava(); 33 | } 34 | System.out.println("before"); 35 | tt.test(); 36 | System.out.println("after"); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/coroutinebus/Bus.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.coroutinebus 2 | 3 | import kotlinx.coroutines.Dispatchers 4 | import kotlinx.coroutines.GlobalScope 5 | import kotlinx.coroutines.launch 6 | import kotlinx.coroutines.withContext 7 | 8 | class Bus { 9 | 10 | } 11 | 12 | fun drive() { 13 | println("我坐车,我快乐") 14 | //车要停一会 15 | Thread.sleep(3000) 16 | println("车继续开") 17 | } 18 | 19 | 20 | 21 | fun drive2() { 22 | GlobalScope.launch(Dispatchers.Main) { 23 | println("我坐车,我快乐")//① 24 | withContext(Dispatchers.IO) { 25 | println("导游去订酒店")//② 26 | } 27 | println("车继续开,剩下团友在车上")//③④ 28 | } 29 | } 30 | 31 | fun drive3() { 32 | GlobalScope.launch(Dispatchers.IO) { 33 | println("我坐车,我快乐")//① 34 | withContext(Dispatchers.Default) {//② 35 | println("导游去订酒店")//③ 36 | } 37 | println("车继续开,剩下团友在车上")//④ 38 | } 39 | } -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/coroutinedispatch/CoroutineDispatch.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.coroutinedispatch 2 | 3 | import android.content.Context 4 | import android.os.Handler 5 | import android.os.Looper 6 | import android.os.Message 7 | import android.widget.Toast 8 | import com.fish.kotlindemo.coroutineraw.launchFish 9 | import kotlinx.coroutines.* 10 | import kotlinx.coroutines.launch 11 | import kotlin.concurrent.thread 12 | import kotlin.coroutines.* 13 | 14 | //协程分发 15 | class CoroutineDispatch(val context: Context) { 16 | 17 | fun startCoroutine() { 18 | GlobalScope.launch(Dispatchers.Main) { 19 | //协程体 20 | } 21 | } 22 | 23 | private inner class MyHandler : Handler(Looper.getMainLooper()) { 24 | override fun handleMessage(msg: Message) { 25 | //主线程弹出toast 26 | Toast.makeText(context, msg.obj.toString(), Toast.LENGTH_SHORT).show() 27 | } 28 | } 29 | 30 | //获取学生信息 31 | fun showStuInfo() { 32 | thread { 33 | //模拟网络请求 34 | Thread.sleep(3000) 35 | var handler = MyHandler() 36 | var msg = Message.obtain() 37 | msg.obj = "我是小鱼人" 38 | //发送到主线程执行 39 | handler.sendMessage(msg) 40 | } 41 | } 42 | 43 | fun showStuInfoV2() { 44 | GlobalScope.launch(Dispatchers.Main) { 45 | var stuInfo = withContext(Dispatchers.IO) { 46 | //模拟网络请求 47 | Thread.sleep(3000) 48 | "我是小鱼人" 49 | } 50 | 51 | Toast.makeText(context, stuInfo, Toast.LENGTH_SHORT).show() 52 | } 53 | } 54 | 55 | fun switchThread() { 56 | println("我在某个线程,准备切换到主线程") 57 | GlobalScope.launch(Dispatchers.Main) { 58 | println("我在主线程,准备切换到子线程") 59 | withContext(Dispatchers.IO) { 60 | println("我在子线程,准备切换到子线程") 61 | withContext(Dispatchers.Default) { 62 | println("我在子线程,准备切换到主线程") 63 | withContext(Dispatchers.Main) { 64 | println("我在主线程") 65 | } 66 | } 67 | } 68 | } 69 | } 70 | 71 | fun launch1() { 72 | GlobalScope.launch(Dispatchers.Main) { 73 | 74 | println("我在主线程执行") 75 | 76 | } 77 | } 78 | 79 | fun launch2() { 80 | GlobalScope.launch(Dispatchers.Main) { 81 | 82 | println("我在主线程执行") 83 | 84 | withContext(Dispatchers.IO) { 85 | println("我在子线程执行") 86 | } 87 | 88 | println("我在哪个线程执行?")//③ 89 | } 90 | } 91 | 92 | fun launch3() { 93 | GlobalScope.launch(Dispatchers.IO) { 94 | withContext(Dispatchers.Default) { 95 | println("我在哪个线程运行") 96 | delay(2000) 97 | println("delay 后我在哪个线程运行") 98 | } 99 | println("我又在哪个线程运行") 100 | } 101 | } 102 | } 103 | 104 | fun main(array: Array) { 105 | launchFish { 106 | println("I am coroutine") 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/coroutinedispatch/DebugCoroutine.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.coroutinedispatch 2 | 3 | 4 | 5 | class DebugCoroutine { 6 | } 7 | -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/coroutineraw/CoroutineRaw.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.coroutineraw 2 | 3 | import kotlinx.coroutines.GlobalScope 4 | import kotlinx.coroutines.intrinsics.startCoroutineCancellable 5 | import kotlinx.coroutines.launch 6 | import kotlin.concurrent.thread 7 | import kotlin.coroutines.* 8 | 9 | fun launchEmpty(block: () -> Unit) { 10 | block()//与block.invoke()等价 11 | } 12 | 13 | fun launchEmpty1(block: () -> Unit) { 14 | } 15 | 16 | fun launchFish(block: suspend () -> T) { 17 | //创建协程,返回值为SafeContinuation(实现了Continuation 接口) 18 | //入参为Continuation 类型,参数名为completion,顾名思义就是 19 | //协程结束后(正常返回&抛出异常)将会调用它。 20 | var coroutine = block.createCoroutine(object : Continuation { 21 | override val context: CoroutineContext 22 | get() = EmptyCoroutineContext 23 | 24 | //协程结束后调用该函数 25 | override fun resumeWith(result: Result) { 26 | println("result:$result") 27 | } 28 | }) 29 | //开启协程 30 | coroutine.resume(Unit) 31 | } 32 | 33 | fun main(array: Array) { 34 | launchFish { 35 | println("I am coroutine") 36 | } 37 | } -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/coroutineraw/StartLaunch.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.coroutineraw 2 | 3 | import kotlinx.coroutines.Dispatchers 4 | import kotlinx.coroutines.GlobalScope 5 | import kotlinx.coroutines.launch 6 | 7 | fun startLaunch() { 8 | GlobalScope.launch(Dispatchers.Main) { 9 | println("launching...") 10 | } 11 | } -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/coroutinestory/JavaStudent.java: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.coroutinestory; 2 | 3 | import java.util.concurrent.Callable; 4 | import java.util.concurrent.ExecutionException; 5 | import java.util.concurrent.FutureTask; 6 | 7 | public class JavaStudent { 8 | 9 | Callable callable = new Callable() { 10 | @Override 11 | public StudentInfo call() throws Exception { 12 | try { 13 | //模拟耗时操作 14 | Thread.sleep(2000); 15 | } catch (InterruptedException e) { 16 | e.printStackTrace(); 17 | } 18 | return new StudentInfo(); 19 | } 20 | }; 21 | 22 | public StudentInfo getStuInfo(long stuId) { 23 | //定义任务 24 | FutureTask futureTask = new FutureTask<>(callable); 25 | //开启线程,执行任务 26 | new Thread(futureTask).start(); 27 | try { 28 | //阻塞获取结果 29 | StudentInfo studentInfo = futureTask.get(); 30 | return studentInfo; 31 | } catch (ExecutionException e) { 32 | e.printStackTrace(); 33 | } catch (InterruptedException e) { 34 | e.printStackTrace(); 35 | } 36 | return null; 37 | } 38 | 39 | //从后台获取信息 40 | public StudentInfo getWithoutThread(long stuId) { 41 | try { 42 | //模拟耗时操作 43 | Thread.sleep(2000); 44 | } catch (InterruptedException e) { 45 | e.printStackTrace(); 46 | } 47 | return new StudentInfo(); 48 | } 49 | 50 | //回调接口 51 | public interface Callback { 52 | void onCallback(StudentInfo studentInfo); 53 | //新增老师回调接口 54 | default void onCallback(TeacherInfo teacherInfo){} 55 | } 56 | 57 | //异步调用 58 | public void getStuInfoAsync(long stuId, Callback callback) { 59 | new Thread(() -> { 60 | try { 61 | //模拟耗时操作 62 | Thread.sleep(2000); 63 | } catch (InterruptedException e) { 64 | e.printStackTrace(); 65 | } 66 | 67 | StudentInfo studentInfo = new StudentInfo(); 68 | if (callback != null) { 69 | callback.onCallback(studentInfo); 70 | } 71 | }).start(); 72 | } 73 | 74 | //异步调用 75 | public void getTeachInfoAsync(long stuId, Callback callback) { 76 | //先获取学生信息 77 | getStuInfoAsync(stuId, new Callback() { 78 | @Override 79 | public void onCallback(StudentInfo studentInfo) { 80 | //获取学生信息后,取出关联的语文老师id,获取老师信息 81 | new Thread(() -> { 82 | try { 83 | //模拟耗时操作 84 | Thread.sleep(2000); 85 | } catch (InterruptedException e) { 86 | e.printStackTrace(); 87 | } 88 | 89 | TeacherInfo teacherInfo = new TeacherInfo(); 90 | if (callback != null) { 91 | //老师信息获取成功 92 | callback.onCallback(teacherInfo); 93 | } 94 | }).start(); 95 | } 96 | }); 97 | } 98 | 99 | private void startNewThread() { 100 | new Thread(()->{ 101 | //线程体 102 | //我在子线程执行... 103 | }).start(); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/coroutinestory/StudentCoroutine.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.coroutinestory 2 | 3 | import android.app.Activity 4 | import android.widget.Toast 5 | import kotlinx.coroutines.Dispatchers 6 | import kotlinx.coroutines.GlobalScope 7 | import kotlinx.coroutines.launch 8 | import kotlinx.coroutines.withContext 9 | 10 | class StudentCoroutine { 11 | private val FIXED_TEACHER_ID = 888 12 | fun getTeachInfo(act: Activity, stuId: Long) { 13 | GlobalScope.launch(Dispatchers.Main) { 14 | 15 | var studentInfo: StudentInfo 16 | var teacherInfo: TeacherInfo? = null 17 | 18 | //先获取学生信息 19 | withContext(Dispatchers.IO) { 20 | //模拟网络获取 21 | Thread.sleep(2000) 22 | studentInfo = StudentInfo() 23 | } 24 | //再获取教师信息 25 | withContext(Dispatchers.IO) { 26 | if (studentInfo.lanTechId.toInt() === FIXED_TEACHER_ID) { 27 | //模拟网络获取 28 | Thread.sleep(2000) 29 | teacherInfo = TeacherInfo() 30 | } 31 | } 32 | //更新UI 33 | Toast.makeText(act, "teacher name:${teacherInfo?.name}", Toast.LENGTH_LONG).show() 34 | } 35 | 36 | Toast.makeText(act, "主线程还在跑...", Toast.LENGTH_LONG).show() 37 | } 38 | } 39 | 40 | -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/coroutinestory/StudentInfo.java: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.coroutinestory; 2 | 3 | public class StudentInfo { 4 | //学生id 5 | private long stuId = 999; 6 | private String name = "fish"; 7 | private int age = 18; 8 | 9 | //关联的语文老师 id 10 | private long lanTechId = 888; 11 | 12 | public long getStuId() { 13 | return stuId; 14 | } 15 | 16 | public void setStuId(long stuId) { 17 | this.stuId = stuId; 18 | } 19 | 20 | public String getName() { 21 | return name; 22 | } 23 | 24 | public void setName(String name) { 25 | this.name = name; 26 | } 27 | 28 | public int getAge() { 29 | return age; 30 | } 31 | 32 | public void setAge(int age) { 33 | this.age = age; 34 | } 35 | 36 | public long getLanTechId() { 37 | return lanTechId; 38 | } 39 | 40 | public void setLanTechId(long lanTechId) { 41 | this.lanTechId = lanTechId; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/coroutinestory/TeacherInfo.java: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.coroutinestory; 2 | 3 | public class TeacherInfo { 4 | //老师id 5 | private long lanTechId = 888; 6 | private String name = "fish's teacher"; 7 | private int age = 38; 8 | 9 | public long getLanTechId() { 10 | return lanTechId; 11 | } 12 | 13 | public void setLanTechId(long lanTechId) { 14 | this.lanTechId = lanTechId; 15 | } 16 | 17 | public String getName() { 18 | return name; 19 | } 20 | 21 | public void setName(String name) { 22 | this.name = name; 23 | } 24 | 25 | public int getAge() { 26 | return age; 27 | } 28 | 29 | public void setAge(int age) { 30 | this.age = age; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/coroutinesuspend/CoroutineGraph.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.coroutinesuspend 2 | 3 | import kotlinx.coroutines.Dispatchers 4 | import kotlinx.coroutines.GlobalScope 5 | import kotlinx.coroutines.launch 6 | import kotlinx.coroutines.withContext 7 | 8 | class CoroutineGraph { 9 | } 10 | 11 | fun startLaunch() { 12 | GlobalScope.launch { 13 | println("parent coroutine running") 14 | 15 | getStuInfoV1() 16 | 17 | println("after suspend") 18 | } 19 | } 20 | 21 | suspend fun getStuInfoV1() { 22 | withContext(Dispatchers.IO) { 23 | println("son coroutine running") 24 | } 25 | } -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/coroutinesuspend/CoroutineSuspend.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.coroutinesuspend 2 | 3 | import android.util.Log 4 | import com.fish.kotlindemo.coroutinestory.StudentInfo 5 | import kotlinx.coroutines.* 6 | import kotlin.concurrent.thread 7 | import kotlin.coroutines.* 8 | class CoroutineSuspend { 9 | } 10 | 11 | fun main(array: Array) { 12 | // GlobalScope.launch() { 13 | // println("before suspend") 14 | // //挂起函数 15 | // var studentInfo = getStuInfo2() //① 16 | // //挂起函数执行返回 17 | // println("after suspend student name:${studentInfo?.name}")//② 18 | // } 19 | 20 | launchFish { 21 | println("before suspend") 22 | var studentInfo = getStuInfo3() 23 | //挂起函数执行返回 24 | println("after suspend student name:${studentInfo?.name}") 25 | } 26 | 27 | //防止进程退出 28 | Thread.sleep(1000000) 29 | } 30 | 31 | suspend fun getStuInfo() { 32 | delay(5000) 33 | Log.d("fish", "after delay thread:${Thread.currentThread()}") 34 | } 35 | 36 | suspend fun getStuInfo1() { 37 | thread { 38 | Thread.sleep(2000) 39 | println("after sleep") 40 | } 41 | println("after thread") 42 | } 43 | 44 | suspend fun getStuInfo2(): StudentInfo { 45 | return withContext(Dispatchers.IO) { 46 | println("start get studentInfo") 47 | //模拟耗时操作 48 | Thread.sleep(3000) 49 | println("get studentInfo successful") 50 | //返回学生信息 51 | StudentInfo() 52 | } 53 | } 54 | 55 | suspend fun getStuInfo3(): StudentInfo { 56 | return suspendCoroutine { 57 | thread { 58 | //开启线程执行耗时任务 59 | Thread.sleep(3000) 60 | var studentInfo = StudentInfo() 61 | println("resume coroutine") 62 | //恢复协程,it指代 Continuation 63 | it.resumeWith(Result.success(studentInfo)) 64 | } 65 | println("suspendCoroutine end") 66 | } 67 | } 68 | 69 | fun launchFish(block: suspend () -> T) { 70 | //创建协程,返回值为SafeContinuation(实现了Continuation 接口) 71 | //入参为Continuation 类型,参数名为completion,顾名思义就是 72 | //协程结束后(正常返回&抛出异常)将会调用它。 73 | var coroutine = block.createCoroutine(object : Continuation { 74 | override val context: CoroutineContext 75 | get() = EmptyCoroutineContext 76 | 77 | //协程结束后调用该函数 78 | override fun resumeWith(result: Result) { 79 | println("result:$result") 80 | } 81 | }) 82 | //开启协程 83 | coroutine.resume(Unit) 84 | } -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/coroutinethreadpool/DebugPool.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.coroutinethreadpool 2 | 3 | 4 | class DebugPool { 5 | } 6 | -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/coroutinethreadpool/Pool.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.coroutinethreadpool 2 | 3 | import android.content.Context 4 | import android.widget.Toast 5 | import com.fish.kotlindemo.coroutineraw.launchFish 6 | import kotlinx.coroutines.* 7 | 8 | class Pool(val context: Context?) { 9 | fun showStuName() { 10 | GlobalScope.launch(Dispatchers.Main) { 11 | var stuInfo = withContext(Dispatchers.IO) { 12 | //模拟网络请求 13 | Thread.sleep(3000) 14 | "我是小鱼人" 15 | } 16 | //展示 17 | Toast.makeText(context, stuInfo, Toast.LENGTH_SHORT).show() 18 | } 19 | } 20 | 21 | fun dealCpuTask() { 22 | GlobalScope.launch(Dispatchers.Main) { 23 | //切换到子线程 24 | withContext(Dispatchers.Default) { 25 | var i = 0 26 | val count = 100000 27 | while(i < count) { 28 | Thread.sleep(1) 29 | } 30 | } 31 | } 32 | } 33 | 34 | fun launch() { 35 | GlobalScope.launch(Dispatchers.Default) { 36 | 37 | } 38 | } 39 | 40 | fun launchIO() { 41 | GlobalScope.launch(Dispatchers.IO) { 42 | println("") 43 | } 44 | } 45 | 46 | fun launch3() { 47 | GlobalScope.launch(Dispatchers.IO) { 48 | println("1>>>${Thread.currentThread()}") 49 | withContext(Dispatchers.Default) { 50 | println("2>>>${Thread.currentThread()}") 51 | delay(2000) 52 | println("3>>>${Thread.currentThread()}") 53 | } 54 | println("4>>>${Thread.currentThread()}") 55 | } 56 | } 57 | } 58 | 59 | fun main(array: Array) { 60 | var pool = Pool(null) 61 | pool.launchIO() 62 | 63 | Thread.sleep(300000) 64 | } 65 | 66 | -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/datastore/DataStoreActivity.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.datastore 2 | 3 | import android.os.Bundle 4 | import androidx.appcompat.app.AppCompatActivity 5 | import androidx.lifecycle.lifecycleScope 6 | import com.fish.kotlindemo.databinding.ActivityDatastoreBinding 7 | import kotlinx.coroutines.flow.MutableStateFlow 8 | import kotlinx.coroutines.launch 9 | 10 | class DataStoreActivity : AppCompatActivity() { 11 | 12 | private lateinit var binding: ActivityDatastoreBinding 13 | 14 | private var count = 0 15 | 16 | val state = MutableStateFlow(null) 17 | 18 | private val myDataStore by lazy { 19 | MyDataStore(this) 20 | } 21 | 22 | 23 | override fun onCreate(savedInstanceState: Bundle?) { 24 | super.onCreate(savedInstanceState) 25 | binding = ActivityDatastoreBinding.inflate(layoutInflater) 26 | setContentView(binding.root) 27 | 28 | binding.btnRead.setOnClickListener { 29 | lifecycleScope.launch { 30 | // myDataStore.getNameStringData { v1, v2 -> 31 | // Toast.makeText(this@DataStoreActivity, "key=$v1 value=$v2", Toast.LENGTH_SHORT) 32 | // .show() 33 | // } 34 | 35 | // myDataStore.queryDataV2() 36 | 37 | // state.collect { 38 | // println(it) 39 | // } 40 | 41 | myDataStore.getSP() 42 | myDataStore.observe() 43 | } 44 | } 45 | 46 | binding.btnWrite.setOnClickListener { 47 | lifecycleScope.launch { 48 | // myDataStore.putNameStringData("fish${count++}") 49 | // myDataStore.saveData() 50 | // myDataStore.saveData2() 51 | // 52 | // 53 | // GlobalScope.launch(Dispatchers.IO) { 54 | // myDataStore.saveData2() 55 | // } 56 | // 57 | // GlobalScope.launch(Dispatchers.Main) { 58 | // myDataStore.saveData2() 59 | // } 60 | myDataStore.saveSP() 61 | myDataStore.updateDataStore("fish", 100) 62 | } 63 | } 64 | // 65 | // GlobalScope.launch(Dispatchers.IO) { 66 | // myDataStore.queryDataV2() 67 | // } 68 | // 69 | // GlobalScope.launch(Dispatchers.Main) { 70 | // myDataStore.saveData2() 71 | // } 72 | // 73 | // lifecycleScope.launch { 74 | // MyDataStore(this@DataStoreActivity).saveData2() 75 | // } 76 | } 77 | } -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/datastore/LoginInfoSerializer.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.datastore 2 | 3 | import androidx.datastore.core.CorruptionException 4 | import androidx.datastore.core.Serializer 5 | import androidx.datastore.preferences.PreferencesMapCompat 6 | import androidx.datastore.preferences.PreferencesProto 7 | import androidx.datastore.preferences.core.* 8 | import com.fish.kotlindemo.test.LoginInfo 9 | import java.io.IOException 10 | import java.io.InputStream 11 | import java.io.OutputStream 12 | import kotlin.jvm.Throws 13 | 14 | object LoginInfoSerializer : Serializer { 15 | //默认值 16 | override val defaultValue: LoginInfo 17 | get() = LoginInfo.getDefaultInstance() 18 | 19 | //如何从文件里读取Protobuf内容 20 | override suspend fun readFrom(input: InputStream): LoginInfo { 21 | return LoginInfo.parseFrom(input) 22 | } 23 | 24 | //将Protobuf写入到文件 25 | override suspend fun writeTo(t: LoginInfo, output: OutputStream) { 26 | t.writeTo(output) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/datastore/MyDataStore.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.datastore 2 | 3 | import android.content.Context 4 | import android.content.SharedPreferences 5 | import androidx.core.content.edit 6 | import androidx.datastore.core.* 7 | import androidx.datastore.dataStore 8 | import androidx.datastore.preferences.core.* 9 | import androidx.datastore.preferences.preferencesDataStore 10 | import com.fish.kotlindemo.test.LoginInfo 11 | import com.fish.kotlindemo.varclass.myName 12 | import kotlinx.coroutines.flow.* 13 | import java.util.* 14 | 15 | class MyDataStore(val context: Context) { 16 | companion object { 17 | val Context.dataStore: DataStore by preferencesDataStore(MyDataStore.javaClass.name) 18 | 19 | val Context.dataProto: DataStore by dataStore( 20 | //文件名,存储在/data/data/包名/files/datastore下 21 | fileName = "login_info", 22 | //指定序列化器,负责将对象序列化/反序列化-到/从文件 23 | serializer = LoginInfoSerializer 24 | ) 25 | } 26 | 27 | private var sp: SharedPreferences? = null 28 | 29 | init { 30 | sp = context.getSharedPreferences("mysp", Context.MODE_PRIVATE) 31 | } 32 | 33 | // val myNameKey = stringPreferencesKey("name") 34 | // val myAgeKey = stringPreferencesKey("age") 35 | 36 | suspend fun getData() { 37 | context.dataStore.data.collect { 38 | it.asMap().forEach { 39 | val vaule = it.value as String 40 | } 41 | } 42 | } 43 | 44 | suspend fun updateDataStore(userName: String, userId:Long) { 45 | context.dataProto.updateData { loginInfo -> 46 | //loginInfo为生成的类的对象 47 | loginInfo.toBuilder() 48 | //给字段赋值 49 | .setUserName(userName) 50 | .setUserId(userId) 51 | //返回LoginInfo 52 | .build() 53 | } 54 | } 55 | 56 | suspend fun observe() { 57 | context.dataProto.data.map { 58 | //it 指代LoginInfo对象 59 | "${it.userId}==${it.userName}" 60 | }.collect { 61 | println("data:$it") 62 | } 63 | } 64 | 65 | fun saveSP() { 66 | sp?.edit { 67 | putString("name", "fish${Random().nextInt(10000)}") 68 | putInt("age", 19) 69 | } 70 | } 71 | 72 | fun getSP() { 73 | val name = sp?.getString("name", "test") 74 | val age = sp?.getString("age", "test") 75 | } 76 | 77 | suspend fun putNameStringData(name: String, age:Int) { 78 | context.dataStore.edit { 79 | it[myNameKey] = name 80 | it[myAgeKey] = age 81 | } 82 | } 83 | 84 | val myNameKey = stringPreferencesKey("name") 85 | val myAgeKey = intPreferencesKey("age") 86 | suspend fun saveData() { 87 | context.dataStore.edit { 88 | //给不同的key赋值 89 | it[myNameKey] = "fish" 90 | it[myAgeKey] = 14 91 | } 92 | } 93 | 94 | val myScoreKey = floatPreferencesKey("score") 95 | suspend fun queryDataV2() { 96 | context.dataStore.data.map { 97 | // val dd = it[myScoreKey] as String 98 | }.collect { 99 | println("$it") 100 | } 101 | } 102 | 103 | suspend fun saveData2() { 104 | context.dataStore.edit { 105 | //只修改分数 106 | it[myNameKey] = "${Random().nextInt(10000)}" 107 | } 108 | } 109 | 110 | suspend fun queryData() { 111 | context.dataStore.data.collect { 112 | it.asMap().forEach { 113 | println("${it.key.name}, ${it.value}") 114 | } 115 | } 116 | 117 | println("dataStore flow end") 118 | } 119 | 120 | suspend fun queryData2() { 121 | val flow = flow { 122 | emit("hello") 123 | } 124 | 125 | flow.collect { 126 | println(it) 127 | } 128 | 129 | println("normal flow end") 130 | } 131 | } -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/datastore/Test.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.datastore 2 | 3 | sealed class NewsIntents { 4 | object TopHeadlinesIntent : NewsIntents() 5 | } 6 | 7 | sealed class NewsStates { 8 | data class Success(val news: String) : NewsStates() 9 | data class Error(val errorMessage: String) : NewsStates() 10 | object Loading : NewsStates() 11 | } 12 | 13 | open class Stu { 14 | val name: String? = null 15 | val age: Int? = null 16 | fun jj() { 17 | } 18 | } 19 | 20 | class C { 21 | object jj : Stu() { 22 | } 23 | } 24 | 25 | // 私有函数,所以其返回类型是匿名对象类型 26 | private fun foo() = object { 27 | val x: String = "x" 28 | 29 | fun lishi() { 30 | 31 | } 32 | } 33 | 34 | // 公有函数,所以其返回类型是 Any 35 | fun publicFoo() = object { 36 | 37 | } 38 | 39 | fun ts() { 40 | var str : String? = null 41 | } -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/datastore/UserPreferencesSerializer.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.datastore 2 | 3 | import androidx.datastore.core.Serializer 4 | import com.fish.kotlindemo.test.UserPreferences 5 | import java.io.InputStream 6 | import java.io.OutputStream 7 | 8 | object UserPreferencesSerializer:Serializer { 9 | 10 | override val defaultValue: UserPreferences 11 | get() = UserPreferences.getDefaultInstance() 12 | override suspend fun readFrom(input: InputStream): UserPreferences { 13 | return UserPreferences.parseFrom(input) 14 | } 15 | 16 | override suspend fun writeTo(t: UserPreferences, output: OutputStream) { 17 | t.writeTo(output) 18 | } 19 | } -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/diffjava/Diff.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.diffjava 2 | 3 | import java.lang.Exception 4 | 5 | class Diff { 6 | fun getNum() = 3 7 | } 8 | 9 | fun test() { 10 | var list = arrayListOf("jj", "mme", "fuck") 11 | var result = list?.let { 12 | var result = false 13 | for (name in list) { 14 | if(name == "mme") { 15 | println("hello") 16 | result = true 17 | break 18 | } 19 | } 20 | result 21 | } 22 | println("wo haizai") 23 | } 24 | 25 | fun test2(diff: Diff?):Int? { 26 | return diff!!.getNum() 27 | } 28 | 29 | fun main(args : Array) { 30 | var result = test() 31 | println("result:$result") 32 | var diff :Diff? = null 33 | try { 34 | var jj = test2(diff) 35 | } catch (e : Exception) { 36 | println("ddd") 37 | } 38 | println("shit") 39 | } 40 | 41 | -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/flow/FlowBuffer.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.flow 2 | 3 | import kotlinx.coroutines.Dispatchers 4 | import kotlinx.coroutines.delay 5 | import kotlinx.coroutines.flow.buffer 6 | import kotlinx.coroutines.flow.collect 7 | import kotlinx.coroutines.flow.flow 8 | import kotlinx.coroutines.flow.flowOn 9 | import kotlinx.coroutines.runBlocking 10 | import kotlinx.coroutines.withContext 11 | import kotlin.concurrent.thread 12 | import kotlin.system.measureTimeMillis 13 | 14 | class FlowBuffer { 15 | fun testBuffer() { 16 | runBlocking { 17 | testBuffer4() 18 | } 19 | } 20 | suspend fun testBuffer1() { 21 | var flow = flow { 22 | //生产者 23 | (1..3).forEach { 24 | println("emit $it") 25 | emit(it) 26 | } 27 | } 28 | 29 | flow.collect { 30 | //消费者 31 | println("collect:$it") 32 | } 33 | } 34 | 35 | suspend fun testBuffer2() { 36 | var flow = flow { 37 | (1..3).forEach { 38 | println("emit $it") 39 | emit(it) 40 | } 41 | } 42 | 43 | var time = measureTimeMillis { 44 | flow.collect { 45 | println("collect:$it") 46 | } 47 | } 48 | println("use time:${time} ms") 49 | } 50 | 51 | suspend fun testBuffer3() { 52 | var flow = flow { 53 | (1..3).forEach { 54 | delay(1000) 55 | println("emit $it") 56 | emit(it) 57 | } 58 | } 59 | 60 | var time = measureTimeMillis { 61 | flow.collect { 62 | delay(2000) 63 | println("collect:$it") 64 | } 65 | } 66 | println("use time:${time} ms") 67 | } 68 | 69 | suspend fun testBuffer4() { 70 | var flow = flow { 71 | (1..3).forEach { 72 | delay(1000) 73 | println("emit $it in thread:${Thread.currentThread()}") 74 | emit(it) 75 | } 76 | }.flowOn(Dispatchers.IO) 77 | 78 | var time = measureTimeMillis { 79 | flow.collect { 80 | delay(2000) 81 | println("collect:$it in thread:${Thread.currentThread()}") 82 | } 83 | } 84 | println("use time:${time} ms") 85 | } 86 | 87 | suspend fun testBuffer5() { 88 | var flow = flow { 89 | (1..3).forEach { 90 | delay(1000) 91 | println("emit $it in thread:${Thread.currentThread()} ${System.currentTimeMillis()}") 92 | emit(it) 93 | } 94 | }.buffer(5) 95 | 96 | var time = measureTimeMillis { 97 | flow.collect { 98 | delay(2000) 99 | println("collect:$it in thread:${Thread.currentThread()} ${System.currentTimeMillis()}") 100 | } 101 | } 102 | println("use time:${time} ms") 103 | } 104 | 105 | suspend fun testBuffer6() { 106 | var flow = flow { 107 | (1..3).forEach { 108 | println("emit $it") 109 | emit(it) 110 | } 111 | } 112 | 113 | var time = measureTimeMillis { 114 | flow.collect { 115 | delay(2000) 116 | println("collect:$it") 117 | } 118 | } 119 | println("use time:${time} ms") 120 | } 121 | } 122 | 123 | fun main(args: Array) { 124 | var flowBuffer = FlowBuffer() 125 | flowBuffer.testBuffer() 126 | Thread.sleep(1000000) 127 | } -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/flow/FlowDemo.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.flow 2 | 3 | import kotlinx.coroutines.* 4 | import kotlinx.coroutines.flow.* 5 | import kotlin.coroutines.coroutineContext 6 | import kotlin.coroutines.resume 7 | import kotlin.coroutines.suspendCoroutine 8 | import kotlin.system.measureTimeMillis 9 | 10 | class FlowDemo() { 11 | fun test() { 12 | GlobalScope.launch(Dispatchers.Default) { 13 | testFlow6() 14 | } 15 | } 16 | 17 | fun testList() { 18 | //构造集合 19 | fun list(): List = listOf(1, 2, 3) 20 | list().forEach { 21 | //获取多个值 22 | println("value = $it") 23 | } 24 | } 25 | 26 | fun testSequence() { 27 | fun sequence(): Sequence = sequence { 28 | for (i in 1..3) { 29 | Thread.sleep(1000) 30 | yield(i) 31 | } 32 | } 33 | 34 | sequence().forEach { 35 | println("value = $it") 36 | } 37 | } 38 | 39 | suspend fun testListDelay() { 40 | suspend fun list(): List { 41 | delay(1000) 42 | return listOf(1, 2, 3) 43 | } 44 | 45 | list().forEach { 46 | println("value = $it") 47 | } 48 | } 49 | 50 | suspend fun testFlow1() { 51 | //生产者 52 | var flow = flow { 53 | println("emit data") 54 | emit(5) 55 | } 56 | 57 | //消费者 58 | flow.collect { 59 | println("value=$it") 60 | } 61 | } 62 | 63 | suspend fun testFlow2() { 64 | //生产者 65 | flow { 66 | println("emit data") 67 | emit(5) 68 | }.collect { 69 | println("value=$it") 70 | } 71 | } 72 | 73 | suspend fun testFlow3() { 74 | //生产者 75 | var flow = flow { 76 | for (i in 1..1000) { 77 | emit(i) 78 | } 79 | }.filter { it > 500 && it % 2 == 0 } 80 | .map { it - 500 } 81 | .catch { 82 | //异常处理 83 | } 84 | 85 | //消费者 86 | flow.collect { 87 | println("value=$it") 88 | } 89 | } 90 | 91 | suspend fun testFlow4() { 92 | //生产者 93 | var flow = flow { 94 | for (i in 1..1000) { 95 | delay(1000) 96 | emit(i) 97 | } 98 | }.flowOn(Dispatchers.IO)//切换到io线程执行 99 | 100 | //消费者 101 | flow.collect { 102 | delay(1000) 103 | println("value=$it") 104 | } 105 | } 106 | 107 | suspend fun testFlow5() { 108 | //生产者 109 | var flow = flow { 110 | println("111") 111 | for (i in 1..1000) { 112 | emit(i) 113 | } 114 | }.filter { 115 | println("222") 116 | it > 500 && it % 2 == 0 117 | }.map { 118 | println("333") 119 | it - 500 120 | }.catch { 121 | println("444") 122 | //异常处理 123 | } 124 | 125 | flow.collect { 126 | println("value:$it") 127 | } 128 | } 129 | 130 | suspend fun testFlow6() { 131 | //生产者 132 | var flow = flow { 133 | println("111") 134 | for (i in 1..2) { 135 | emit(i) 136 | } 137 | }.filter { 138 | println("222") 139 | true 140 | } 141 | 142 | flow.collect { 143 | println("value:$it") 144 | } 145 | } 146 | } 147 | 148 | fun main(args: Array) { 149 | var demo = FlowDemo() 150 | demo.test() 151 | Thread.sleep(1000000) 152 | } 153 | -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/flow/Test.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.flow 2 | 3 | 4 | class Test { 5 | } 6 | 7 | fun main(str: Array) { 8 | var i = 0 9 | var list = mutableListOf() 10 | while (i < 1000) { 11 | if (i > 500 && i % 2 == 0) 12 | list.add(i) 13 | i++ 14 | } 15 | } -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/flowoperand/LiveDataDemo.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.flowoperand 2 | 3 | import androidx.lifecycle.* 4 | import kotlinx.coroutines.GlobalScope 5 | import kotlinx.coroutines.launch 6 | import kotlinx.coroutines.runBlocking 7 | 8 | class LiveDataDemo { 9 | val _liveData1 = MutableLiveData(false) 10 | val livedata1 : LiveData 11 | get() = _liveData1 12 | 13 | fun test0() { 14 | val mediaLiveData = MediatorLiveData() 15 | 16 | // mediaLiveData.observeForever { 17 | // println("find something") 18 | // } 19 | 20 | mediaLiveData.addSource(_liveData1) { 21 | println("media add") 22 | mediaLiveData.value = "hello" 23 | _liveData1.value = true 24 | } 25 | 26 | val jj = _liveData1.switchMap { 27 | val ld = MutableLiveData() 28 | ld.value = "你好" 29 | ld 30 | } 31 | 32 | _liveData1.map { 33 | "ddd" 34 | } 35 | 36 | jj.observeForever { 37 | println(it) 38 | } 39 | 40 | GlobalScope.launch { 41 | _liveData1.postValue(true) 42 | } 43 | } 44 | } 45 | 46 | fun main() = runBlocking { 47 | LiveDataDemo().test0() 48 | Thread.sleep(200000) 49 | } -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/flowoperand/Test.java: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.flowoperand; 2 | 3 | public class Test { 4 | public static void main(String args[]) { 5 | Test test = new Test(); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/fragment/dialogFragment/FishFragmentActivity.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.fragment.dialogFragment 2 | 3 | import android.app.Dialog 4 | import android.graphics.Color 5 | import android.os.Bundle 6 | import android.view.View 7 | import android.widget.Button 8 | import android.widget.FrameLayout 9 | import android.widget.LinearLayout 10 | import androidx.activity.viewModels 11 | import androidx.appcompat.app.AppCompatActivity 12 | import androidx.fragment.app.DialogFragment 13 | import com.fish.kotlindemo.R 14 | import com.fish.kotlindemo.vm.MyViewModel2 15 | 16 | var count = 1 17 | class FishFragmentActivity : AppCompatActivity() { 18 | 19 | override fun onCreate(savedInstanceState: Bundle?) { 20 | super.onCreate(savedInstanceState) 21 | savedInstanceState?.let { 22 | it.getBundle("androidx.lifecycle.BundleSavedStateRegistry.key")?.remove("android:support:fragments"); 23 | } 24 | setContentView(R.layout.layout_fragment ) 25 | val fragment = FishPureFragment() 26 | fragment.arguments = Bundle().apply { 27 | putString("hello", "fragment:${count++}") 28 | } 29 | // supportFragmentManager.beginTransaction().replace(R.id.root, fragment).commitNow() 30 | 31 | MyDialogFragment().show(supportFragmentManager, "dd") 32 | } 33 | 34 | override fun onSaveInstanceState(outState: Bundle) { 35 | super.onSaveInstanceState(outState) 36 | } 37 | 38 | override fun onDestroy() { 39 | super.onDestroy() 40 | } 41 | } -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/fragment/dialogFragment/FishPureFragment.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.fragment.dialogFragment 2 | 3 | import android.content.Context 4 | import android.os.Bundle 5 | import android.view.LayoutInflater 6 | import android.view.TextureView 7 | import android.view.View 8 | import android.view.ViewGroup 9 | import android.widget.TextView 10 | import androidx.activity.viewModels 11 | import androidx.fragment.app.Fragment 12 | import androidx.fragment.app.activityViewModels 13 | import androidx.fragment.app.viewModels 14 | import androidx.lifecycle.lifecycleScope 15 | import com.fish.kotlindemo.vm.MyViewModel2 16 | 17 | class FishPureFragment:Fragment() { 18 | 19 | private val vm by viewModels() 20 | 21 | override fun onCreateView( 22 | inflater: LayoutInflater, 23 | container: ViewGroup?, 24 | savedInstanceState: Bundle? 25 | ): View? { 26 | val textView = MyView(requireContext()) 27 | textView.text = arguments?.get("hello").toString() 28 | textView.textSize = 20f 29 | lifecycleScope 30 | // vm.testLife() 31 | return textView 32 | } 33 | 34 | override fun onAttach(context: Context) { 35 | super.onAttach(context) 36 | } 37 | 38 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { 39 | super.onViewCreated(view, savedInstanceState) 40 | } 41 | 42 | override fun onCreate(savedInstanceState: Bundle?) { 43 | super.onCreate(savedInstanceState) 44 | } 45 | 46 | override fun onActivityCreated(savedInstanceState: Bundle?) { 47 | super.onActivityCreated(savedInstanceState) 48 | } 49 | 50 | override fun onDetach() { 51 | super.onDetach() 52 | } 53 | 54 | override fun onDestroy() { 55 | super.onDestroy() 56 | } 57 | 58 | override fun onDestroyView() { 59 | super.onDestroyView() 60 | } 61 | } -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/fragment/dialogFragment/MyDialogFragment.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.fragment.dialogFragment 2 | 3 | import android.graphics.Color 4 | import android.os.Bundle 5 | import android.view.LayoutInflater 6 | import android.view.View 7 | import android.view.ViewGroup 8 | import android.widget.TextView 9 | import androidx.activity.viewModels 10 | import androidx.fragment.app.DialogFragment 11 | import androidx.fragment.app.viewModels 12 | import androidx.lifecycle.ViewModelStore 13 | import com.fish.kotlindemo.vm.MyViewModel2 14 | 15 | class MyDialogFragment : DialogFragment() { 16 | override fun onCreateView( 17 | inflater: LayoutInflater, 18 | container: ViewGroup?, 19 | savedInstanceState: Bundle? 20 | ): View? { 21 | val tv = TextView(context).apply { 22 | text = "hello world" 23 | setTextColor(Color.RED) 24 | textSize = 30f 25 | } 26 | return tv 27 | } 28 | } -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/fragment/dialogFragment/MyView.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.fragment.dialogFragment 2 | 3 | import android.content.Context 4 | import android.widget.TextView 5 | import androidx.appcompat.widget.AppCompatTextView 6 | 7 | class MyView(context:Context):AppCompatTextView(context) { 8 | override fun onAttachedToWindow() { 9 | super.onAttachedToWindow() 10 | } 11 | 12 | override fun onDetachedFromWindow() { 13 | super.onDetachedFromWindow() 14 | } 15 | } -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/funclass/ClassFun.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.funclass 2 | 3 | //泛型类 4 | class A {} 5 | 6 | //泛型接口 7 | interface B {} 8 | 9 | //泛型方法 10 | fun pick(a: T) { 11 | } 12 | 13 | class Fruit { 14 | var quality: T? = null 15 | get() { 16 | println("$field") 17 | return field 18 | } 19 | 20 | fun setValue(t: T) { 21 | this.quality = t 22 | } 23 | } 24 | 25 | fun test1() { 26 | println("normal func") 27 | } 28 | 29 | inline fun testInline() { 30 | println("inline func") 31 | } 32 | 33 | fun main(args: Array) { 34 | var fruit: Fruit = Fruit() 35 | fruit.setValue("jj") 36 | //编译不通过 37 | // fruit.setValue(33) 38 | fruit.quality 39 | } 40 | -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/funclass/ExpandFun.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.funclass 2 | 3 | class ExpandFun { 4 | } 5 | 6 | class Student { 7 | //来自省份 8 | var province:String?= null 9 | //学生名字 10 | var name:String? = null 11 | init { 12 | name = "fish" 13 | province = "beijing" 14 | } 15 | fun printStudent() { 16 | println("$name") 17 | } 18 | } 19 | 20 | fun main(args: Array) { 21 | var student = Student() 22 | student.printStudent1() 23 | 24 | var b1 = "Fish".isFirstUpper() 25 | var b2 = "1Fish".isFirstUpper(); 26 | println("$b1 $b2") 27 | } 28 | 29 | 30 | fun Student.printStudent1() { 31 | println("name:$name province:$province") 32 | } 33 | 34 | fun String.isFirstUpper():Boolean { 35 | if (isNotEmpty()) { 36 | return get(0).code in 65..97 37 | } 38 | return false 39 | } -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/funclass/HighOrderFun.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.funclass 2 | 3 | import kotlin.contracts.InvocationKind 4 | import kotlin.contracts.contract 5 | 6 | class StudentInfo { 7 | //姓名 8 | var name: String? = "Fish" 9 | var alias: String? = "小鱼人" 10 | 11 | //省份 12 | var province: String? = "北京" 13 | 14 | //年龄 15 | var age: Int? = 18 16 | 17 | //性别 18 | var isBoy: Boolean = true 19 | 20 | //分数 21 | var score: Float = 88f 22 | } 23 | 24 | //let 使用 25 | fun testLet1(studentInfo: StudentInfo) { 26 | studentInfo?.isBoy = false 27 | studentInfo?.name = "小鱼人" 28 | studentInfo?.age = 14 29 | } 30 | 31 | fun testLet2(studentInfo: StudentInfo) { 32 | var letRet = studentInfo?.let { 33 | it.isBoy = false 34 | it.name = "小鱼人" 35 | it.age = 14 36 | //Lambda结果作为let 返回值 37 | "Fish" 38 | } 39 | println("letRet:$letRet") 40 | } 41 | 42 | //also 使用 43 | fun testAlso1(studentInfo: StudentInfo) { 44 | studentInfo?.isBoy = false 45 | studentInfo?.name = "小鱼人" 46 | studentInfo?.age = 14 47 | } 48 | 49 | fun testAlso2(studentInfo: StudentInfo) { 50 | var letRet = studentInfo?.also { 51 | it.isBoy = false 52 | it.name = "小鱼人" 53 | it.age = 14 54 | //Lambda结果作为let 返回值 55 | "Fish" 56 | } 57 | println("letRet:${letRet.name}") 58 | } 59 | 60 | fun testAlso3(studentInfo: StudentInfo) { 61 | studentInfo?.also { 62 | it.isBoy = false 63 | it.name = "小鱼人" 64 | it.age = 14 65 | //Lambda结果作为let 返回值 66 | "Fish" 67 | }.let { 68 | it.score = 99f 69 | } 70 | } 71 | 72 | //with 使用 73 | fun testWith1(studentInfo: StudentInfo) { 74 | studentInfo?.isBoy = false 75 | studentInfo?.name = "小鱼人" 76 | studentInfo?.age = 14 77 | } 78 | 79 | fun testWith2(studentInfo: StudentInfo) { 80 | var withRet = with(studentInfo) { 81 | isBoy = false 82 | name = "小鱼人" 83 | age = 14 84 | "Fish" 85 | } 86 | println("withRet:$withRet") 87 | } 88 | 89 | //run 使用 90 | fun testRun1(studentInfo: StudentInfo) { 91 | studentInfo?.isBoy = false 92 | studentInfo?.name = "小鱼人" 93 | studentInfo?.age = 14 94 | } 95 | 96 | fun testRun2(studentInfo: StudentInfo) { 97 | var withRet = studentInfo?.run { 98 | isBoy = false 99 | name = "小鱼人" 100 | age = 14 101 | "Fish" 102 | } 103 | println("withRet:$withRet") 104 | } 105 | 106 | //apply 使用 107 | fun testApply1() { 108 | var studentInfo = StudentInfo() 109 | studentInfo.isBoy = false 110 | studentInfo.name = "小鱼人" 111 | studentInfo.age = 14 112 | } 113 | 114 | fun testApply2() { 115 | var applyRet = StudentInfo().apply { 116 | isBoy = false 117 | name = "小鱼人" 118 | age = 14 119 | "Fish" 120 | } 121 | println("withRet:${applyRet.name}") 122 | } 123 | 124 | //repeat 使用 125 | fun testRepeat1() { 126 | var list = mutableListOf() 127 | for (index in 1..100) { 128 | list.add(StudentInfo()) 129 | } 130 | } 131 | 132 | fun testRepeat2() { 133 | var list = mutableListOf() 134 | repeat(10) { 135 | //重复这个动作10次 136 | list.add(StudentInfo()) 137 | println("第 $it 个") 138 | } 139 | } 140 | 141 | fun main(args: Array) { 142 | testAlso2(StudentInfo()) 143 | testWith2(StudentInfo()) 144 | } 145 | -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/funclass/InlineFun.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.funclass 2 | 3 | class InlineFun { 4 | } 5 | 6 | //普通函数 7 | fun normalFun1() { 8 | println("normal fun") 9 | } 10 | 11 | //内联函数 12 | inline fun inlineFun2() { 13 | println("inline fun") 14 | } 15 | 16 | inline fun inlineFun3(block: (Int) -> String): String { 17 | println("execute fun3") 18 | return block(3) 19 | } 20 | 21 | fun inlineFun4(block: (Int) -> String): String { 22 | println("execute fun4") 23 | //编译错误 24 | return inlineFun5(block) 25 | } 26 | 27 | inline fun inlineFun5(block: (Int) -> String): String { 28 | return block(3) 29 | } 30 | 31 | inline fun inlineFun6(block: (Int) -> String): String { 32 | println("execute fun6") 33 | return block(3) 34 | } 35 | 36 | fun testReturn(): String { 37 | var str = inlineFun6 { 38 | if (it > 3) { 39 | ">3" 40 | } else { 41 | "<=3" 42 | } 43 | //直接return 44 | return "fish" 45 | } 46 | println("execute inlineFun6 str:$str") 47 | return "fish" 48 | } 49 | 50 | 51 | fun main(args: Array) { 52 | // normalFun1() 53 | // inlineFun2() 54 | 55 | // var str = inlineFun3 { 56 | // if (it > 3) { 57 | // ">3" 58 | // } else { 59 | // "<=3" 60 | // } 61 | // } 62 | 63 | // var str = inlineFun4 { 64 | // if (it > 3) { 65 | // ">3" 66 | // } else { 67 | // "<=3" 68 | // } 69 | // } 70 | // println("str $str") 71 | 72 | testReturn() 73 | } 74 | 75 | var block = { it: Int -> 76 | if (it > 3) { 77 | ">3" 78 | } else { 79 | "<=3" 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/funclass/ObjectExpression.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.funclass 2 | -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/funclass/Start.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.funclass 2 | 3 | fun main(args: Array) { 4 | } -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/funclass/TestJava.java: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.funclass; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | import kotlin.jvm.functions.Function2; 9 | import kotlin.jvm.internal.Intrinsics; 10 | 11 | public class TestJava { 12 | private void test() { 13 | // ClassFunKt.testFun2(new Function2() { 14 | // @Override 15 | // public String invoke(Integer integer, String s) { 16 | // return null; 17 | // } 18 | // }); 19 | // 20 | //// ClassFunKt.getTest1().invoke() 21 | } 22 | 23 | 24 | private void testStudent(HandleStudent handleStudent) { 25 | float score = 0; 26 | if (handleStudent != null) { 27 | score = handleStudent.getScore("fish", 18); 28 | } 29 | System.out.println("score:" + score); 30 | } 31 | 32 | 33 | interface HandleStudent { 34 | //传入学生的姓名、年龄,返回学生的分数 35 | float getScore(String name, int age); 36 | } 37 | 38 | private void testKotlin() { 39 | UpFunKt.testUpFun3(true, new Function2() { 40 | @Override 41 | public Float invoke(String s, Integer integer) { 42 | return null; 43 | } 44 | }); 45 | } 46 | 47 | private void test1() { 48 | List nameList = new ArrayList(); 49 | //添加字符串 50 | nameList.add("fish"); 51 | //添加数字 52 | nameList.add(3); 53 | 54 | String ss = (String)nameList.get(0); 55 | int age = (int)nameList.get(1); 56 | } 57 | 58 | private void test2() { 59 | List nameList = new ArrayList(); 60 | //添加字符串 61 | nameList.add("fish"); 62 | //添加数字 63 | nameList.add("forest"); 64 | //编译器不允许 65 | // nameList.add(3); 66 | 67 | //无需强转 68 | String name1 = nameList.get(0); 69 | String name2 = nameList.get(1); 70 | } 71 | 72 | private void testExpand() { 73 | //需要传入扩展类的对象实例 74 | boolean b1 = ExpandFunKt.isFirstUpper("Fish"); 75 | boolean b2 = ExpandFunKt.isFirstUpper("1fish"); 76 | } 77 | } 78 | 79 | -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/funclass/UpFun.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.funclass 2 | 3 | import com.fish.kotlindemo.varclass.name 4 | import com.fish.kotlindemo.varclass.test 5 | import kotlinx.coroutines.Delay 6 | import kotlin.concurrent.thread 7 | 8 | fun upFun1(name: String, age: Int): Float { 9 | return 88f 10 | } 11 | 12 | //赋值 13 | //var varFun:(name: String, age: Int)->Float = ::upFun1 14 | var varFun = ::upFun1 15 | 16 | //testUpFun1 接收的参数为函数类型:(String, Int)->String 17 | fun testUpFun1(getScore: (String, Int) -> Float) { 18 | var score = getScore("fish", 18) 19 | println("student score:$score") 20 | } 21 | 22 | //匿名函数 23 | //var varFun1:(String, Int)->Float = fun (name: String, age: Int):Float { 24 | // return 88f 25 | //} 26 | //类型推断 27 | var varFun1 = fun(name: String, age: Int): Float { 28 | return 88f 29 | } 30 | 31 | //Lambda 表达式 32 | //var lambda1:(String, Int)->Float = { 33 | // name:String,age:Int-> 34 | // 88f 35 | //} 36 | 37 | var lambda1 = { name: String, age: Int -> 38 | 88f 39 | } 40 | 41 | //定义匿名函数 42 | var anoymous1: (String, Int) -> Float = fun(name: String, age: Int): Float { 43 | println("name:$name age:$age") 44 | return 88f 45 | } 46 | 47 | //自动推导,消除变量类型 48 | var anoymous2 = fun(name: String, age: Int): Float { 49 | println("name:$name age:$age") 50 | return 88f 51 | } 52 | 53 | //传入匿名函数 54 | fun main0(args: Array) { 55 | //传入匿名函数 56 | testUpFun1(fun(name: String, age: Int): Float { 57 | println("name:$name age:$age") 58 | return 88f 59 | }) 60 | testUpFun1(anoymous1) 61 | testUpFun1(anoymous2) 62 | } 63 | 64 | fun testUpFun2(getScore: (String, Int) -> Float, needDelay: Boolean) { 65 | if (needDelay) 66 | println("delay...") 67 | var score = getScore("fish", 18) 68 | println("student score:$score") 69 | } 70 | 71 | 72 | fun main1(args: Array) { 73 | //传入Lambda 74 | testUpFun1 { name: String, age: Int -> 75 | 88f 76 | } 77 | //传入匿名函数 78 | testUpFun1({ name: String, age: Int -> 79 | println("name:$name age:$age") 80 | 88f 81 | } 82 | ) 83 | } 84 | 85 | //完整写法 86 | var varLambda1: (String, Int) -> Float = { name: String, age: Int -> 87 | println("student name:$name age:$age") 88 | 88f 89 | } 90 | 91 | //var varLambda1 = { name: String, age: Int -> 92 | // println("student name:$name age:$age") 93 | // 88f 94 | //} 95 | // 96 | //var varLambda1: (String, Int) -> Float = { name, age -> 97 | // println("student name:$name age:$age") 98 | // 88f 99 | //} 100 | 101 | var varLambda2 = { name: String, int: Int -> 102 | println() 103 | test() 104 | "jj" 105 | } 106 | 107 | fun testUpFun3(needDelay: Boolean, getScore: (String, Int) -> Float) { 108 | if (needDelay) 109 | println("delay...") 110 | var score = getScore("fish", 18) 111 | println("student score:$score") 112 | } 113 | 114 | fun testUpFun4(getScore: (String, Int) -> Float) { 115 | var score = getScore("fish", 18) 116 | println("student score:$score") 117 | } 118 | 119 | fun testUpFun5(getScore: (String) -> Float) { 120 | var score = getScore("fish") 121 | println("student score:$score") 122 | } 123 | 124 | //无参数 125 | fun testUpFun6(getScore: () -> Float) { 126 | var score = getScore() 127 | println("student score:$score") 128 | } 129 | 130 | fun testUpFun7(getScore: (String) -> Unit): (Boolean, Int) -> String { 131 | //调用函数 132 | var score = getScore("fish") 133 | println("student score:$score") 134 | 135 | //返回函数,Lambda表示 136 | return { need: Boolean, age: Int -> 137 | println("need:$need age:$age") 138 | "fish" 139 | } 140 | } 141 | 142 | fun main2(args: Array) { 143 | testUpFun2({ name: String, age: Int -> 144 | println("name:$name age:$age") 145 | 88f 146 | }, true 147 | ) 148 | } 149 | 150 | fun main3(args: Array) { 151 | testUpFun3(true 152 | ) { name: String, age: Int -> 153 | println("name:$name age:$age") 154 | 88f 155 | } 156 | } 157 | 158 | fun main4(args: Array) { 159 | ////省略"()" 160 | testUpFun4 { name: String, age: Int -> 161 | println("name:$name age:$age") 162 | 88f 163 | } 164 | } 165 | 166 | //fun main5(args: Array) { 167 | // ////省略"()" 168 | // testUpFun5 { name: String -> 169 | // println("name:$name") 170 | // 88f 171 | // } 172 | //} 173 | 174 | fun main5(args: Array) { 175 | ////省略"()" 176 | testUpFun5 { 177 | println("name:$it") 178 | 88f 179 | } 180 | } 181 | 182 | fun main6(args: Array) { 183 | ////省略"()" 184 | testUpFun6 { 185 | println("name") 186 | 88f 187 | } 188 | } 189 | 190 | fun main7(args: Array) { 191 | ////省略"()" 192 | var testReturn = testUpFun7 { 193 | println("name:") 194 | 77f 195 | } 196 | testReturn(true, 5) 197 | } -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/inner/InnerJava.java: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.inner; 2 | 3 | public class InnerJava { 4 | } 5 | -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/inner/TestInner.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.inner 2 | 3 | import kotlinx.coroutines.* 4 | import kotlinx.coroutines.flow.* 5 | import kotlin.concurrent.thread 6 | 7 | class TestInner { 8 | 9 | data class StuInfo(val stuId: Long, val teachId:Long) 10 | data class TeachInfo(val teachId: Long, val name:String) 11 | 12 | //同步 13 | fun test0() { 14 | //模拟网络耗时 15 | val name = getStuInfoSync() 16 | println("stu name:${name.teachId}") 17 | } 18 | 19 | //异步 20 | fun test1() { 21 | getStuInfoAsync { 22 | println("stu name:${it.teachId}") 23 | } 24 | } 25 | 26 | fun getStuInfoSync(stuId:Long = 12):StuInfo { 27 | Thread.sleep(2000) 28 | return StuInfo(stuId, 99) 29 | } 30 | 31 | fun getStuInfoAsync(stuId:Long = 12, callback:((StuInfo)->Unit)?) { 32 | thread { 33 | //模拟网络耗时 34 | Thread.sleep(2000) 35 | callback?.invoke(StuInfo(stuId, 99)) 36 | } 37 | } 38 | 39 | //异步 40 | fun test2() { 41 | getStuInfoAsync { 42 | getTeachInfoAsync { 43 | println("teach info:${it.name}") 44 | } 45 | } 46 | } 47 | 48 | fun getTeachInfoAsync(teachId:Long = 99, callback:((TeachInfo)->Unit)?) { 49 | thread { 50 | //模拟网络耗时 51 | Thread.sleep(2000) 52 | callback?.invoke(TeachInfo(teachId, "Tom")) 53 | } 54 | } 55 | 56 | //挂起函数获取学生信息 57 | suspend fun getStuInfoAsyncForCoroutine(stuId:Long = 12):StuInfo { 58 | return withContext(Dispatchers.IO) { 59 | //模拟网络耗时 60 | Thread.sleep(2000) 61 | StuInfo(stuId, 99) 62 | } 63 | } 64 | 65 | //挂起函数获取教师信息 66 | suspend fun getTeachInfoAsyncForCoroutine(teachId:Long = 99):TeachInfo { 67 | return withContext(Dispatchers.IO) { 68 | //模拟网络耗时 69 | Thread.sleep(2000) 70 | TeachInfo(teachId, "Tom") 71 | } 72 | } 73 | 74 | fun test3() { 75 | runBlocking { 76 | val teachId = getStuInfoAsyncForCoroutine().teachId 77 | val teachName = getTeachInfoAsyncForCoroutine(teachId).name 78 | println("teachName:$teachName") 79 | } 80 | } 81 | 82 | 83 | fun test4() { 84 | 85 | val flow = flow { 86 | emit("hello") 87 | }.shareIn(CoroutineScope(Job()), SharingStarted.Eagerly, 20) 88 | 89 | GlobalScope.launch { 90 | flow.collect { 91 | println("hello") 92 | } 93 | } 94 | 95 | GlobalScope.launch { 96 | } 97 | } 98 | } 99 | 100 | 101 | fun main() { 102 | val demo = TestInner() 103 | demo.test3() 104 | 105 | Thread.sleep(1000000) 106 | } 107 | -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/inner/TmpDemo.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.inner 2 | 3 | import kotlinx.coroutines.* 4 | import kotlin.concurrent.thread 5 | import kotlin.coroutines.resume 6 | import kotlin.coroutines.suspendCoroutine 7 | 8 | class TmpDemo { 9 | fun test0() { 10 | 11 | } 12 | suspend fun test1() { 13 | 14 | } 15 | 16 | suspend fun test2() { 17 | thread { 18 | Thread.sleep(2000) 19 | println("sleep end") 20 | } 21 | println("test end") 22 | } 23 | 24 | suspend fun test3() { 25 | withContext(Dispatchers.IO) { 26 | Thread.sleep(2000) 27 | println("sleep end") 28 | } 29 | println("test end") 30 | } 31 | 32 | suspend fun test4() { 33 | val ret = suspendCoroutine { 34 | thread { 35 | Thread.sleep(2000) 36 | println("sleep end") 37 | } 38 | // delay(2000) 39 | } 40 | println("test end $ret") 41 | } 42 | 43 | suspend fun test5() { 44 | val ret = suspendCoroutine { 45 | thread { 46 | Thread.sleep(2000) 47 | println("sleep end") 48 | it.resume("thread finish") 49 | } 50 | } 51 | println("test end $ret") 52 | } 53 | 54 | suspend fun test6() { 55 | println("") 56 | delay(100) 57 | println("test end ${Thread.currentThread()}") 58 | delay(200) 59 | println("test end2 ${Thread.currentThread()}") 60 | 61 | } 62 | } 63 | 64 | fun main() { 65 | runBlocking { 66 | TmpDemo().test6() 67 | } 68 | Thread.sleep(200000) 69 | } -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/lifecycleAndCoroutine/MyFlow.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.lifecycleAndCoroutine 2 | 3 | import androidx.lifecycle.Lifecycle 4 | import androidx.lifecycle.LifecycleEventObserver 5 | import kotlinx.coroutines.Dispatchers 6 | import kotlinx.coroutines.channels.awaitClose 7 | import kotlinx.coroutines.coroutineScope 8 | import kotlinx.coroutines.flow.callbackFlow 9 | import kotlinx.coroutines.flow.flow 10 | import kotlinx.coroutines.flow.flowOn 11 | import kotlinx.coroutines.isActive 12 | import kotlinx.coroutines.launch 13 | import kotlinx.coroutines.sync.withLock 14 | import kotlin.concurrent.thread 15 | import kotlin.coroutines.resume 16 | 17 | class MyFlow { 18 | val flow = flow { 19 | var count = 0 20 | while (true) { 21 | kotlinx.coroutines.delay(1000) 22 | println("emit hello world $count") 23 | emit(count++) 24 | } 25 | }.flowOn(Dispatchers.IO) 26 | 27 | val flow2 = flow { 28 | kotlinx.coroutines.delay(5000) 29 | println("before emit") 30 | emit("jj") 31 | } 32 | 33 | fun getInfo(callback:()->Unit) { 34 | thread { 35 | Thread.sleep(3000) 36 | callback.invoke() 37 | } 38 | } 39 | 40 | val flow3 = callbackFlow { 41 | getInfo { 42 | println("send flow in thread") 43 | trySend("send flow") 44 | } 45 | Thread.sleep(5000) 46 | if (!isActive) { 47 | println("流被关闭了") 48 | } 49 | println("after try send") 50 | awaitClose { 51 | println("end") 52 | } 53 | } 54 | } -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/lifecycleAndCoroutine/MyLifecycle.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.lifecycleAndCoroutine 2 | 3 | class MyLifecycle { 4 | } -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/lifecycleAndCoroutine/MyVM.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.lifecycleAndCoroutine 2 | 3 | import android.widget.Toast 4 | import androidx.lifecycle.* 5 | import kotlinx.coroutines.* 6 | import kotlin.concurrent.thread 7 | 8 | 9 | class MyVM: ViewModel() { 10 | fun getInfo() { 11 | viewModelScope.launch { 12 | //模拟网络请求 13 | delay(4000) 14 | liveData.postValue("hello world") 15 | println("hello world") 16 | } 17 | } 18 | 19 | val liveData = MutableLiveData() 20 | fun getStuInfo() { 21 | thread { 22 | //模拟网络请求 23 | Thread.sleep(2000) 24 | liveData.postValue("hello world") 25 | } 26 | } 27 | 28 | val scope = CoroutineScope(Job()) 29 | fun getStuInfoV2() { 30 | scope.launch { 31 | //模拟网络请求 32 | delay(4000) 33 | liveData.postValue("hello world") 34 | println("hello world") 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/mutablesharedflow/MutableSharedFlowDemo.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.mutablesharedflow 2 | 3 | import kotlinx.coroutines.GlobalScope 4 | import kotlinx.coroutines.delay 5 | import kotlinx.coroutines.flow.MutableSharedFlow 6 | import kotlinx.coroutines.flow.MutableStateFlow 7 | import kotlinx.coroutines.flow.collect 8 | import kotlinx.coroutines.launch 9 | import kotlinx.coroutines.runBlocking 10 | 11 | class MutableSharedFlowDemo { 12 | fun test1() { 13 | runBlocking { 14 | //构造热流 15 | val flow = MutableSharedFlow() 16 | //发送数据(生产者) 17 | flow.emit("hello world") 18 | 19 | //开启协程 20 | GlobalScope.launch { 21 | //接收数据(消费者) 22 | flow.collect { 23 | println("collect: $it") 24 | } 25 | } 26 | } 27 | } 28 | 29 | fun test2() { 30 | runBlocking { 31 | //构造热流 32 | val flow = MutableSharedFlow() 33 | 34 | //开启协程 35 | GlobalScope.launch { 36 | //接收数据(消费者) 37 | flow.collect { 38 | println("collect: $it") 39 | } 40 | } 41 | 42 | //发送数据(生产者) 43 | delay(200)//保证消费者已经注册上 44 | flow.emit("hello world") 45 | } 46 | } 47 | 48 | fun test3() { 49 | runBlocking { 50 | //构造热流 51 | val flow = MutableSharedFlow(4) 52 | //发送数据(生产者) 53 | flow.emit("hello world1") 54 | flow.emit("hello world2") 55 | flow.emit("hello world3") 56 | flow.emit("hello world4") 57 | 58 | //开启协程 59 | GlobalScope.launch { 60 | //接收数据(消费者) 61 | flow.collect { 62 | println("collect: $it") 63 | } 64 | } 65 | } 66 | } 67 | 68 | fun test4() { 69 | runBlocking { 70 | //构造热流 71 | val flow = MutableSharedFlow() 72 | 73 | //接收数据(消费者) 74 | flow.collect { 75 | println("collect: $it") 76 | } 77 | println("start emit")//① 78 | flow.emit("hello world") 79 | } 80 | } 81 | 82 | fun test5() { 83 | runBlocking { 84 | //构造热流 85 | val flow = MutableSharedFlow() 86 | 87 | //开启协程 88 | GlobalScope.launch { 89 | //接收数据(消费者) 90 | flow.collect { 91 | println("collect: $it") 92 | delay(2000) 93 | } 94 | } 95 | 96 | //发送数据(生产者) 97 | delay(200)//保证消费者先执行 98 | println("emit 1 ${System.currentTimeMillis()}") 99 | flow.emit("hello world1") 100 | delay(100) 101 | println("emit 2 ${System.currentTimeMillis()}") 102 | flow.emit("hello world2") 103 | delay(100) 104 | println("emit 3 ${System.currentTimeMillis()}") 105 | flow.emit("hello world3") 106 | delay(100) 107 | println("emit 4 ${System.currentTimeMillis()}") 108 | flow.emit("hello world4") 109 | } 110 | } 111 | 112 | fun test6() { 113 | runBlocking { 114 | //构造热流 115 | val flow = MutableSharedFlow(2, 2) 116 | 117 | //开启协程 118 | GlobalScope.launch { 119 | //接收数据(消费者) 120 | flow.collect { 121 | delay(2000) 122 | println("collect: $it") 123 | } 124 | } 125 | 126 | //发送数据(生产者) 127 | delay(200)//保证消费者先执行 128 | println("emit 1 ${System.currentTimeMillis()}") 129 | flow.emit("hello world1") 130 | println("emit 2 ${System.currentTimeMillis()}") 131 | flow.emit("hello world2") 132 | println("emit 3 ${System.currentTimeMillis()}") 133 | flow.emit("hello world3") 134 | println("emit 4 ${System.currentTimeMillis()}") 135 | flow.emit("hello world4") 136 | } 137 | } 138 | 139 | fun test7() { 140 | runBlocking { 141 | //构造热流 142 | val flow = MutableSharedFlow(4, 3) 143 | //开启协程 144 | GlobalScope.launch { 145 | //接收数据(消费者1) 146 | flow.collect { 147 | println("collect1: $it") 148 | } 149 | } 150 | GlobalScope.launch { 151 | //接收数据(消费者2) 152 | flow.collect { 153 | //模拟消费慢 154 | delay(10000) 155 | println("collect2: $it") 156 | } 157 | } 158 | //发送数据(生产者) 159 | delay(200)//保证消费者先执行 160 | var count = 0 161 | while (true) { 162 | flow.emit("emit:${count++}") 163 | } 164 | } 165 | } 166 | 167 | fun test8() { 168 | runBlocking { 169 | //构造热流 170 | val flow = MutableStateFlow("") 171 | flow.emit("hello world") 172 | flow.collect { 173 | //消费者 174 | println(it) 175 | } 176 | } 177 | } 178 | 179 | fun test9() { 180 | runBlocking { 181 | //构造热流 182 | val flow = MutableStateFlow("") 183 | flow.emit("hello world") 184 | GlobalScope.launch { 185 | flow.collect { 186 | println(it) 187 | } 188 | } 189 | //再发送 190 | delay(1000) 191 | flow.emit("hello world") 192 | // flow.emit("hello world") 193 | } 194 | } 195 | 196 | fun test10() { 197 | runBlocking { 198 | //构造热流 199 | val flow = MutableStateFlow("") 200 | flow.emit("hello world") 201 | flow.emit("hello world1") 202 | flow.emit("hello world2") 203 | flow.emit("hello world3") 204 | flow.emit("hello world4") 205 | flow.collect { 206 | println(it) 207 | } 208 | } 209 | } 210 | } 211 | 212 | fun main(args: Array) { 213 | var demo = MutableSharedFlowDemo() 214 | demo.test5() 215 | Thread.sleep(1000000) 216 | } -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/object/EasyJavaInterface.java: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.object; 2 | 3 | public interface EasyJavaInterface { 4 | //学生姓名 5 | String getStuName(); 6 | } 7 | -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/object/JavaAbClass.java: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.object; 2 | //Java 抽象类 3 | public abstract class JavaAbClass { 4 | public String getStuName() { 5 | return null; 6 | } 7 | public abstract int getStuAge(); 8 | } 9 | -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/object/JavaAbClass2.java: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.object; 2 | //Java 抽象类 3 | public abstract class JavaAbClass2 { 4 | public abstract float getScore(); 5 | } 6 | -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/object/JavaInterface.java: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.object; 2 | 3 | public interface JavaInterface { 4 | //学生姓名 5 | String getStuName(); 6 | //学生年级 7 | int getStuAge(); 8 | } 9 | -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/object/JavaSingleton.java: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.object; 2 | 3 | public class JavaSingleton { 4 | private static volatile JavaSingleton instance; 5 | private JavaSingleton(){} 6 | 7 | //双重检测锁 8 | public JavaSingleton getInstance() { 9 | if (instance == null) { 10 | synchronized (JavaSingleton.class) { 11 | if (instance == null) { 12 | instance = new JavaSingleton(); 13 | } 14 | } 15 | } 16 | return instance; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/object/JavaStatic.java: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.object; 2 | 3 | public class JavaStatic { 4 | private String name; 5 | private int age; 6 | private float score; 7 | //构造Bean对象 8 | public static JavaStatic buildBean() { 9 | JavaStatic bean = new JavaStatic(); 10 | return bean; 11 | } 12 | 13 | public String getName() { 14 | return name; 15 | } 16 | 17 | public void setName(String name) { 18 | this.name = name; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/object/ObjectCompanion.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.`object` 2 | 3 | class ObjectCompanion { 4 | fun test() { 5 | for (i in 1..100) { 6 | KotlinStatic.buildBean() 7 | } 8 | } 9 | } 10 | 11 | class KotlinStatic { 12 | private val name: String? = null 13 | private val age = 0 14 | private val score = 0f 15 | 16 | companion object StudentFactory : EasyJavaInterface { 17 | //伴生对象函数 18 | fun buildBean(): KotlinStatic { 19 | //不允许访问外部变量 20 | // score = 13.f 21 | return KotlinStatic() 22 | } 23 | 24 | override fun getStuName(): String { 25 | TODO("Not yet implemented") 26 | } 27 | } 28 | } 29 | 30 | class KotlinStatic1 { 31 | private val name: String? = null 32 | private val age = 0 33 | private val score = 0f 34 | 35 | companion object { 36 | //伴生对象函数 37 | fun buildBean(): KotlinStatic { 38 | return KotlinStatic() 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/object/ObjectDeclaration.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.`object` 2 | 3 | import com.fish.kotlindemo.varclass.age 4 | 5 | class ObjectDeclaration { 6 | fun test() { 7 | KtSingleton.getStuName() 8 | KtSingleton.age = 18 9 | } 10 | 11 | fun test1() { 12 | mySingleton.getStuName() 13 | } 14 | } 15 | 16 | object KtSingleton { 17 | var name: String? = null 18 | @JvmField 19 | var age: Int = 0 20 | @JvmStatic 21 | fun getStuName(): String { 22 | return "name:$name" 23 | } 24 | } 25 | 26 | var mySingleton = KtSingleton 27 | -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/object/ObjectExpression.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.`object` 2 | 3 | fun main(args: Array) { 4 | var testJava = TestJava() 5 | testJava.getStuInfo(object : JavaInterface { 6 | override fun getStuName(): String { 7 | return "fish" 8 | } 9 | 10 | override fun getStuAge(): Int { 11 | return 18 12 | } 13 | }) 14 | 15 | //调用 16 | testJava.getStuInfo(object : JavaAbClass() { 17 | override fun getStuAge(): Int { 18 | return 18 19 | } 20 | 21 | override fun getStuName(): String { 22 | return "fish" 23 | } 24 | }) 25 | 26 | //普通使用 27 | testJava.getStuInfo(object : EasyJavaInterface { 28 | override fun getStuName(): String { 29 | return "fish" 30 | } 31 | }) 32 | //Lambda 代替 33 | testJava.getStuInfo { "fish" } 34 | 35 | //匿名类 36 | Thread(object : Runnable { 37 | override fun run() { 38 | Thread.sleep(100) 39 | Thread.sleep(200) 40 | } 41 | }) 42 | //Lambda 43 | Thread { 44 | Thread.sleep(100) 45 | Thread.sleep(200) 46 | } 47 | 48 | //外部变量 49 | var height = 0 50 | var javaInterface = object : JavaInterface { 51 | override fun getStuName(): String { 52 | //编译正确 53 | height = 99 54 | return "name" 55 | } 56 | 57 | override fun getStuAge(): Int { 58 | return 18 59 | } 60 | } 61 | //扩展属性 62 | var javaInterface1 = object : JavaInterface { 63 | var score = 0f 64 | override fun getStuName(): String { 65 | return "fish" 66 | } 67 | 68 | override fun getStuAge(): Int { 69 | return 18 70 | } 71 | } 72 | javaInterface1.score = 88f 73 | //赋值 74 | // javaInterface.score = 99f 75 | 76 | //多接口 77 | var multiple = object : JavaInterface, JavaAbClass2() { 78 | override fun getStuName(): String { 79 | return "fish" 80 | } 81 | override fun getStuAge(): Int { 82 | return 18 83 | } 84 | override fun getScore(): Float { 85 | return 88f 86 | } 87 | } 88 | 89 | //对象 90 | var tempObject = object { 91 | var name : String ? = null 92 | var age = 0 93 | } 94 | //调用 95 | tempObject.age = 18 96 | tempObject.name = "fish" 97 | 98 | fun tempFun() = object { 99 | var name : String ? = null 100 | var age = 0 101 | } 102 | tempFun().age = 18 103 | tempFun().name = "fish" 104 | } 105 | 106 | class ObjectExpression { 107 | private fun tempFun() = object { 108 | var name : String ? = null 109 | var age = 0 110 | } 111 | fun tempFun2() = object { 112 | var name : String ? = null 113 | var age = 0 114 | } 115 | fun test() { 116 | //ok 117 | tempFun().age = 5 118 | //报错 119 | // tempFun2().age = 6 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/object/Start.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.`object` 2 | 3 | class Start { 4 | } -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/object/TestJava.java: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.object; 2 | 3 | import android.view.View; 4 | 5 | import org.jetbrains.annotations.NotNull; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | import kotlin.Metadata; 11 | 12 | public class TestJava { 13 | //继承接口 14 | class MyInter implements JavaInterface { 15 | @Override 16 | public String getStuName() { 17 | return null; 18 | } 19 | 20 | @Override 21 | public int getStuAge() { 22 | return 0; 23 | } 24 | } 25 | 26 | public static void main(String args[]) { 27 | TestJava testJava = new TestJava(); 28 | // //实例化接口 29 | // MyInter myInter = new TestJava().new MyInter(); 30 | // //传入参数 31 | // testJava.getStuInfo(myInter); 32 | 33 | //匿名内部类 34 | testJava.getStuInfo(new JavaInterface() { 35 | @Override 36 | public String getStuName() { 37 | return "fish"; 38 | } 39 | 40 | @Override 41 | public int getStuAge() { 42 | return 18; 43 | } 44 | }); 45 | 46 | testJava.getStuInfo(new JavaAbClass() { 47 | @Override 48 | public int getStuAge() { 49 | return 18; 50 | } 51 | }); 52 | 53 | testJava.getStuInfo(() -> "fish"); 54 | 55 | //学生身高 56 | int height = 0; 57 | JavaInterface javaInterface = new JavaInterface() { 58 | @Override 59 | public String getStuName() { 60 | //编译错误 61 | // height = 180; 62 | return "fish"; 63 | } 64 | 65 | @Override 66 | public int getStuAge() { 67 | return 18; 68 | } 69 | }; 70 | 71 | JavaInterface javaInterface1 = new JavaInterface() { 72 | //新增分数 73 | private float score; 74 | public float getScore() { 75 | return score; 76 | } 77 | @Override 78 | public String getStuName() { 79 | return null; 80 | } 81 | 82 | @Override 83 | public int getStuAge() { 84 | return 0; 85 | } 86 | }; 87 | //无法访问 88 | // javaInterface1.getScore(); 89 | } 90 | 91 | public void getStuInfo(JavaInterface javaInterface) { 92 | String name = javaInterface.getStuName(); 93 | int age = javaInterface.getStuAge(); 94 | } 95 | 96 | public void getStuInfo(JavaAbClass javaAbClass) { 97 | String name = javaAbClass.getStuName(); 98 | int age = javaAbClass.getStuAge(); 99 | } 100 | 101 | public void getStuInfo(EasyJavaInterface easyJavaInterface) { 102 | String name = easyJavaInterface.getStuName(); 103 | } 104 | 105 | public void testKtSingleton() { 106 | String name = KtSingleton.getStuName(); 107 | int age = KtSingleton.age; 108 | } 109 | 110 | public void testKt() { 111 | for (int i = 0; i < 100; i++) { 112 | KotlinStatic.StudentFactory.buildBean(); 113 | KotlinStatic1.Companion.buildBean(); 114 | } 115 | } 116 | } 117 | 118 | -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/repository/MyRepo.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.repository 2 | 3 | import android.app.Application 4 | import com.fish.kotlindemo.app.MyApp 5 | import com.fish.kotlindemo.app.scope 6 | import kotlinx.coroutines.* 7 | import kotlinx.coroutines.flow.Flow 8 | import kotlinx.coroutines.flow.flow 9 | import kotlinx.coroutines.flow.launchIn 10 | import kotlinx.coroutines.flow.map 11 | 12 | class MyRepo { 13 | companion object { 14 | var scope:CoroutineScope? = null 15 | var app:Application ?= null 16 | } 17 | suspend fun getInfo():String { 18 | delay(2000) 19 | getId() 20 | // app?.scope?.launch { 21 | // delay(6000) 22 | // println("shit") 23 | // }?.join() 24 | // app?.scope?.coroutineContext?.let { 25 | // withContext(it) { 26 | // delay(6000) 27 | // println("shit") 28 | // } 29 | // println("fuck world") 30 | // } 31 | println("fuck world2") 32 | return "hello" 33 | } 34 | 35 | fun bind(app1:Application) { 36 | app = app1 37 | } 38 | 39 | suspend fun getId() { 40 | app?.scope?.launch { 41 | delay(6000) 42 | println("shit") 43 | }?.join() 44 | println("fuck world") 45 | } 46 | 47 | fun getFlow(): Flow { 48 | return flow { 49 | delay(2000) 50 | emit("hello world") 51 | }.map { 52 | "$it 0000" 53 | } 54 | } 55 | } -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/select/SelectDebug.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.select 2 | -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/sequence/Java8Stream.java: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.sequence; 2 | 3 | import android.os.Build; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | import java.util.stream.Stream; 8 | 9 | import androidx.annotation.RequiresApi; 10 | 11 | public class Java8Stream { 12 | 13 | private List list = new ArrayList<>(); 14 | 15 | public Java8Stream() { 16 | for (int i = 0; i < 10000000; i++) { 17 | list.add(i); 18 | } 19 | } 20 | 21 | public List dealCollection() { 22 | List evenList = new ArrayList<>(); 23 | for (Integer integer : list) { 24 | //筛选出偶数 25 | if (integer % 2 == 0) { 26 | evenList.add(integer); 27 | } 28 | } 29 | 30 | List bigList = new ArrayList<>(); 31 | for (Integer integer : evenList) { 32 | //从偶数中筛选出大于1000的数 33 | if (integer > 1000) { 34 | bigList.add(integer); 35 | } 36 | } 37 | //返回筛选结果列表 38 | return bigList; 39 | } 40 | 41 | @RequiresApi(api = Build.VERSION_CODES.N) 42 | public long dealCollectionWithStream() { 43 | Stream stream = list.stream(); 44 | return stream.filter(value -> value % 2 == 0) 45 | .filter(value -> value > 1000) 46 | .count(); 47 | } 48 | 49 | @RequiresApi(api = Build.VERSION_CODES.N) 50 | public static void main(String args[]) { 51 | 52 | SequenceDemo sequenceDemo = new SequenceDemo(); 53 | //使用集合操作 54 | sequenceDemo.testCollection(); 55 | //使用sequence操作 56 | sequenceDemo.testSequence(); 57 | sequenceDemo.testSequence1(); 58 | 59 | Java8Stream java8Stream = new Java8Stream(); 60 | //普通集合耗时 61 | long startTime = System.currentTimeMillis(); 62 | List list = java8Stream.dealCollection(); 63 | System.out.println("java7 list size:" + list.size() + " use time:" + (System.currentTimeMillis() - startTime) + "ms"); 64 | 65 | //Stream API 的耗时 66 | long startTime2 = System.currentTimeMillis(); 67 | long count = java8Stream.dealCollectionWithStream(); 68 | System.out.println("java8 stream list size:" + count + " use time:" + (System.currentTimeMillis() - startTime2) + "ms"); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/sequence/SequenceDemo.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.sequence 2 | 3 | import kotlin.system.measureTimeMillis 4 | 5 | class SequenceDemo { 6 | fun testCollection() { 7 | var time = measureTimeMillis { 8 | var list = (0..10000000).filter { 9 | it % 2 == 0 10 | }.filter { 11 | it > 1000 12 | } 13 | println("kotlin collection list size:${list.size}") 14 | } 15 | println("kotlin collection use time:$time") 16 | } 17 | 18 | fun testSequence() { 19 | var time = measureTimeMillis { 20 | val count = 21 | 22 | (0..10000000) 23 | .asSequence()//转换为sequence 24 | .filter { 25 | it % 2 == 0//过滤偶数 26 | }.filter { 27 | it > 1000//过滤>1000 28 | } 29 | .count() //统计个数 30 | 31 | 32 | println("kotlin sequence list size:${count}") 33 | } 34 | println("kotlin sequence use time:$time") 35 | } 36 | 37 | fun testSequence1() { 38 | var time = measureTimeMillis { 39 | val count = (0..10000000) 40 | .asSequence()//转换为sequence 41 | .filter { 42 | it % 2 == 0//过滤偶数 43 | }.take(10).count() 44 | println("kotlin sequence1 list size:${count}") 45 | } 46 | println("kotlin sequence1 use time:$time") 47 | } 48 | 49 | // 50 | // fun simple(): Sequence = sequence { // sequence builder 51 | // for (i in 1..3) { 52 | // Thread.sleep(100) // pretend we are computing it 53 | // yield(i) // yield next value 54 | // } 55 | // } 56 | // 57 | // fun main2() { 58 | // simple().forEach { value -> println(value) } 59 | // } 60 | } 61 | 62 | fun main(args: Array) { 63 | var demo = SequenceDemo() 64 | demo.testCollection() 65 | demo.testSequence() 66 | Thread.sleep(1000000) 67 | 68 | } -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/service/MyService.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.service 2 | 3 | import androidx.lifecycle.DefaultLifecycleObserver 4 | import androidx.lifecycle.LifecycleOwner 5 | import androidx.lifecycle.LifecycleService 6 | 7 | class MyService:LifecycleService() { 8 | override fun onCreate() { 9 | super.onCreate() 10 | lifecycle.addObserver(object:DefaultLifecycleObserver { 11 | override fun onCreate(owner: LifecycleOwner) { 12 | super.onCreate(owner) 13 | } 14 | 15 | override fun onStart(owner: LifecycleOwner) { 16 | super.onStart(owner) 17 | } 18 | 19 | override fun onStop(owner: LifecycleOwner) { 20 | super.onStop(owner) 21 | } 22 | 23 | override fun onDestroy(owner: LifecycleOwner) { 24 | super.onDestroy(owner) 25 | } 26 | }) 27 | } 28 | } -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/ui/TestData.java: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.ui; 2 | 3 | public class TestData { 4 | private int ms1vv; 5 | private int b; 6 | 7 | private void setB(int b) { 8 | this.b = b; 9 | } 10 | 11 | private int getB() { 12 | return b; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/ui/dashboard/DashboardFragment.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.ui.dashboard 2 | 3 | import android.os.Bundle 4 | import android.view.LayoutInflater 5 | import android.view.View 6 | import android.view.ViewGroup 7 | import android.widget.TextView 8 | import androidx.fragment.app.Fragment 9 | import androidx.lifecycle.Observer 10 | import androidx.lifecycle.ViewModelProvider 11 | import com.fish.kotlindemo.R 12 | import com.fish.kotlindemo.databinding.FragmentDashboardBinding 13 | 14 | class DashboardFragment : Fragment() { 15 | 16 | private lateinit var dashboardViewModel: DashboardViewModel 17 | private var _binding: FragmentDashboardBinding? = null 18 | 19 | // This property is only valid between onCreateView and 20 | // onDestroyView. 21 | private val binding get() = _binding!! 22 | 23 | override fun onCreateView( 24 | inflater: LayoutInflater, 25 | container: ViewGroup?, 26 | savedInstanceState: Bundle? 27 | ): View? { 28 | dashboardViewModel = 29 | ViewModelProvider(this).get(DashboardViewModel::class.java) 30 | 31 | _binding = FragmentDashboardBinding.inflate(inflater, container, false) 32 | val root: View = binding.root 33 | 34 | val textView: TextView = binding.textDashboard 35 | dashboardViewModel.text.observe(viewLifecycleOwner, Observer { 36 | textView.text = it 37 | }) 38 | return root 39 | } 40 | 41 | override fun onDestroyView() { 42 | super.onDestroyView() 43 | _binding = null 44 | } 45 | } -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/ui/dashboard/DashboardViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.ui.dashboard 2 | 3 | import androidx.lifecycle.LiveData 4 | import androidx.lifecycle.MutableLiveData 5 | import androidx.lifecycle.ViewModel 6 | 7 | class DashboardViewModel : ViewModel() { 8 | 9 | private val _text = MutableLiveData().apply { 10 | value = "This is dashboard Fragment" 11 | } 12 | val text: LiveData = _text 13 | } -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/ui/home/HomeFragment.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.ui.home 2 | 3 | import android.os.Bundle 4 | import android.view.LayoutInflater 5 | import android.view.View 6 | import android.view.ViewGroup 7 | import android.widget.TextView 8 | import androidx.fragment.app.Fragment 9 | import androidx.lifecycle.LifecycleObserver 10 | import androidx.lifecycle.Observer 11 | import androidx.lifecycle.ViewModelProvider 12 | import androidx.lifecycle.lifecycleScope 13 | import com.fish.kotlindemo.R 14 | import com.fish.kotlindemo.databinding.FragmentHomeBinding 15 | 16 | class HomeFragment : Fragment() { 17 | 18 | private lateinit var homeViewModel: HomeViewModel 19 | private var _binding: FragmentHomeBinding? = null 20 | 21 | // This property is only valid between onCreateView and 22 | // onDestroyView. 23 | private val binding get() = _binding!! 24 | 25 | override fun onCreateView( 26 | inflater: LayoutInflater, 27 | container: ViewGroup?, 28 | savedInstanceState: Bundle? 29 | ): View? { 30 | homeViewModel = 31 | ViewModelProvider(this).get(HomeViewModel::class.java) 32 | 33 | _binding = FragmentHomeBinding.inflate(inflater, container, false) 34 | val root: View = binding.root 35 | 36 | val textView: TextView = binding.textHome 37 | homeViewModel.text.observe(viewLifecycleOwner, Observer { 38 | textView.text = it 39 | }) 40 | 41 | binding.btnHome.setOnClickListener { 42 | 43 | } 44 | return root 45 | } 46 | 47 | override fun onDestroyView() { 48 | super.onDestroyView() 49 | _binding = null 50 | } 51 | } -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/ui/home/HomeViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.ui.home 2 | 3 | import androidx.lifecycle.LiveData 4 | import androidx.lifecycle.MutableLiveData 5 | import androidx.lifecycle.ViewModel 6 | 7 | class HomeViewModel : ViewModel() { 8 | 9 | private val _text = MutableLiveData().apply { 10 | value = "This is home Fragment" 11 | } 12 | val text: LiveData = _text 13 | } -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/ui/notifications/NotificationsFragment.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.ui.notifications 2 | 3 | import android.os.Bundle 4 | import android.view.LayoutInflater 5 | import android.view.View 6 | import android.view.ViewGroup 7 | import android.widget.TextView 8 | import androidx.fragment.app.Fragment 9 | import androidx.lifecycle.Observer 10 | import androidx.lifecycle.ViewModelProvider 11 | import com.fish.kotlindemo.R 12 | import com.fish.kotlindemo.databinding.FragmentNotificationsBinding 13 | 14 | class NotificationsFragment : Fragment() { 15 | 16 | private lateinit var notificationsViewModel: NotificationsViewModel 17 | private var _binding: FragmentNotificationsBinding? = null 18 | 19 | // This property is only valid between onCreateView and 20 | // onDestroyView. 21 | private val binding get() = _binding!! 22 | 23 | override fun onCreateView( 24 | inflater: LayoutInflater, 25 | container: ViewGroup?, 26 | savedInstanceState: Bundle? 27 | ): View? { 28 | notificationsViewModel = 29 | ViewModelProvider(this).get(NotificationsViewModel::class.java) 30 | 31 | _binding = FragmentNotificationsBinding.inflate(inflater, container, false) 32 | val root: View = binding.root 33 | 34 | val textView: TextView = binding.textNotifications 35 | notificationsViewModel.text.observe(viewLifecycleOwner, Observer { 36 | textView.text = it 37 | }) 38 | return root 39 | } 40 | 41 | override fun onDestroyView() { 42 | super.onDestroyView() 43 | _binding = null 44 | } 45 | } -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/ui/notifications/NotificationsViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.ui.notifications 2 | 3 | import androidx.lifecycle.LiveData 4 | import androidx.lifecycle.MutableLiveData 5 | import androidx.lifecycle.ViewModel 6 | 7 | class NotificationsViewModel : ViewModel() { 8 | 9 | private val _text = MutableLiveData().apply { 10 | value = "This is notifications Fragment" 11 | } 12 | val text: LiveData = _text 13 | } -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/varclass/FunTest.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.varclass 2 | 3 | fun testV2(name: String, age: Int, score: Double) { 4 | 5 | } 6 | 7 | fun testV3(name: String, age: Int = 5, score: Double){ 8 | 9 | } 10 | 11 | fun testV4(name: String = "fish", age: Int, score: Double = 4.5){ 12 | 13 | } 14 | 15 | fun testV5(vararg name:String) { 16 | name.forEach { 17 | println(it.length) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/varclass/Start.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.varclass 2 | 3 | 4 | fun main(args: Array) { 5 | //赋值 6 | num = 3.5 7 | //取值 8 | var numLong2 = num 9 | test() 10 | } 11 | 12 | fun main1() { 13 | var varTestClass = VarTestClass() 14 | //赋值 15 | varTestClass.num = 3 16 | //获取值 17 | var num = varTestClass.num 18 | } 19 | 20 | fun main2() { 21 | testV2("fish", 5, 4.5) 22 | testV2(score = 4.5, name = "fish", age = 5) 23 | } 24 | 25 | fun main3() { 26 | testV4("fish", 4) 27 | } 28 | 29 | fun main4() { 30 | testV5("fish", "fish2", "fish3") 31 | var myStart = MyStart() 32 | myStart.start() 33 | } 34 | 35 | class MyStart { 36 | fun start() { 37 | fun end() { 38 | } 39 | //调用 40 | end() 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/varclass/TestJava.java: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.varclass; 2 | 3 | import android.util.Log; 4 | 5 | import kotlin.jvm.JvmField; 6 | import kotlin.jvm.JvmName; 7 | 8 | class TestJava { 9 | void test() { 10 | int a = 5; 11 | 12 | //小转大 允许 13 | long b = a; 14 | 15 | //大转小 允许 16 | a = (int) b; 17 | } 18 | 19 | void test2() { 20 | //调用方法 21 | VarTestKt.test2(); 22 | // //获取变量 23 | // VarTestKt.getNum(); 24 | // //设置变量 25 | // VarTestKt.setNum(33); 26 | 27 | //直接访问属性 28 | VarTestKt.num = 2.4; 29 | double num = VarTestKt.num; 30 | } 31 | 32 | void test3() { 33 | VarTestClass varTestClass = new VarTestClass(); 34 | // varTestClass.num = 3 35 | varTestClass.getNum(); 36 | varTestClass.setNum(3); 37 | } 38 | 39 | void test4() { 40 | 41 | } 42 | 43 | void test(String... names) { 44 | for (String name : names) { 45 | Log.d("fish", name); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/varclass/TestJavaActivity.java: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.varclass; 2 | 3 | import android.os.Bundle; 4 | import android.widget.Toast; 5 | 6 | import com.fish.kotlindemo.coroutinestory.JavaStudent; 7 | import com.fish.kotlindemo.coroutinestory.StudentInfo; 8 | import com.fish.kotlindemo.funclass.Student; 9 | 10 | import androidx.annotation.Nullable; 11 | import androidx.appcompat.app.AppCompatActivity; 12 | 13 | public class TestJavaActivity extends AppCompatActivity { 14 | @Override 15 | protected void onCreate(@Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) { 16 | super.onCreate(savedInstanceState); 17 | } 18 | 19 | private void click() { 20 | JavaStudent javaStudent = new JavaStudent(); 21 | StudentInfo studentInfo = javaStudent.getWithoutThread(999); 22 | Toast.makeText(this, "学生姓名:" + studentInfo.getName(), Toast.LENGTH_LONG).show(); 23 | } 24 | 25 | private void onClick2() { 26 | JavaStudent javaStudent = new JavaStudent(); 27 | javaStudent.getStuInfoAsync(999, new JavaStudent.Callback() { 28 | @Override 29 | public void onCallback(StudentInfo studentInfo) { 30 | //异步调用,回调从子线程返回,需要切换到主线程更新UI 31 | runOnUiThread(() -> { 32 | Toast.makeText(TestJavaActivity.this, "学生姓名:" + studentInfo.getName(), Toast.LENGTH_LONG).show(); 33 | }); 34 | } 35 | }); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/varclass/VarTest.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.varclass 2 | 3 | //kotlin 4 | //变量 5 | @JvmField 6 | var num = 3.4 7 | 8 | 9 | //常量 10 | 11 | val age = 4 12 | 13 | ////java 14 | ////变量 15 | //int num = 3; 16 | ////常量 17 | //final int age = 4; 18 | 19 | @JvmField 20 | var numInt: Int = 4 21 | var numLong: Long = 5 22 | 23 | //kotlin 转换 24 | @JvmName("test2") 25 | fun test() { 26 | //不被允许 27 | // numInt = numLong 28 | // numLong = numInt 29 | 30 | //允许 31 | //大范围转小范围可能会发生溢出 32 | numInt = numLong.toInt() 33 | numLong = numInt.toLong() 34 | } 35 | 36 | //Java 转换 37 | //void test() { 38 | // int a = 5; 39 | // //小转大 允许 40 | // long b = a; 41 | // //大转小 允许 42 | // a = (int) b; 43 | //} 44 | 45 | //初始化 46 | //初始 47 | var myAge = 3 48 | 49 | //正常初始化 50 | val myNum = 4 51 | 52 | //延迟初始化 常量 53 | val myNum2: Int by lazy { 3 } 54 | 55 | class MyBean { 56 | var age = 3 57 | } 58 | 59 | //正常初始化 60 | val myBean = MyBean() 61 | 62 | //延迟初始化 63 | val myBean1: MyBean by lazy { 64 | MyBean() 65 | } 66 | 67 | //变量正常初始化 68 | var name: String = "fish" 69 | 70 | //变量延迟初始化 71 | lateinit var name1: String 72 | 73 | fun useName() { 74 | name1 = "fish1" 75 | } 76 | 77 | ////错误,不能修饰基本类型 78 | //lateinit var num3:Int 79 | ////错误,不能修饰空类型 80 | //lateinit var name2?:String 81 | 82 | //get set 方式 83 | 84 | var myName: String = "" 85 | get() { 86 | //获取值 87 | var age = 2 88 | if (age > 18) 89 | return field 90 | return "" 91 | } 92 | set(value) { 93 | //设置值 94 | if (value == "fish") 95 | field = value 96 | } 97 | 98 | fun test4(name : String):String { 99 | return "hello" 100 | } 101 | 102 | fun test5(name: String) { 103 | } 104 | -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/varclass/VarTestClass.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.varclass 2 | 3 | 4 | class VarTestClass { 5 | // @JvmField 6 | var num:Int = 3; 7 | } -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/vm/MyViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.vm 2 | 3 | import androidx.lifecycle.LiveData 4 | import androidx.lifecycle.MutableLiveData 5 | import androidx.lifecycle.ViewModel 6 | import androidx.lifecycle.viewModelScope 7 | import com.fish.kotlindemo.repository.MyRepo 8 | import kotlinx.coroutines.Dispatchers 9 | import kotlinx.coroutines.launch 10 | import kotlinx.coroutines.withContext 11 | 12 | class MyViewModel() : ViewModel() { 13 | 14 | private val _liveData = MutableLiveData() 15 | 16 | val livedata:LiveData 17 | get() = _liveData 18 | 19 | val repo = MyRepo() 20 | fun getInfo(block:(String)->Unit) { 21 | viewModelScope.launch { 22 | val result = repo.getInfo() 23 | withContext(Dispatchers.Main) { 24 | block(result) 25 | } 26 | 27 | _liveData.postValue("hello world") 28 | } 29 | } 30 | 31 | override fun onCleared() { 32 | super.onCleared() 33 | println("hello") 34 | } 35 | } -------------------------------------------------------------------------------- /app/src/main/java/com/fish/kotlindemo/vm/MyViewModel2.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo.vm 2 | 3 | import androidx.lifecycle.* 4 | import kotlinx.coroutines.delay 5 | import kotlinx.coroutines.flow.* 6 | import kotlinx.coroutines.flow.SharingStarted.Companion.WhileSubscribed 7 | import kotlinx.coroutines.launch 8 | 9 | class MyViewModel2 : ViewModel() { 10 | 11 | val livedata1 = MediatorLiveData() 12 | private val livedata2 = MutableLiveData() 13 | 14 | val livedata3:LiveData = livedata2.switchMap { 15 | val md = getFlow().asLiveData(viewModelScope.coroutineContext) 16 | md 17 | }.map { 18 | "helloxxx $it" 19 | } 20 | 21 | fun test() { 22 | viewModelScope.launch { 23 | flow { 24 | emit("hello") 25 | }.transform { 26 | emit("jj") 27 | }.mapLatest { 28 | 29 | } 30 | } 31 | 32 | livedata1.addSource(livedata2) { 33 | println("livedata $it") 34 | livedata1.value = it 35 | } 36 | } 37 | 38 | fun getFlow():Flow { 39 | return flow { 40 | emit("I'm flow") 41 | } 42 | } 43 | 44 | fun update() { 45 | livedata2.value = "fuck" 46 | } 47 | 48 | fun testLife() { 49 | viewModelScope.launch { 50 | println("fragment continue1") 51 | delay(5000) 52 | println("fragment continue2") 53 | } 54 | } 55 | 56 | override fun onCleared() { 57 | super.onCleared() 58 | } 59 | } -------------------------------------------------------------------------------- /app/src/main/proto/login_info.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | //指定生成类的包名 4 | option java_package = "com.fish.kotlindemo.test"; 5 | option java_multiple_files = true; 6 | 7 | //message 可以类比class 8 | //编译后,自动生成对应的class 9 | message LoginInfo { 10 | //定义字段, 1,2表示字段顺序而非具体值 11 | int64 userId = 1; 12 | string userName = 2; 13 | } 14 | -------------------------------------------------------------------------------- /app/src/main/proto/user_prefs.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | option java_package = "com.fish.kotlindemo.test"; 4 | option java_multiple_files = true; 5 | 6 | message UserPreferences { 7 | // filter for showing / hiding completed tasks 8 | bool show_completed = 1; 9 | int32 count = 2; 10 | string name = 3; 11 | Pick pick = 4; 12 | } 13 | 14 | message Pick { 15 | string country = 1; 16 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 15 | 18 | 21 | 22 | 23 | 24 | 30 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_dashboard_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_home_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 15 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 | 65 | 70 | 75 | 80 | 85 | 90 | 95 | 100 | 105 | 110 | 115 | 120 | 125 | 130 | 135 | 140 | 145 | 150 | 155 | 160 | 165 | 170 | 171 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_notifications_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_datastore.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 19 | 20 | 30 | 31 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 20 | 21 | 22 | 35 | 36 | 46 | 47 | 57 | 58 | 68 | 69 | 80 | 81 | 92 | 93 | 104 | 105 | 116 | 117 | 128 | 129 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_second.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 19 | 20 | 30 | 31 | 41 | 42 | 53 | 54 | 65 | 66 | 77 | 78 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_dashboard.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 22 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_home.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 22 | 23 | 34 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_notifications.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 22 | -------------------------------------------------------------------------------- /app/src/main/res/layout/layout_fragment.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/menu/bottom_nav_menu.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 13 | 14 | 18 | 19 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishforest/KotlinDemo/b8534218aa3484d0720f541ef839fcb7ed7b326a/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishforest/KotlinDemo/b8534218aa3484d0720f541ef839fcb7ed7b326a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishforest/KotlinDemo/b8534218aa3484d0720f541ef839fcb7ed7b326a/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishforest/KotlinDemo/b8534218aa3484d0720f541ef839fcb7ed7b326a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishforest/KotlinDemo/b8534218aa3484d0720f541ef839fcb7ed7b326a/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishforest/KotlinDemo/b8534218aa3484d0720f541ef839fcb7ed7b326a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishforest/KotlinDemo/b8534218aa3484d0720f541ef839fcb7ed7b326a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishforest/KotlinDemo/b8534218aa3484d0720f541ef839fcb7ed7b326a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishforest/KotlinDemo/b8534218aa3484d0720f541ef839fcb7ed7b326a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishforest/KotlinDemo/b8534218aa3484d0720f541ef839fcb7ed7b326a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/navigation/mobile_navigation.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 13 | 14 | 19 | 20 | 25 | -------------------------------------------------------------------------------- /app/src/main/res/values-night/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #FFBB86FC 4 | #FF6200EE 5 | #FF3700B3 6 | #FF03DAC5 7 | #FF018786 8 | #FF000000 9 | #FFFFFFFF 10 | -------------------------------------------------------------------------------- /app/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16dp 4 | 16dp 5 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | KotlinDemo 3 | Home 4 | Dashboard 5 | Notifications 6 | -------------------------------------------------------------------------------- /app/src/main/res/values/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16 | -------------------------------------------------------------------------------- /app/src/test/java/com/fish/kotlindemo/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package com.fish.kotlindemo 2 | 3 | import org.junit.Test 4 | 5 | import org.junit.Assert.* 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * See [testing documentation](http://d.android.com/tools/testing). 11 | */ 12 | class ExampleUnitTest { 13 | @Test 14 | fun addition_isCorrect() { 15 | assertEquals(4, 2 + 2) 16 | } 17 | } -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | buildscript { 3 | ext.kotlin_version = "1.5.31" 4 | repositories { 5 | google() 6 | mavenCentral() 7 | } 8 | dependencies { 9 | classpath "com.android.tools.build:gradle:4.2.0" 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.17' 12 | // NOTE: Do not place your application dependencies here; they belong 13 | // in the individual module build.gradle files 14 | } 15 | } 16 | 17 | allprojects { 18 | repositories { 19 | google() 20 | mavenCentral() 21 | } 22 | } 23 | 24 | task clean(type: Delete) { 25 | delete rootProject.buildDir 26 | } -------------------------------------------------------------------------------- /config.gradle: -------------------------------------------------------------------------------- 1 | 2 | ext { 3 | user='lishi' 4 | age = 6 5 | } -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | # IDE (e.g. Android Studio) users: 3 | # Gradle settings configured through the IDE *will override* 4 | # any settings specified in this file. 5 | # For more details on how to configure your build environment visit 6 | # http://www.gradle.org/docs/current/userguide/build_environment.html 7 | # Specifies the JVM arguments used for the daemon process. 8 | # The setting is particularly useful for tweaking memory settings. 9 | org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 10 | # When configured, Gradle will run in incubating parallel mode. 11 | # This option should only be used with decoupled projects. More details, visit 12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 13 | # org.gradle.parallel=true 14 | # AndroidX package structure to make it clearer which packages are bundled with the 15 | # Android operating system, and which are packaged with your app"s APK 16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 17 | android.useAndroidX=true 18 | # Kotlin code style for this project: "official" or "obsolete": 19 | kotlin.code.style=official 20 | android.enableJetifier=true -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fishforest/KotlinDemo/b8534218aa3484d0720f541ef839fcb7ed7b326a/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Tue May 10 20:44:49 CST 2022 2 | distributionBase=GRADLE_USER_HOME 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip 4 | distributionPath=wrapper/dists 5 | zipStorePath=wrapper/dists 6 | zipStoreBase=GRADLE_USER_HOME 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn () { 37 | echo "$*" 38 | } 39 | 40 | die () { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Escape application args 158 | save () { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = "KotlinDemo" 2 | include ':app' 3 | --------------------------------------------------------------------------------