基礎學習day08——Service

1 進程概念介紹
  四大組件都是運行在主線程 
  Android中的服務 也是在後臺運行  可以理解成是在後臺運行並且是沒有界面的Activity

  (1)Foreground process 前臺進程  用戶正在交互  可以理解成相 當於 Activity執行onResume方法
  (2)Visible process 可視進程 用戶沒有在交互 但用戶還一直能看得見頁面 相當於Activity執行了onPause方法 
  (3)Service Process  服務進程  通過startService()開啓了一個服務
  (4)Background process  後臺進程  當前用戶看不見頁面 相當於Activity執行了onStop方法
  (5)Empty process 空進程


2 start方式開啓服務的特點
  服務是在後臺運行 可以理解成是沒有界面的activity
  定義四大組件的方式都是一樣的  
  定義一個類繼承Service
  
  特點:
  (1)服務通過startservice方式開啓 第一次點擊按鈕開啓服務 會執行服務的onCreate 和 onStart方法
  (2)如果第二次開始在點擊按鈕開啓服務 服務之後執行onStrat方法
  (3)服務被開啓後 會在設置頁面裏面的 running裏面找得到這個服務 
  ***(4)startservice 方式開啓服務 服務就會在後臺長期運行 直到用戶手工停止 或者調用StopService方法 服務纔會被銷燬
 


#bindService 方式開啓服務的特點 
 09-10 03:15:00.603: E/ActivityThread(11793): Activity com.itheima.service.MainActivity has leaked ServiceConnection com.itheima.service.MainActivity$MyConn@b6445bf8 that was originally bound here
09-10 03:15:00.603: E/ActivityThread(11793): android.app.ServiceConnectionLeaked: Activity com.itheima.service.MainActivity has leaked ServiceConnection com.itheima.service.MainActivity$MyConn@b6445bf8 that was originally bound here
  
  (1)當點擊按鈕第一次開啓服務 會執行服務的onCreate方法 和 onBind()方法
   (2) 當我第二次點擊按鈕在調用bindservice  服務沒有響應 
   **(3) 當activity銷燬的時候服務也銷燬  不求同時生但求同時死 
  (4)通過bind方式開啓服務  服務不能再設置頁面裏面找到  相當於是一個隱形的服務
  (5)bindservice不能多次解綁 多次解綁會報錯

3 電話竊聽器案例
  new Thread(){}.start();  服務有啥區別 股票應用
  實現步驟 
  (1)先定義一個服務 服務用來監聽電話狀態 開啓服務
  (2)在服務的oncreate方法裏面實例化TelephoneManager類的實例  
  
  (3)註冊一個電話監聽 
   
    (4)定義一個電話監聽的類 代碼如下 
  1. //監聽電話的狀態
    	private class MyPhoneStateListenrer extends PhoneStateListener{
    		//當設備的狀態發生改變的時候調用
    		@Override
    		public void onCallStateChanged(int state, String incomingNumber) {
    			
    			//[3]具體判斷一下  電話是處於什麼狀態
    			switch (state) {
    			case TelephonyManager.CALL_STATE_IDLE:  //空閒狀態
    				
    				break;
    				
    			case TelephonyManager.CALL_STATE_OFFHOOK://接聽狀態 
    				
    				System.out.println("開始錄");
    				break;
    				
    			case TelephonyManager.CALL_STATE_RINGING:  //響鈴狀態
    				System.out.println("我準備一個錄音機出來 ");
    				break;
    			}
    			
    			
    			
    			super.onCallStateChanged(state, incomingNumber);
    		}
    		
    	}

(5) 實現錄音的功能 
  1. //[1]獲取MediaRecorder類的實例
    				recorder = new MediaRecorder();
    				//[2]設置音頻的來源
    				 recorder.setAudioSource(MediaRecorder.AudioSource.MIC); //zet 
    				 //[3]設置音頻的輸出格式 
    				 recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
    				 //[4]設置音頻的編碼方式 
    				 recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
    				 //[5]保存的文件路徑
    				 recorder.setOutputFile("/mnt/sdcard/luyin.3gp");
    				 //[5]準備錄音
    				 try {
    					recorder.prepare();
    				} catch (IllegalStateException e) {
    					e.printStackTrace();
    				} catch (IOException e) {
    					e.printStackTrace();
    				}

 (6)記得加上相應的權限 
  <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  <uses-permission android:name="android.permission.RECORD_AUDIO" />
  <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>




   
