Štúdia pre Android zaznamenáva služby na jednorazové použitie na implementáciu časovačov

Android Study Notes 1 Use Services Implement Timers



Štúdia pre Android zaznamenáva služby na jednorazové použitie na implementáciu časovačov

Podľa žiadosti pána Li potrebujeme implementovať časovač prostredníctvom služby, ale nie sú dané žiadne konkrétne požiadavky, a spoliehame sa na samoštúdium. Potom navrhnite jednoduchú funkciu, to znamená spustiť časovanie a zastaviť časovanie, a súčasne zobraziť zodpovedajúci čas, ktorý je možné použiť. Komponent služby a spôsob viazania služby na dokončenie interakcie so službou nájdete v konkrétnej implementácii nižšie.

Rozloženie XML

Používa sa iba jeden ovládací prvok textu (slúži na zobrazenie časovania) a dva tlačidlové ovládacie prvky (príslušné na spustenie a ukončenie časovania). Tu je súbor rozloženia:
activity_main.xml



<androidx.constraintlayout.widget.ConstraintLayout xmlns:android='http://schemas.android.com/apk/res/android' xmlns:app='http://schemas.android.com/apk/res-auto' xmlns:tools='http://schemas.android.com/tools' android:layout_width='match_parent' android:layout_height='match_parent' tools:context='.MainActivity'> <TextView android:id='@+id/tv' android:layout_width='wrap_content' android:layout_height='wrap_content' android:layout_marginTop='160dp' android:text='Hello Timer!' android:textColor='@color/colorBlack' android:textSize='36sp' app:layout_constraintLeft_toLeftOf='parent' app:layout_constraintRight_toRightOf='parent' app:layout_constraintTop_toTopOf='parent' tools:ignore='InvalidId' /> <Button android:id='@+id/btstar' android:layout_width='wrap_content' android:layout_height='wrap_content' android:text='start the timer' android:layout_marginTop='53dp' app:layout_constraintTop_toBottomOf='@+id/tv' app:layout_constraintLeft_toLeftOf='parent' app:layout_constraintRight_toRightOf='parent' >Button> <Button android:id='@+id/btend' android:layout_width='wrap_content' android:layout_height='wrap_content' android:text='End time' android:layout_marginTop='53dp' app:layout_constraintTop_toBottomOf='@+id/btstar' app:layout_constraintLeft_toLeftOf='parent' app:layout_constraintRight_toRightOf='parent' >Button> androidx.constraintlayout.widget.ConstraintLayout>

Celá vyzerá takto, takže v tejto časti nebudem príliš vysvetľovať



obrázok



AndroidMainfest

Pri používaní služby nezabudnite nakonfigurovať! Konfigurovať! Konfigurovať! V opačnom prípade môže dôjsť k nemému správaniu, ktoré po napísaní kódu nedosiahne očakávaný efekt a bude si lámať hlavu.
Pridajte uzol služby do uzla aplikácie
obrázok

Služby

Ak chcete vytvoriť objekt Binder v službe, ktorú chcete zavolať, venujte pozornosť nastaveniu zodpovedajúcich metód onBind a onUnbind v metóde onStartCommand (môžete tiež prispôsobiť metódu) pre nové vlákno, ktoré je jednoduchou operáciou spánku, a nastavte príznakové vlákno Zakázané súčasne Na zastavenie slučky je kód nasledovný

countservice.java



package com.artoria.timecount import android.app.Service import android.content.Intent import android.os.Binder import android.os.IBinder import android.util.Log import android.widget.Toast public class countservice extends Service { private volatile boolean threadDisable Thread timeThread = new Thread() public static int count private LocalBinder binder = new LocalBinder() /** * Create a Binder object and return it to the client that is used by Activity to provide an interface for data exchange */ public class LocalBinder extends Binder { // Declare a method, getService. (Provided to the client to call) countservice getService() { // Return the current object LocalService, so that we can call the public methods of Service on the client side return countservice.this } } @Override public IBinder onBind(Intent intent) { return this.binder } /** * Called when unbinding * @return */ @Override public boolean onUnbind(Intent intent) { return super.onUnbind(intent) } public int onStartCommand(Intent intent, int flags, int startId) { // Let it continue running until it is stopped. Toast.makeText(this, 'start the timer', Toast.LENGTH_LONG).show() count = 0 new Thread(new Runnable() { @Override public void run() { while (!threadDisable){ try{ timeThread.sleep(10) }catch (InterruptedException e){ e.printStackTrace() break } count++ Log.v('countservice','now:'+count) } } }).start() return START_STICKY } @Override public void onDestroy() { this.threadDisable=true super.onDestroy() Toast.makeText(this, 'Time ends', Toast.LENGTH_LONG).show() } public int getCount(){ return count } public void clear(){ count=0 } }

Hlavná činnosť

V hlavnej činnosti musíte službu zviazať, získať odkaz na službu prostredníctvom získaného objektu IBinder, potom môžete získať údaje a metódy v službe, vypočuť si udalosti dvoch tlačidiel, spustiť a ukončiť službu prostredníctvom itente, získať spočítajte hodnotu prostredníctvom objektu služby myService a synchronizujte Aktualizujte používateľské rozhranie, kód je nasledovný
MainActivity.java

package com.artoria.timecount import androidx.appcompat.app.AppCompatActivity import android.app.Service import android.content.ComponentName import android.content.Intent import android.content.ServiceConnection import android.os.Bundle import android.os.Handler import android.os.IBinder import android.util.Log import android.view.View import android.widget.Button import android.widget.TextView import java.util.Locale import java.util.Timer import java.util.TimerTask public class MainActivity extends AppCompatActivity { private countservice myService private Timer time = new Timer() private ServiceConnection conn @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) final Button star = (Button) findViewById(R.id.btstar) final Button end = (Button) findViewById(R.id.btend) final TextView tv = (TextView) findViewById(R.id.tv) final Intent t = new Intent(MainActivity.this, countservice.class) conn = new ServiceConnection() { /** * The interface method that interacts with the server is called back when the service is bound. This method gets the IBinder object passed by the bound Service. * Through this IBinder object, the interaction between the host and the Service is realized. */ @Override public void onServiceConnected(ComponentName name, IBinder service) {// Get Binder countservice.LocalBinder binder = (countservice.LocalBinder) service// Get service object myService = binder.getService() } /** * Called back when unbinding. However, it is not called under normal circumstances. Its calling time is when the Service is accidentally destroyed, * For example, this method is automatically called when the memory resources are insufficient. */ @Override public void onServiceDisconnected(ComponentName name) { myService=null } } star.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { Log.v('service', 'star') //myService.clear() bindService(t, conn, Service.BIND_AUTO_CREATE) startService(t) //myService.star() //myService.clear() TimerTask timerTask = new TimerTask() { @Override public void run() { runOnUiThread(new Runnable() { @Override public void run() { tv.setText(showtime(myService.count)) } }) } } if (time == null){ time = new Timer() } time.schedule(timerTask,0,10) } }) end.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { unbindService(conn) stopService(t) } }) } private String showtime(int t) { int s=(t/100)%60 int m=(t/6000)%60 int ms = t%100 return String.format(Locale.CHINA,'%02d : %02d : %02d',m,s,ms) } }

Ukážka efektu

Bežiaci efekt na virtuálnom stroji

obrázok