一、远程服务主要代码

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>

调用服务前必须先绑定服务(当然了,远程服务必须首先启动起来)

调用结果截图:

最新文章

  1. Android okHttp网络请求之Get/Post请求
  2. 2016 12 21 的project 未注释版
  3. (转)深度学习主机环境配置: Ubuntu16.04+Nvidia GTX 1080+CUDA8.0
  4. Launchpad添加openPGP keys
  5. GLFW is an Open Source, multi-platform library for OpenGL
  6. focus 、blur和focusin,focusout的区别
  7. 每日一“酷”之string
  8. 关于git服务器的搭建
  9. JS实现简单倒计时
  10. Oracle/Mysql批量插入的sql,效率比较高
  11. C# Monads的实现(一)
  12. LeetCode OJ 11. Container With Most Water
  13. BZOJ 2806: [Ctsc2012]Cheat [广义后缀自动机 单调队列优化DP 二分]
  14. Android开发学习之路--React-Native之初体验
  15. Vim PHP环境设置文章
  16. 修改MyEclipse字体大小及颜色
  17. ife2018 零基础学院 day 3
  18. asp.net 访问页面访问统计实现
  19. C++学习(六)(C语言部分)之 输出
  20. widdow.locationg.可跟的参数,获取url不同的地址

热门文章

  1. 洛谷 P2866 [USACO06NOV]糟糕的一天Bad Hair Day
  2. EF为什么向我的数据库再次插入已有对象?(ZT)
  3. Python基础1 介绍、基本语法 、 流程控制-DAY1
  4. 最短路 || UOJ 19 寻找道路
  5. mybatis-spring_缓存
  6. python数组中数据位置交换 -- IndexError: list assignment index out of range
  7. python-opencv 分离图片(视频)中的某一颜色物体
  8. [HIHO] 1048 铺地板
  9. Linux查看配置文件中未被注释的有效配置行
  10. Servlet+JSP教程之:第一个Web程序