4 使用服務註冊特殊的廣播接收者
   (1)創建我們要註冊的廣播接收者 
  1. public class ScreenReceiver extends BroadcastReceiver {
    	@Override
    	public void onReceive(Context context, Intent intent) {
    		//獲取廣播事件的類型
    		String action = intent.getAction();
    		
    		if ("android.intent.action.SCREEN_OFF".equals(action)) {
    			
    			System.out.println("說明屏幕鎖屏了");
    		}else if("android.intent.action.SCREEN_ON".equals(action)){
    			
    			System.out.println("說明屏幕解鎖了");
    		}
    		
    		
    		
    	}
    }

(2)創建一個服務 用來註冊廣播接收者  代碼如下
  1. package com.itheima.registerbroadcast;
    import android.app.Service;
    import android.content.Intent;
    import android.content.IntentFilter;
    import android.os.IBinder;
    public class ScreenService extends Service {
    	
    	private ScreenReceiver receiver;
    	@Override
    	public IBinder onBind(Intent intent) {
    		return null;
    	}
    	
    	//當服務第一次啓動的時候調用
    	@Override
    	public void onCreate() {
    		
    		//在這個方法裏面註冊廣播接收者
    		//[1]獲取ScreenReceiver實例
            receiver = new ScreenReceiver();
    		
            //[2]創建IntentFilter對象
    		IntentFilter filter = new IntentFilter();
    		//[3]添加註冊的事件
    		filter.addAction("android.intent.action.SCREEN_OFF");
    		filter.addAction("android.intent.action.SCREEN_ON");
    		//[4]通過代碼的方式註冊
    		registerReceiver(receiver, filter);
    		
    		super.onCreate();
    	}
    	
    	//當服務銷燬的時候調用
    	@Override
    	public void onDestroy() {
    		
    		//當actvivity銷燬的時候  取消註冊廣播接收者 
    		unregisterReceiver(receiver);
    				
    		
    		super.onDestroy();
    	}
    }

(3)一定要記得配置service
  
 

 
6 爲什麼要引入bindService
  目的爲了調用服務裏面的方法

7 通過bindservice方式調用服務方法裏面的過程
  (1)定義一個服務 服務裏面有一個方法需要Activity調用
      
  (2)定義一箇中間人對象(IBinder) 繼承Binder; 
     

  (3)在onbind方法裏面把我們定義的中間人對象返回  
     
  (4)在Activity的oncreate 方法裏面調用bindservice 目的是爲來獲取我們定義的中間人對象
    

  (4.1)獲取中間人對象
   

  (5)拿到中間人對象後就可以間接的調用到服務裏面的方法 
      

8 通過接口方式調用服務裏面的方法
  接口可以隱藏代碼內部的細節 讓程序員暴露自己只想暴露的方法
  (6)定義一個接口 把想暴露的方法都定義在接口裏面 
  (7)我們定義的中間人對象 實現我們定義的接口
  (8)在獲取我們定義的中間人對象方式變了
      
    
9 百度音樂盒框架
  需求:我既想讓服務在後臺長期運行  又想調用服務裏面的方法  
  混合方式開啓服務 
  (1)先調用startService()方法 保證服務在後臺長期運行
  (2)調用bindservice()目的獲取我們定義的中間人對象 調用服務裏面的方法
  (3)unbindservice() 看這時候服務會不會銷燬
  (4)最後調用stopservice() 停止服務 
    

10 aidl介紹
  (1)遠程服務 運行在其他應用裏面的服務  
  (2)本地服務 運行在自己應用裏面的服務 
  (3)進行進程間通信  IPC
  (4)aidl Android interface Defination Language Android接口定義語言 專門是用來解決進程間通信的 
  
 aidl 實現步驟和之前調用服務裏面的方法的區別 
 (1)先把Iservice.java文件變成aidl文件 
 (2)adil 不認識public 把public 給我去掉
 (3)會自動生成一個Stub類 實現ipc 
 (4)我們定義的中間人對象 直接繼承stub
 (5)想要保證2個應用程序的aidl文件是同一個 要求aidl文件所在包名相同
 (6)獲取中間人對象Stub.asinterface(Ibinder obj) 

11 aidl的應用場景 
 支付寶  非常有名 支付的方法  


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章