Android10
来源:互联网 发布:php程序员简历项目经验 编辑:程序博客网 时间:2024/06/05 21:52
Android10
需求_调用服务的方法
在Activity里面直接调用Service里面的方法,直接调用时行不通的.
Activity和Service 是Context的子类,不能被new,是系统框架得到的.
绑定服务调用服务方法的原理
在服务里面创建内部类,间接的去调用服务里面的方法
- 绑定服务,得到中间人的对象, onBind()方法[MyBinder对象]
- MyBinder对象,就是服务内部类的对象(中间人的对象)
- 可以拿中间人的对象,调用中间人内部类的方法
- 而内部类的方法,可以去调用外部类的方法
- 间接的调用到了,外部类方法,服务里面的方法数据了
服务内部代码的编写
public class TestService extends Service { /** * 服务内部的中间人 */ public class MyBinder extends Binder { /** * 中间人帮忙简介的调用服务的方法. * @param name 姓名 * @param money 钱 */ public void callMethodInService(String name, int money) { if (money > 200) { methodInService(name); } else { Toast.makeText(TestService.this, "这点钱不够用,我们要按照制度办事", 0).show(); } } } // 在服务成功绑定的时候 返回服务中的代理人(中间人) @Override public IBinder onBind(Intent intent) { return new MyBinder(); } @Override public void onCreate() { System.out.println("服务被创建了.."); super.onCreate(); } @Override public void onDestroy() { System.out.println("服务被销毁了.."); super.onDestroy(); } /** * 服务内部的方法,帮助你办暂住证. * @param name 姓名 */ public void methodInService(String name) { Toast.makeText(this, name + "你的暂住证办好了...", 0).show(); }}
绑定服务调用服务方法
/** * 代理人 */private MyBinder myBinder;/** * 绑定服务获取中间人 */public void bind(View view) { Intent intent = new Intent(this, TestService.class); // conn 通讯频道. BIND_AUTO_CREATE如果服务不存在,会把服务创建出来. bindService(intent, new MyConn(), BIND_AUTO_CREATE);}private class MyConn implements ServiceConnection { // 当服务被成功连接的时候调用的方法 @Override public void onServiceConnected(ComponentName name, IBinder service) { myBinder = (MyBinder) service; } // 当服务失去连接的时候调用的方法. @Override public void onServiceDisconnected(ComponentName name) { } }/** * 通过中间人调用服务里面的方法 */public void call(View view) { myBinder.callMethodInService("小XX", 250); }}
绑定服务调用方法的回顾
服务端
public IBinder onBind(Intent intent) { return new MyBinder();} public class MyBinder extends Binder{ //自定义一个方法调用methodInService public void CallMethodInService(String name , int money){ if (money >100) { methodInService(name); }else{ Toast.makeText(TestService.this, name + "钱太少了,办不了暂住证", 0).show(); } }}
Activity端
----------------------------------------- Intent intent = new Intent(this, TestService.class); bindService(intent, new MyConn(), BIND_AUTO_CREATE); public class MyConn implements ServiceConnection{ @Override public void onServiceConnected(ComponentName name, IBinder service) { myBinder = (MyBinder) service; } }public void call(View view){ myBinder.CallMethodInService("sam", 10);}
通过接口隐藏代码内部实现的细节
public interface IService { public void callMethodInService(String name,int money);}//private 和 implements IService{private class MyBinder extends Binder implements IService{ public void callMethodInService(String name, int money) { if (money > 200) { methodInService(name); }else{ Toast.makeText(TestService.this, "这点钱不够用,我们要按照制度办事", 0).show(); } } public void 洗桑拿(){ Toast.makeText(TestService.this, "走,一起去洗桑拿吧...", 0).show(); } public void 打麻将(){ Toast.makeText(TestService.this, "走,一起去打麻将吧...", 0).show(); }}-------------------------------------------------------private IService myBinder;private class MyConn implements ServiceConnection{ //当服务被成功连接的时候调用的方法 @Override public void onServiceConnected(ComponentName name, IBinder service) { myBinder = (IService) service; } //当服务失去连接的时候调用的方法. @Override public void onServiceDisconnected(ComponentName name) { }}public void call(View view){ myBinder.callMethodInService("XXX", 250);}
绑定服务的生命周期
- 绑定的方式开启服务,如果服务不存在,先执行onCreate在执行onbind
- 服务的onstart和onstartcommand方法不会被执行
- 解除绑定服务,先执行onunbind在执行ondetroy
- 多次绑定服务,服务只会被创建一次,oncreate方法只会被执行一次
- 多次绑定服务,onBind方法不会被重复调用
- 在实际开发的时候,如果需要调用服务的方法,就绑定服务,只能绑定一次
- 服务只可以被解绑一次,如果用同一个conn对象多次解绑,服务和抛出异常
两种开启服务方式比较
start的方式开启服务器
服务一旦开启,长期后台运行,服务和开启者(Activity)没有任何的关系,开启者退出了,服务还是继续在后台长期运行,开启者(Activity)不可以调用服务里面的方法,在系统设置界面可以观察到
bind的方式开启服务
不求同时生,但求同时死,如果开启者(Activity)退出了,服务也会跟者挂掉,
开启者(Activity)可以间接的利用中间人调用服务里面的方法.在系统设置界面看不到的
服务如果被开启同时被绑定,服务就停不掉了.必须解除绑定才可以停止服务
混合调用服务的生命周期
- 为了保证服务又能长期后台运行,又能调用到服务里面的方法
- 采用混合的方式开启服务
按照步骤编写代码:
- start的方式开启服务(保证服务长期后台运行)
- bind的方式绑定服务(调用服务的方法)
- unbind的方式解除绑定服务
- stop的方式停止服务
本地服务和远程服务
进程
操作系统分配的独立的内存空间
IPC
inter process communication 进程间通讯
aidl
android interface definition language 安卓接口定义语言
aidl的编写步骤
- 跟本地服务的代码是一样
- 远程服务的接口的定义文件.java—>.aidl
- 把接口定义文件的访问修饰符全部删除 public private
- 原来代理人MyBinder extend Binder implement IService —>:extend IService.Stub
- 先把远程服务.AIDL文件拷贝到本地应用程序的工程目录里面,包名一致
- IService = IService.Stub.asInterface(service);得到远程服务的代理对象
- 通过代理对象调用远程服务的方法
绑定远程服务的应用场景
- 捕鱼游戏
支付宝
bindService(intent, conn, BIND_AUTO_CREATE);iService = IService.Stub.asInterface(service);
支付宝安全支付案例
private class MyBinder extends IAlipayService.Stub{ @Override public int callSafePay(String username, String password, float money) { return safePay(username, password, money); }}public int safePay(String username ,String password , float money){ if ("zhangsan".equals(username) && "123".equals(password)) { if (money < 500) {//余额只有500元 return 200; } else { return 250; } } else { return 404; }} <service android:name="com.xxx.newswork.service.AlipayService" ><!-- 远程项目调用服务 --> <intent-filter > <action android:name="com.xxx.alipay"/> </intent-filter> </service>@Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_alipay); //得到远程服务的代理人iAlipayService Intent intent = new Intent(); intent.setAction("com.heima.alipay"); bindService(intent, new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { iAlipayService = IAlipayService.Stub.asInterface(service); } @Override public void onServiceDisconnected(ComponentName name) { } }, BIND_AUTO_CREATE); }public void buyBall(View view){ //买炮弹 try { int result = iAlipayService.callSafePay("zhangsan", "123", 800);//买个100元的炮弹 switch (result) { case 200: Toast.makeText(this, "支付成功", 0).show(); break; case 250: Toast.makeText(this, "卡上余额不足", 0).show(); break; case 404: Toast.makeText(this, "账号或者密码不正确", 0).show(); break; } } catch (RemoteException e) { e.printStackTrace(); } }
系统服务
- 普通的服务(startService) ,activity想去调用服务的方法
- 绑定的服务(bindService),一个应用程序需要调用另一个应用程序的服务
- 远程的服务AIDL,系统服务对象 = context.getSystemService(系统服务)
- 系统的服务
利用系统服务监听通话的状态
private class MyPhoneListener extends PhoneStateListener { @Override public void onCallStateChanged(int state, String incomingNumber) { super.onCallStateChanged(state, incomingNumber); switch (state) { case TelephonyManager.CALL_STATE_IDLE: // 空闲状态,代表当前没有电话 if (mRecorder != null) { System.out.println("停止录音"); stopRecording(); } break; case TelephonyManager.CALL_STATE_RINGING:// 响铃状态 break; case TelephonyManager.CALL_STATE_OFFHOOK:// 通话状态 System.out.println("通话状态,开启录音机,录音."); startRecording(); break; } }
通话录音
/** * 开始录音 */ private void startRecording() { mRecorder = new MediaRecorder(); mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);// 从麦克风录音 mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); mRecorder.setOutputFile("/mnt/sdcard/" + SystemClock.uptimeMillis() + ".3gp"); mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);// 手机的一种音频编码方式 try { mRecorder.prepare(); } catch (Exception e) { System.out.println("prepare() failed"); } mRecorder.start(); } /** * 停止录音 */ private void stopRecording() { mRecorder.stop(); mRecorder.release(); mRecorder = null; }
0 0
- Android10
- Android10
- android10个不错学习网站
- Android10--Android之异步任务AsyncTask
- Android10--Android之动态代理详解
- Android10.3-ViewPager+Fragment实现仿微信界面
- Arcgis android10.2测试版中android.view.InflateException
- Android10--Android之异步任务加载网页和图片
- Android10--Android之动态接口实现加载网页和图片
- BAT大牛带你深度剖析Android10大开源框架
- Facebook登录申请流程
- Android09
- JavaSE总结 -集合框架collection
- 数据结构图的基本操作--邻接表法(不包括深度、广度算法)
- Ajax之判断用户名是否存在
- Android10
- 虚拟机上下载Android源码
- 自动创建hibernate的hbm.xml文件失败
- LDA的Gibbs抽样详细推理与理解
- 第十五周OJ项目K包含B的字符
- 学习Python运维之Shellinabox安装笔记
- Spring Jar包因为JDK版本报错
- 程序员的口头禅:技术上无法实现
- Java基本算法——排序(一)