Android远程服务

一、远程服务主要代码
1.IService.aidl
package com.shz.remoteservice;
interface IService {
String getTicketInfoById(int id);
}
编译aidl文件自动生成的IService.java文件(存在于gen目录下)
/*
* This file is auto-generated. DO NOT MODIFY.
* Original file: E:\\Code\\Java\\远程服务\\src\\com\\shz\\remoteservice\\IService.aidl
*/
package com.shz.remoteservice;
public interface IService extends android.os.IInterface
{
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements com.shz.remoteservice.IService
{
private static final java.lang.String DESCRIPTOR = "com.shz.remoteservice.IService";
/** Construct the stub at attach it to the interface. */
public Stub()
{
this.attachInterface(this, DESCRIPTOR);
}
/**
* Cast an IBinder object into an com.shz.remoteservice.IService interface,
* generating a proxy if needed.
*/
public static com.shz.remoteservice.IService asInterface(android.os.IBinder obj)
{
if ((obj==null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof com.shz.remoteservice.IService))) {
return ((com.shz.remoteservice.IService)iin);
}
return new com.shz.remoteservice.IService.Stub.Proxy(obj);
}
@Override public android.os.IBinder asBinder()
{
return this;
}
@Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
{
switch (code)
{
case INTERFACE_TRANSACTION:
{
reply.writeString(DESCRIPTOR);
return true;
}
case TRANSACTION_getTicketInfoById:
{
data.enforceInterface(DESCRIPTOR);
int _arg0;
_arg0 = data.readInt();
java.lang.String _result = this.getTicketInfoById(_arg0);
reply.writeNoException();
reply.writeString(_result);
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
private static class Proxy implements com.shz.remoteservice.IService
{
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote)
{
mRemote = remote;
}
@Override public android.os.IBinder asBinder()
{
return mRemote;
}
public java.lang.String getInterfaceDescriptor()
{
return DESCRIPTOR;
}
@Override public java.lang.String getTicketInfoById(int id) throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
java.lang.String _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeInt(id);
mRemote.transact(Stub.TRANSACTION_getTicketInfoById, _data, _reply, 0);
_reply.readException();
_result = _reply.readString();
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
}
static final int TRANSACTION_getTicketInfoById = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
}
public java.lang.String getTicketInfoById(int id) throws android.os.RemoteException;
}
2.TicketService.java
package com.shz.remoteservice; import java.util.ArrayList;
import java.util.List; import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log; /**
* 后台服务(组件),提供查询电影票相关信息
* @author SHZ
*
*/
public class TicketService extends Service { private final static String TAG = "TicketService";
private List<Ticket> tickets; @Override
public IBinder onBind(Intent intent) {
Log.i(TAG, "onBind 服务绑定成功");
// 2.Activity绑定服务成功之后,服务返回给Activity一个IBinder类型的对象,
// 通过该对象,Activity就可以和服务进行交互了,就像一个代理一样
return new TicketBinder();
} @Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "onCreate 服务创建成功");
this.tickets = new ArrayList<Ticket>();
this.tickets.add(new Ticket(1, "变形金刚4", 103));
this.tickets.add(new Ticket(2, "窃听风云3", 86));
this.tickets.add(new Ticket(3, "反腐风暴", 75));
} @Override
public void onStart(Intent intent, int startId) {
Log.i(TAG, "onStart 服务启动");
super.onStart(intent, startId);
} @Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "onStartCommand 服务启动");
return super.onStartCommand(intent, flags, startId);
} @Override
public boolean onUnbind(Intent intent) {
Log.i(TAG, "onUnbind 服务解绑成功");
return super.onUnbind(intent);
} @Override
public void onDestroy() {
super.onDestroy();
Log.i(TAG, "onDestroy 服务销毁成功");
} private Ticket getTicket(int id)
{
for(Ticket ticket:this.tickets)
{
if(ticket.Id == id)
{
return ticket;
}
} return null;
} /**
* 服务内部方法:查询电影票信息
* @param id
* @return
*/
public String getTicketInfo(int id)
{
Ticket ticket = this.getTicket(id);
if(ticket == null)
{
return "未查询到该电影票信息";
}
else
{
return ticket.toString();
}
} /**
* 服务内部方法(测试用,没有意义):更新电影票价格
* @param id
* @param newPrice
*/
public void updateTicketPrice(int id, float newPrice)
{
Ticket ticket = this.getTicket(id);
if(ticket != null)
{
ticket.Price = newPrice;
}
} /**
* 自定义一个代理类,继承Binder并实现IService接口。
* 服务会返回该类的一个实例给调用者,调用者可通过该实例调用相应的类方法
* @author SHZ
*
*/
private class TicketBinder extends IService.Stub
{
/**
* 实现IService接口中的方法,调用服务内部的方法,这样调用服务的Activity就可以获取电影票信息了
*/
@Override
public String getTicketInfoById(int id) {
return getTicketInfo(id);
} /**
* 由于该方法并未在IService接口中定义,故调用者无法使用该方法
* @param id
* @param newPrice
*/
public void updateTicketPrice(int id,float newPrice)
{
updateTicketPrice(id, newPrice);
} } }
3.Ticket.java(实体类)
package com.shz.remoteservice;
public class Ticket {
public int Id;
public String Name;
public float Price;
public Ticket(int id, String name, float price) {
Id = id;
Name = name;
Price = price;
}
@Override
public String toString() {
return "您查询的电影是:"+this.Name+",票价为:"+this.Price;
}
}
4.清单配置文件AndroidManifest.xml
<service android:name="com.shz.remoteservice.TicketService">
<intent-filter>
<!-- 如果用于远程服务,则需指定action -->
<action android:name="com.shz.TICKETSERVICE"/>
</intent-filter>
</service>
二、调用远程服务的代码
1.把远程服务工程里面的IService.aidl文件(包括包名)拷贝到调用者的工程中
2.调用代码
package com.shz.callremoteservice; import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.text.TextUtils;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast; import com.shz.remoteservice.IService; public class MainActivity extends Activity { private TicketServiceConnection conn;
private IService ticketBinder;
private EditText txtTicketId;
private TextView lblTicketInfo; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); txtTicketId = (EditText) findViewById(R.id.txtTicketId);
lblTicketInfo = (TextView) findViewById(R.id.lblTicketInfo); } private class TicketServiceConnection implements ServiceConnection
{ @Override
public void onServiceConnected(ComponentName name, IBinder service) {
// 2.绑定服务成功之后,后台服务会返回IBinder类型的 service 对象,通过该对象可以间接调用后台服务的方法
ticketBinder = IService.Stub.asInterface(service);
} @Override
public void onServiceDisconnected(ComponentName name) { } } /**
* 绑定服务
* @param view
*/
public void bindService(View view) {
Intent service = new Intent();
service.setAction("com.shz.TICKETSERVICE"); // 通过action指定要调用的服务
// 1.绑定服务
// service:服务意图
// new TicketServiceConnection():与后台服务连接的对象,接收后台服务信息
// BIND_AUTO_CREATE:如果服务没有被创建,则自动创建并绑定
conn = new TicketServiceConnection();
bindService(service, conn, BIND_AUTO_CREATE);
} @Override
protected void onDestroy() {
try {
unbindService(conn);
} catch (Exception e) {
}
super.onDestroy();
} public void callServiceMethod(View view) {
if(this.ticketBinder == null)
{
Toast.makeText(this, "请先绑定服务", 1).show();
}
else
{
String strTicketId = this.txtTicketId.getText().toString().trim();
if(TextUtils.isEmpty(strTicketId))
{
Toast.makeText(this, "请输入电影票Id", 1).show();
return;
} try {
// 3.调用IBinder对象的方法
String ticketInfo = this.ticketBinder.getTicketInfoById(Integer.parseInt(strTicketId));
this.lblTicketInfo.setText(ticketInfo);
} catch (NumberFormatException e) {
e.printStackTrace();
} catch (RemoteException e) {
e.printStackTrace();
}
}
} }
3.前台UI布局代码
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.shz.localservice.MainActivity"
tools:ignore="MergeRootFrame" > <Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="bindService"
android:text="绑定服务" /> <EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入电影票Id"
android:id="@+id/txtTicketId"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="callServiceMethod"
android:text="查询" /> <TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/lblTicketInfo"
android:textColor="#ff0000"/> </LinearLayout>
调用服务前必须先绑定服务(当然了,远程服务必须首先启动起来)
调用结果截图:

