android開發 關於Service的研究
兩年學習android開發的時候 瞭解到Service的技術
一直沒抽出時間整理這塊內容 現在終於有時間來詳細的比較深入的編碼 理解這個Service了
一. Service與Activity
android開發是離不開Activity的 Activity相當於WIN的視窗
但是一般只有一個現實在前端 其他的Activity要麼壓到背景棧中 要麼手動銷毀掉了
而Service是可以啟動多個的 這樣多個Service就是相當是並行狀態
並且 這個Service可以和Activity保持相對獨立
換句話說 可以ActivityA中啟動Service
在ActivityB中給Service發訊息
最後在ActivityC中關閉Service
這幾個Activity輪流現實在前端
二. Service與線程
其實 理解線程的話 就很容易理解Service
Activity Service 都是在主線程中執行的 不過Activity對象是只有一個顯示在前端
而Service 不顯示在前端 並可以產生多個對象
這樣儲存在Service的資料 不會像Activity內的資料 隨著Activity銷毀而銷毀
另外可以開啟新的線程 作為幕後處理線程
完全獨立於Activity 只處理Activity發來的訊息
三. Code
manifest中
註冊2個activity 一個Service
布局
activity_main 第一個activity 給三個按鈕 開始Service 結束Service 和下一個介面
activity_sec 第二個activity 也給三個按鈕 退出介面 發送訊息2和結束Service
MainActivity的按鈕處理
public void onClick(View arg0) {// TODO Auto-generated method stub switch (arg0.getId()) { case (R.id.button_on): //啟動 Service this.startService(new Intent(this, PlayService.class)); break; case (R.id.button_off): { //停止 Service this.stopService(new Intent(this,PlayService.class)); } break; case (R.id.button_next): { //開啟另一個Activity Intent intent = new Intent(); intent.setClass(MainActivity.this, SecActivity.class); startActivity(intent); } break; default: break; }}
SecActivity的按鈕處理
public void onClick(View arg0) { switch (arg0.getId()) { case (R.id.button_esc): //退出Activity finish(); break; case (R.id.button_off): { //關閉Service this.stopService(new Intent(this,PlayService.class)); } break; case (R.id.button_step2): { //向Service發訊息 Intent intent = new Intent(this, PlayService.class); Bundle bundle = new Bundle(); bundle.putInt("op", 2); intent.putExtras(bundle); this.startService(intent); } break; default: break; }}
PlayService完整代碼
public class PlayService extends Service {private HandlerThread mHandlerThread;private Handler mPlayHandler; class PlayHandler extends Handler{ public PlayHandler(){ } public PlayHandler(Looper lp){ super(lp); } @Override public void handleMessage(Message msg) { // TODO Auto-generated method stub super.handleMessage(msg); //接收到線程處理的資料 // 注意 這裡已經不是主線程上 而是獨立的線程上 System.out.println("PlayHandler handleMessage"); System.out.println("PlayHandler thread id :"+Thread.currentThread().getId()); } }@Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub System.out.println("PlayService on onBind"); return null; } @Override public void onCreate() { // TODO Auto-generated method stub super.onCreate(); Toast.makeText(this, "Play Service Created", Toast.LENGTH_SHORT).show(); System.out.println("PlayService on onCreate"); //啟動線程 mHandlerThread= new HandlerThread("Play_Service_thread"); mHandlerThread.start(); mPlayHandler= new PlayHandler(mHandlerThread.getLooper()); } @Override public void onStart(Intent intent, int startId) { // TODO Auto-generated method stub super.onStart(intent, startId); //onStart 可以用於接收Activity發來的訊息 //注意 到這裡還是處於主線程上 Toast.makeText(this, "Play Service onStart", Toast.LENGTH_SHORT).show(); System.out.println("PlayService on onStart"); System.out.println("PlayService thread id :"+Thread.currentThread().getId()); if (intent != null) { Bundle bundle = intent.getExtras(); if (bundle != null) { int op = bundle.getInt("op"); switch (op) { case 2: //通過Message對象 轉寄給線程處理 System.out.println("PlayService on onStart step2"); Message msg = mPlayHandler.obtainMessage(); msg.sendToTarget(); break; } } }//if } @Override public void onDestroy() { // TODO Auto-generated method stub super.onDestroy(); Toast.makeText(this, "Play Service Stopped", Toast.LENGTH_SHORT).show(); System.out.println("PlayService on Destroy"); //退出線程 銷毀資料 mHandlerThread.quit(); mHandlerThread = null; mPlayHandler = null; }}
Service的產生與銷毀都可以在Activity內調用
但是Service的生命週期不等於Activity 而是在主線程 這是得注意的地方