一、进程概念介绍
【1】Android下四大组件都是运行在主线程中
【2】服务是在后台运行 可以理解为是没有界面的activity
进程的优先级
【1】Foreground process 前台进程 优先级最高 相当于activity进行了onResume 方法 用户用户交互
【2】Visible process 可视进程 一直影响用户看得见 相当于activity执行了onPause方法
【3】service process 服务进程 通过startService 方法开启了一个服务
【4】background process后台进程 相当于activity 执行了onStop方法 界面不可见 但activity并没有被销毁
【5】Empty process 空进程 不会维持任何组件运行
二、start方式开启服务的特点
【1】定义四大组件的方式是一样的
【2】定义一个类继承Service
【3】第一次点击按钮开启服务 服务执行onCreate方法和onStart方法
【4】第二次点击按钮 再次开启服务 服务执行onStart方法
【5】服务一旦被开启 服务就会在后台长期运行 直到用户手动停止
补充:股票应用 实时去服务器去数据更新
三、电话窃听器案例
【1】SmsManager
【2】TelephoneManager
实现步骤
【1】定义一个服务 开启服务 记得在清单文件配置服务
【2】在服务的onCreate方法里面 获取TelephoneManager
//[1]获取telephonemanager的实例 TelephonyManager tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
【3】注册电话的监听
//[2]注册电话的监听 tm.listen(new MyPhoneStateListener(), PhoneStateListener.LISTEN_CALL_STATE);【4】定义一个类用来监听电话的状态
//定义一个类来监听电话的状态 private class MyPhoneStateListener 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; default: break; } super.onCallStateChanged(state, incomingNumber); } }
【5】准备一个录音机
//[1]创建MediaRecorder 实例 recorder = new MediaRecorder(); //[2]设置音频的来源 recorder.setAudioSource(MediaRecorder.AudioSource.VOICE_CALL); //[3]设置输出的格式 recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); //[4]设置音频的编码方式 recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); //[5]设置存放的路径 recorder.setOutputFile("/mnt/sdcard/luyin.3gp"); try { recorder.prepare(); } catch (IOException e) { e.printStackTrace(); }
recorder.start();
if(recorder!=null){ recorder.stop(); //停止录音 recorder.reset(); //重置 recorder.release(); //释放资源 }
【6】把开启服务的逻辑放到手机重启的广播中
public class BootRecevier extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { //把服务开启 Intent intent1 = new Intent(context, PhoneService.class); context.startService(intent1); } }
四、使用服务注册特殊的广播接受者
操作特别频繁的广播事件 比如屏幕的解锁和锁屏
实现步骤
【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】写一个服务 用来注册广播接受者
public class ScreenService extends Service { private ScreenReceiver receiver; @Nullable @Override public IBinder onBind(Intent intent) { return null; } @Override public void onCreate() { //[1]创建ScreenReceiver 实例 receiver = new ScreenReceiver(); //[2]获取IntentFilter 实例 目的是添加action IntentFilter filter = new IntentFilter(); //[3]添加action filter.addAction("android.intent.action.SCREEN_OFF"); filter.addAction("android.intent.action.SCREEN_ON"); //[4]动态接受广播接受者 registerReceiver(receiver, filter); super.onCreate(); } @Override public void onDestroy() { //当服务销毁的时候 取消注册广播接受者 unregisterReceiver(receiver); super.onDestroy(); } }【3】在mainActivity的onCreate方法里面开启服务
//开启服务 Intent intent = new Intent(this, ScreenService.class); startService(intent);【4】一定要记得配置服务
五、bindService开启服务特点
六、为什么要引入bindService
目的是为了调服务里的方法
七、通过bindService方式调用服务方法里面的过程
//办证的方法 public void banZheng(int money) { if(money > 1000) { Toast.makeText(getApplicationContext(), "我是领导 把证给你办了", Toast.LENGTH_LONG).show(); } else { Toast.makeText(getApplicationContext(), "就这点钱 还想办事...", Toast.LENGTH_LONG).show(); } }[2]在服务的内容定义一个中间人对象(IBinder)
//[1]定义中间人对象(IBinder) public class MyBinder extends Binder { public void callBanZheng(int money){ //调用办证的方法 banZheng(money); } }[3]把我定义的中间人对象 在onBind方法返回
//把我定义的中间人对象返回 @Nullable @Override public IBinder onBind(Intent intent) { return new MyBinder(); }[4]在mainActivity的onCreate方法里面调用bindservice 的目的是为了获取我们定义的中间人对象
Intent intent = new Intent(this, BanZhengService.class); //连接服务 conn = new MyConn(); bindService(intent, conn, BIND_AUTO_CREATE);
[5]获取中间人对象
//监视服务的状态 private class MyConn implements ServiceConnection{ //当服务连接成功 @Override public void onServiceConnected(ComponentName componentName, IBinder iBinder) { //获取中间人对象 myBinder = (BanZhengService.MyBinder) iBinder; } //失去连接 @Override public void onServiceDisconnected(ComponentName componentName) { } }[6]拿到了中间人对象 就可以间接调用到服务里面的方法
[7]当Activity销毁的时候 解绑服务
八、通过接口方式调用服务方法里面的方法
九、百度音乐盒框架
十、aidl介绍
public static abstract class Stub extends android.os.Binder implements com.example.wzy.a9_remoteservice.IService { private static final java.lang.String DESCRIPTOR = "com.example.wzy.a9_remoteservice.IService";
//获取中间人对象 注意这里面在获取中间人对象的方式变了 和之前不一样 iService = IService.Stub.asInterface(iBinder);
十一、aidl的应用场景
支付宝 和 捕鱼达人 买豆