Androidスタディノート1-サービスを使用してタイマーを実装する



Android Study Notes 1 Use Services Implement Timers



Androidスタディノート1-サービスを使用してタイマーを実装する

李氏の要望によると、サービスを通じてタイマーを実装する必要がありますが、具体的な要件はなく、自習に頼っています。次に、開始タイミングと停止タイミングという単純な関数を設計し、対応する時間を同時に表示します。これを使用できます。サービスコンポーネントと、サービスとの対話を完了するためにサービスをバインドする方法については、以下の特定の実装を参照してください。

XMLレイアウト

1つのテキストコントロール(タイミングの表示に使用)と2つのボタンコントロール(それぞれタイミングの開始と終了に使用)のみが使用されます。レイアウトファイルは次のとおりです。
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>

全体がこんな感じなので、ここではあまり説明しません

画像



AndroidMainfest

サービスを使用するときは、必ず構成してください。構成、設定!構成、設定!そうしないと、コードを記述した後に期待される効果が得られず、困惑するような馬鹿げた振る舞いが発生する可能性があります。
サービスノードをアプリケーションノードに追加します
画像

サービス

呼び出すサービスでBinderオブジェクトを作成するには、対応するonBindメソッドとonUnbindメソッドを、新しいスレッドのonStartCommandメソッド(メソッドをカスタマイズすることもできます)で時間に設定することに注意してください。これは単純なスリープ操作です。フラグthreadDisableを同時に無効にするループを停止するには、コードは次のとおりです。

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 } }

MainActivity

メインアクティビティでは、サービスをバインドし、取得したIBinderオブジェクトを介してサービス参照を取得する必要があります。次に、サービス内のデータとメソッドを取得し、2つのボタンイベントをリッスンし、itenteを介してサービスを開始および終了し、サービスオブジェクトmyServiceを介して値をカウントし、同期しますUIを更新します。コードは次のとおりです。
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) } }

エフェクトプレビュー

仮想マシンでの実行効果

画像