Android远程服务的更多相关文章
- Android远程服务AIDL开发过程中容易遇见的两个问题
问题 一 JavaBinder: Uncaught remote exception! (Exceptions are not yet supported across processes.) jav ...
- Android远程服务(AIDL)实现步骤
AIDL是安卓接口定义语言的缩写 由于笔者使用的是android studio所以建立AIDL文件的位置也需要注意,要在APPNAME->main->aidl->packagenam ...
- Android中利用AIDL机制调用远程服务
服务端: //CalculateInterface.aidl package com.itheima.aidl.calculate; interface CalculateInterface { do ...
- Android 中的AIDL,Parcelable和远程服务
Android 中的AIDL,Parcelable和远程服务 早期在学习期间便接触到AIDL,当时对此的运用也是一撇而过.只到近日在项目中接触到AIDL,才开始仔细深入.AIDL的作用 ...
- android Service Activity交互之传递复杂数据类型的远程服务
远程服务往往不只是传递java基本数据类型.这时需要注意android的一些限制和规定: android支持String和CharSequence 如果需要在aidl中使用其他aidl接口类型,需要i ...
- Android(java)学习笔记233: 远程服务的应用场景(移动支付案例)
一. 移动支付: 用户需要在移动终端提交账号.密码以及金额等数据 到 远端服务器.然后远端服务器匹配这些信息,进行逻辑判断,进而完成交易,返回交易成功或失败的信息给移动终端.用户提交账号. ...
- Android学习笔记--远程服务的使用
1.AIDL和Binder Android系统四大组件Activity, Content Provider, Broadcast和Service均可以进行跨进程数据传输. Activity可以隐式调用 ...
- [android] 采用aidl绑定远程服务
aidl:android interface definition language 安卓接口定义语言 在两个不同的应用程序里面使用同一个接口 使用场景:调用支付宝服务进行支付 先写远程服务端Seri ...
- Android -- service的开启方式, start开启和绑定开启服务,调用服务的的方法, aidl调用远程服务
1. 概述 bindService() 绑定服务 可以得到服务的代理人对象,间接调用服务里面的方法. 绑定服务: 间接调用服务里面的方法. 如果调用者activity被销毁了, ...
随机推荐
- 洛谷 P1216 [USACO1.5]数字三角形 Number Triangles(水题日常)
题目描述 观察下面的数字金字塔. 写一个程序来查找从最高点到底部任意处结束的路径,使路径经过数字的和最大.每一步可以走到左下方的点也可以到达右下方的点. 7 3 8 8 1 0 2 7 4 4 4 5 ...
- SAP成都研究院安德鲁:自己动手开发一个Chrome Extension
各位好,我叫何金鑫(He Andrew), 团队同事亲切地称呼在下为安德鲁.如果你在附近找到wifi热点名为 「安德鲁森面包房5g」,可能是我就在附近,我们可以去喝杯咖啡,聊聊最近有趣的东西. 鄙人现 ...
- python_使用qrcode生成二维码
1.功能 使用qrcode生成二维码 2.代码 #生成二维码: import qrcode #根据url生成二维码 def qrcodeWithUrl(url): img = qrcode.make( ...
- Format a Hard Drive in Csharp
Article Author(s): Audric Thevenet All Rights Reserved. Here's how to format hard drives, floppies, ...
- Java任务执行计时
Long startTime = System.currentTimeMillis(); Long endTime = System.currentTimeMillis(); endTime-star ...
- 【传智播客】Libevent学习笔记(三):事件循环
目录 00. 目录 01. event_base_loop函数 02. event_base_dispatch函数 03. event_base_loopexit函数 04. event_base_l ...
- swift详解之十-------------异常处理、类型转换 ( Any and AnyObject )
异常处理.类型转换 ( Any and AnyObject ) 1.错误处理 (异常处理) swift 提供第一类错误支持 ,包括在运行时抛出 ,捕获 , 传送和控制可回收错误.在swift中 ,错误 ...
- STL源码分析与实现-stl_list容器
1. stl_list 介绍 今天我们来总结一下stl_List, 通过之前介绍单链表的文章,其实对链表的基本操作已经十分熟悉了,那对于stl_list,无非就是链表结构不一样,至于其中的增删改查的细 ...
- jdk环境变量配置至第一个简单程序运行成功
桌面右键单击我的电脑,属性,高级,环境变量,然后再系统变量中配置(也可在用户变量中配置) 在配置环境变量时限查看是否已存在变量名称,有则添加路径,没有则创建再添加路径 /* JAVA_HOME% C: ...
- 我们需要了解的五个ERP趋势
企业的全面现代化进程伴随着ERP的发展.在2019年,预计规模较小的供应商将加大力度,双层ERP(Two-Tier ERP)将开始占据市场份额,企业也将要求更加灵活的ERP的实施方案. 该预测基于咨询 ...