第十章 Service
-
多线程
-
Thread
Thread { // todo }.start() thread { // todo } -
Handler
class ThreadActivity : BaseActivity() { val updateText = 1 private lateinit var textView: TextView override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_thread) textView = findViewById(R.id.textView) } fun update(view: View) { thread { // Message可以在内部携带少量信息,Int型的arg1和arg2,obj字段携带Object对象 val message = Message() message.what = updateText message.arg1 handler.sendMessage(message) } } val handler = object : Handler(Looper.getMainLooper()) { override fun handleMessage(msg: Message) { super.handleMessage(msg) when (msg.what) { updateText -> { textView.text = "123" } } } } } -
AsyncTask
var myAsyncTask = object : AsyncTask<Void, Int, String>() { var count = 0 override fun onPreExecute() { super.onPreExecute() textView.text = "准备阶段" } override fun doInBackground(vararg params: Void?): String { while (count <= 100) { sleep(count.toLong()) publishProgress(count++) } return "执行完毕!" } override fun onPostExecute(result: String?) { super.onPostExecute(result) textView.text = result } override fun onProgressUpdate(vararg values: Int?) { super.onProgressUpdate(*values) textView.text = "当前进度 : ${values[0] ?: 0}%" } }
-
-
Service
-
startService()
// startService() 2021-07-11 20:34:14.855 6487-6487/com.youngly.firstlineofcode E/MyService: onCreate 2021-07-11 20:34:14.860 6487-6487/com.youngly.firstlineofcode E/MyService: onStartCommand 2021-07-11 20:34:14.860 6487-6487/com.youngly.firstlineofcode E/MyService: onStart // stopService() 2021-07-11 20:34:15.962 6487-6487/com.youngly.firstlineofcode E/MyService: onDestroy缺点:启动后就失去了与service的联系
-
bindService()
class ServiceActivity : BaseActivity() { lateinit var downloadBinder: MyService.DownloadBinder override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_service) } fun start(view: View) { startService(Intent(this, MyService::class.java)) } fun stop(view: View) { stopService(Intent(this, MyService::class.java)) } val connection = object : ServiceConnection { override fun onServiceConnected(name: ComponentName?, service: IBinder?) { downloadBinder = service as MyService.DownloadBinder } override fun onServiceDisconnected(name: ComponentName?) { } } fun bind(view: View) { bindService(Intent(this, MyService::class.java), connection, Context.BIND_AUTO_CREATE) } fun unbind(view: View) { unbindService(connection) } fun startDownload(view: View) { downloadBinder.startDownload() } fun getProgress(view: View) { downloadBinder.getProgress() } }class MyService : Service() { open class DownloadBinder : Binder() { fun startDownload() { Log.e(TAG, "startDownload") } fun getProgress(): Int { Log.e(TAG, "getProgress") return 4 } } private val downloadBinder = DownloadBinder() override fun onBind(intent: Intent): IBinder { return downloadBinder } override fun onCreate() { super.onCreate() Log.e(TAG, "onCreate") } override fun onStart(intent: Intent?, startId: Int) { super.onStart(intent, startId) Log.e(TAG, "onStart") } override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { Log.e(TAG, "onStartCommand") return super.onStartCommand(intent, flags, startId) } override fun onUnbind(intent: Intent?): Boolean { return super.onUnbind(intent) Log.e(TAG, "onUnbind") } override fun onRebind(intent: Intent?) { super.onRebind(intent) Log.e(TAG, "onRebind") } override fun onDestroy() { super.onDestroy() Log.e(TAG, "onDestroy") } }
-
-
前台Service
class ForegroundService : Service() { override fun onCreate() { super.onCreate() val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { notificationManager.createNotificationChannel( NotificationChannel( "foregroundService", "前台服务", NotificationManager.IMPORTANCE_DEFAULT ) ) } val build = NotificationCompat.Builder(this, "foregroundService") .setContentTitle("foreground Service title") .setContentText("service text") .setSmallIcon(R.drawable.ic_launcher_foreground) .setLargeIcon(BitmapFactory.decodeResource(resources, R.drawable.apple_pic)) .setContentIntent( PendingIntent.getActivity( this, 0, Intent(this, MainActivity::class.java), 0 ) ) .build() startForeground(1, build) } override fun onBind(intent: Intent): IBinder { TODO("Return the communication channel to the service.") } }// 申请权限 <uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> -
IntentService
private const val ACTION_FOO = "com.youngly.firstlineofcode.chapter10.action.FOO" private const val ACTION_BAZ = "com.youngly.firstlineofcode.chapter10.action.BAZ" private const val EXTRA_PARAM1 = "com.youngly.firstlineofcode.chapter10.extra.PARAM1" private const val EXTRA_PARAM2 = "com.youngly.firstlineofcode.chapter10.extra.PARAM2" class MyIntentService : IntentService("MyIntentService") { override fun onHandleIntent(intent: Intent?) { when (intent?.action) { ACTION_FOO -> { val param1 = intent.getStringExtra(EXTRA_PARAM1) val param2 = intent.getStringExtra(EXTRA_PARAM2) handleActionFoo(param1, param2) } ACTION_BAZ -> { val param1 = intent.getStringExtra(EXTRA_PARAM1) val param2 = intent.getStringExtra(EXTRA_PARAM2) handleActionBaz(param1, param2) } } } /** * Handle action Foo in the provided background thread with the provided * parameters. */ private fun handleActionFoo(param1: String?, param2: String?) { TODO("Handle action Foo") } /** * Handle action Baz in the provided background thread with the provided * parameters. */ private fun handleActionBaz(param1: String?, param2: String?) { TODO("Handle action Baz") } companion object { /** * Starts this service to perform action Foo with the given parameters. If * the service is already performing a task this action will be queued. * * @see IntentService */ // TODO: Customize helper method @JvmStatic fun startActionFoo(context: Context, param1: String, param2: String) { val intent = Intent(context, MyIntentService::class.java).apply { action = ACTION_FOO putExtra(EXTRA_PARAM1, param1) putExtra(EXTRA_PARAM2, param2) } context.startService(intent) } /** * Starts this service to perform action Baz with the given parameters. If * the service is already performing a task this action will be queued. * * @see IntentService */ // TODO: Customize helper method @JvmStatic fun startActionBaz(context: Context, param1: String, param2: String) { val intent = Intent(context, MyIntentService::class.java).apply { action = ACTION_BAZ putExtra(EXTRA_PARAM1, param1) putExtra(EXTRA_PARAM2, param2) } context.startService(intent) } } }MyIntentService.startActionBaz(this, "", "") -
Kotlin课堂
-
泛型实例化
Java泛型功能是通过类型擦除机制实现的。
泛型对于类型的约束只在编译期,运行的时候JVM识别不出我们在代码中指定的泛型类型。
泛型实例化:该函数必须是内联函数,声明泛型的地方必须加上
reified关键字。inline fun <reified T> getGenericType() = T::class.java可以获取到泛系实际类型的功能
泛型实例化应用:
inline fun <reified T> Activity.start() { startActivity(Intent(this, T::class.java)) } // 无参 start<ServiceActivity>()inline fun <reified T> Activity.start(block: Intent.() -> Unit) { val intent = Intent(this, T::class.java) intent.block() startActivity(intent) } // 有参 start<ServiceActivity> { putExtra("type", "") } -
协变
-
逆变
-
@UnsafeVariance
-