您的位置:首页 > 移动开发 > Android开发

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: