基础学习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的应用场景 
 支付宝  非常有名 支付的方法  


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