Android10
2016-12-11 21:18
295 查看
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> @Override protected 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 abee ("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; }
相关文章推荐
- Android培训班(10)
- Android入门逆引手册 - 10 列表框(ListView)的使用
- 如何解决:Android中 Error generating final archive: Debug Certificate expired on 10/09/18 16:30 的错误
- Android 开发人员必须掌握的 10 个开发工具
- Android学习10Android上的数据存储02
- Android 开发人员必须掌握的 10 个开发工具
- 在fedora 10下载android源码
- Android开发者指南(10) —— Android API Levels
- Android 开发人员必须掌握的 10 个开发工具
- Jollen 的 Android 教学(10): 如何检查 Service 是否已启动?使用 Android 除错器
- Android2.2 r1 API 中文文档系列(10) —— CheckBox
- android2.2一键root教程(转http://www.360doc.com/content/10/1109/22/114824_68050314.shtml)
- Android学习笔记10——Android的调试
- Android2.2 r1 API 中文文档系列(10) —— CheckBox
- 系出名门Android(10) - HTTP 通信, XML 解析, 通过 Hander 实现异步消息处理
- 系出名门Android(10) - HTTP 通信, XML 解析, 通过 Hander 实现异步消息处理
- Android培训班(10)
- ArcGIS API for Android 案例教程 10
- 实现MultiSelectListPreference 在Android-10
- [Android利器] Android 开发人员必须掌握的 10 个开发工具