Presentation is loading. Please wait.

Presentation is loading. Please wait.

Android + Service 建國科技大學 資管系 饒瑞佶.

Similar presentations


Presentation on theme: "Android + Service 建國科技大學 資管系 饒瑞佶."— Presentation transcript:

1 Android + Service 建國科技大學 資管系 饒瑞佶

2 Android Service Android中的Service與Activity不同,Service不具有UI 介面,不能自己啟動

3 Android Service life cycle
Android Service的生命週期不同於Activity, Service的生命 週期只有onCreate(),onStart(),onDestroy()三個方法 第一次啟動Service時,首先執行onCreate(),再執行 onStart()方法 停止Service則是執行onDestroy()方法 如果Service已經啟動,再次啟動Service時,將不再執行 onCreate()方法,而是直接執行onStart()方法

4 Service life cycle 不牽涉到Activity與Service兩邊互動與資料傳輸

5 Service lifecycle Activity與Service需要互相傳輸使用 Activity單純呼叫Service

6 Activity呼叫Service內的方法 Service做一個計時器方法,Activity呼叫後取得結果顯示在畫面上
Android bound service Activity呼叫Service內的方法 Service做一個計時器方法,Activity呼叫後取得結果顯示在畫面上

7 建立一個Service-BoundService

8 Service名稱

9 會自動註冊到AndroidManidest.xml中

10 預設有BoundService與onBind事件

11 Service lifecycle Activity與Service需要互相傳輸使用 Activity單純呼叫Service

12 加入onCreate事件

13 onCreate事件

14 public class BoundService extends Service {
private static String LOG_TAG = "ServiceTest"; // debug用 private Chronometer mChronometer; // 計時器 public BoundService() { } @Override public void onCreate() { super.onCreate(); Log.v(LOG_TAG, "onCreate"); mChronometer = new Chronometer(this); mChronometer.setBase(SystemClock.elapsedRealtime()); mChronometer.start(); // 開始計時

15 onBind事件 @Override public IBinder onBind(Intent intent) {
Log.v(LOG_TAG, "onBind2"); return mBinder; }

16 建立Activity與Service間聯繫(bind)
private IBinder mBinder = new MyBinder(); public class MyBinder extends Binder { BoundService getService() { return BoundService.this; }

17 加入onRebind與onUnbind與onDestroy事件

18 加入對應的事件程式 @Override public void onRebind(Intent intent) {
Log.v(LOG_TAG, "onRebind"); super.onRebind(intent); } public boolean onUnbind(Intent intent) { Log.v(LOG_TAG, "onUnbind"); return true; public void onDestroy() { super.onDestroy(); Log.v(LOG_TAG, "onDestroy"); mChronometer.stop();

19 Service中加入計時程式 // 等待Activity呼叫使用 public String getTimestamp() {
long elapsedMillis = SystemClock.elapsedRealtime() - mChronometer.getBase(); int hours = (int) (elapsedMillis / ); int minutes = (int) (elapsedMillis - hours * ) / 60000; int seconds = (int) (elapsedMillis - hours * minutes * 60000) / 1000; int millis = (int) (elapsedMillis - hours * minutes * seconds * 1000); return hours + ":" + minutes + ":" + seconds + ":" + millis; }

20 layout <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android=" xmlns:tools=" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="edu.ctu.rcjao.androidservice.MainActivity"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:text="從Service取出計時時間" /> <TextView android:text="" /> android:text="停止Service" /> </LinearLayout> layout

21 設定Activity bind Service

22 public class MainActivity extends AppCompatActivity {
BoundService mBoundService; // Service boolean mServiceBound = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 對應畫面物件 final TextView timestampText = (TextView) findViewById(R.id.timestamp_text); Button printTimestampButton = (Button) findViewById(R.id.print_timestamp); Button stopServiceButon = (Button) findViewById(R.id.stop_service); // 從Service取出計時時間 printTimestampButton.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { if (mServiceBound) { // 如果已經bind,呼叫Service內的getTimestamp方法 timestampText.setText(mBoundService.getTimestamp()); } }); // 停止Service stopServiceButon.setOnClickListener(new View.OnClickListener() { if (mServiceBound) { // 如果已經bind,切斷Service unbindService(mServiceConnection); mServiceBound = false; Intent intent = new Intent(MainActivity.this, BoundService.class); stopService(intent); 呼叫Service 停止Service

23 建立onStart與onStop @Override protected void onStart() { super.onStart();
Intent intent = new Intent(this, BoundService.class); startService(intent); bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE); } protected void onStop() { super.onStop(); if (mServiceBound) { unbindService(mServiceConnection); mServiceBound = false;

24 建立mServiceConnection
private ServiceConnection mServiceConnection = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { mServiceBound = false; } public void onServiceConnected(ComponentName name, IBinder service) { BoundService.MyBinder myBinder = (BoundService.MyBinder) service; mBoundService = myBinder.getService(); mServiceBound = true; };

25 result 每按一次取出經過的時間

26 執行log

27 從Service更新Activity Service呼叫Activity方法

28 Layout加入一個TextView 用來顯示Service更新的資料
android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:text="" />

29 修改Service,加入callback
Callbacks activity; //宣告 // 加入callbacks interface(需要到Activity實作updateClient) public interface Callbacks{ public void updateClient(long data); } // 註冊Activity 成為Callbacks client public void registerClient(Activity activity){ this.activity = (Callbacks)activity;

30 修改Service,加入計時與更新Activity
// 開始計時 private long startTime = 0; private long millis = 0; public void startCounter(){ // 由Activity發動 startTime = System.currentTimeMillis(); handler.postDelayed(serviceRunnable, 0); Toast.makeText(getApplicationContext(), "開始計時", Toast.LENGTH_SHORT).show(); } // 停止計時 public void stopCounter(){ handler.removeCallbacks(serviceRunnable); Handler handler = new Handler(); Runnable serviceRunnable = new Runnable() { @Override public void run() { millis = System.currentTimeMillis() - startTime; activity.updateClient(millis); // 透過callback更新Activity handler.postDelayed(this, 1000); };

31 修改Activity 繼承Callback 會被要求實作updateClient

32 加入畫面TextView物件對應

33 開始與停止計時

34 註冊Activity到Service

35 @Override public void updateClient(long data) { int seconds = (int) (data / 1000) % 60 ; int minutes = (int) ((data / (1000*60)) % 60); int hours = (int) ((data / (1000*60*60)) % 24); timestampTextfromservice.setText((hours>0 ? String.format("%d:", hours) : "") + ((minutes<10 && hours > 0)? "0" + String.format("%d:", minutes) : String.format("%d:", minutes)) + (seconds<10 ? "0" + seconds: seconds)); }

36 Service 範例 播放音樂

37 單純呼叫

38 Service流程

39 新增一組Activity與layout

40 MediaController.java

41 <LinearLayout xmlns:android="http://schemas. android
xmlns:tools=" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="edu.ctu.rcjao.androidservice.MediaController" android:orientation="vertical"> <TextView android:text="" android:layout_height="wrap_content" " android:textSize="30sp" /> <Button android:text="播放" android:text="繼續播放" android:text="暫停" android:text="停止" </LinearLayout> layout 顯示播放狀態

42 加入OnClickListener

43 設定對應畫面物件

44 public class MediaController extends AppCompatActivity implements View
public class MediaController extends AppCompatActivity implements View.OnClickListener { Button buttonPlay, buttonContinuePlay, buttonStop, buttonPause; TextView textState; Intent intent; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_media_controller); // 對應layout物件 buttonPlay = (Button) findViewById(R.id.Play); buttonContinuePlay = (Button) findViewById(R.id.ContinuePlay); buttonPause = (Button) findViewById(R.id.Pause); buttonStop = (Button) findViewById(R.id.Stop); textState = (TextView)findViewById(R.id.textState); // 設定onclick事件 buttonPlay.setOnClickListener(this); buttonStop.setOnClickListener(this); buttonPause.setOnClickListener(this); buttonContinuePlay.setOnClickListener(this); intent = new Intent(this, MusicService.class); //透過intent啟動Service }

45 onClick @Override public void onClick(View v) { switch (v.getId()) {
case R.id.Play: playAction(1); textState.setText("- Playing -"); buttonPlay.setEnabled(false); buttonContinuePlay.setEnabled(false); buttonPause.setEnabled(true); buttonStop.setEnabled(true); break; case R.id.ContinuePlay: playAction(2); case R.id.Pause: playAction(3); textState.setText("- Pause -"); buttonPlay.setEnabled(true); buttonContinuePlay.setEnabled(true); buttonPause.setEnabled(false); case R.id.Stop: playAction(4); textState.setText("- Stop -"); buttonStop.setEnabled(false); } onClick

46 新增playAction方法 // 執行的播放動作 private void playAction(int op) {
Bundle bundle = new Bundle(); bundle.putInt("op", op); //設定intent啟動的動作 intent.putExtras(bundle); MediaController.this.startService(intent); //啟動service,透過intent傳送資料 }

47 建立Service-MusicService
會自動註冊到AndroidManifest.xml中

48 建立播放音樂物件

49 加入onStart 音樂檔 @Override
public void onStart(Intent intent, int startId) { //完成onCreate()後啟動 if (intent != null) { Bundle bundle = intent.getExtras(); if (bundle != null) { int op = bundle.getInt("op"); switch (op) { case 1: //play player=MediaPlayer.create(this, R.raw.test) ; player.start(); break; case 2: //replay case 3: //pause player.pause(); case 4: //stop if (player != null) { player.stop(); } 加入onStart 音樂檔

50 加入onStop @Override public void onDestroy() { super.onDestroy();
if (player != null) { player.stop(); player.release(); }

51 執行 當App在背景時,音樂仍然會繼續播放


Download ppt "Android + Service 建國科技大學 資管系 饒瑞佶."

Similar presentations


Ads by Google