文章目录
参考资料
- https://blog.csdn.net/x2584179909/article/details/108319973
- https://developer.android.google.cn/guide/components/bound-services?hl=zh-cn
- https://gitee.com/18071569361/ApiDemos/tree/master
- https://blog.csdn.net/hello_1995/article/details/122094512
代码
- https://gitee.com/hellosunshine/service-android-java.git
内容
服务类型
- 前台服务
- 后台服务
- 绑定服务
服务的回调方法
- onStartCommand()
当另一个组件请求启动服务时 - onBind()
绑定服务 - onCreate()
首次创建会调用 - onDestroy()
销毁服务
IntentService
- 创建服务
package com.example.serviceandroidjava;
import android.app.IntentService;
import android.content.Intent;
import androidx.annotation.Nullable;
public class HelloIntentService extends IntentService {
public HelloIntentService() {
super("HelloIntentService");
}
@Override
protected void onHandleIntent(@Nullable Intent intent) {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
- manifest.xml 注册服务
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.example.serviceandroidjava">
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.ServiceAndroidJava"
tools:targetApi="31">
<service
android:name=".HelloIntentService"
android:exported="false" />
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Service
package com.example.serviceandroidjava;
import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.Process;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
public class HelloService extends Service {
private Looper serviceLooper;
private ServiceHandler serviceHandler;
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(@NonNull Message msg) {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
stopSelf(msg.arg1);
}
}
@Override
public void onCreate() {
super.onCreate();
HandlerThread thread = new HandlerThread("ServiceStartArgs",
Process.THREAD_PRIORITY_BACKGROUND);
thread.start();
serviceLooper = thread.getLooper();
serviceHandler = new ServiceHandler(serviceLooper);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
Message message = serviceHandler.obtainMessage();
message.arg1 = startId;
serviceHandler.sendMessage(message);
return START_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show();
}
}
启动服务
Intent intent = new Intent(this, HelloService.class);
startService(intent);
绑定服务
binder方式
- Binder
实现自有的Binder类,让客户端通过该类直接访问服务中公共方法 - 创建服务
package com.example.serviceandroidjava;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import androidx.annotation.Nullable;
import java.util.Random;
public class LocalService extends Service {
private final IBinder binder = new LocalBinder();
private final Random mGenerator = new Random();
///返回LocalService实例,从而客户端可以调用服务中的公共方法
public class LocalBinder extends Binder {
LocalService getService() {
return LocalService.this;
}
}
//返回binder
@Nullable
@Override
public IBinder onBind(Intent intent) {
return binder;
}
///公共方法
public int getRandomNumber() {
return mGenerator.nextInt(100);
}
}
- manifest注册服务
<service
android:name=".LocalService"
android:exported="false" />
- 绑定服务\解绑服务\
package com.example.serviceandroidjava;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import android.Manifest;
import android.app.Notification;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
LocalService mService;
boolean mBound = false;
private Button btn;
@Override
protected void onStart() {
super.onStart();
//绑定服务
Intent intent = new Intent(this, LocalService.class);
bindService(intent, connection, Context.BIND_AUTO_CREATE);
}
@Override
protected void onStop() {
super.onStop();
//解绑服务
unbindService(connection);
mBound = false;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//启动服务
// Intent intent = new Intent(this, HelloService.class);
// startService(intent);
//启动前台服务
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// Intent intent = new Intent(this, ForegroundService.class);
// startService(intent);
// Context context = getApplicationContext();
// context.startForegroundService(intent);
// } else {
// Log.i("MainActivity", "版本问题");
// }
//点击获取随机数字(绑定服务)
btn = findViewById(R.id.button);
btn.setOnClickListener(view -> {
if (mBound) {
int number = mService.getRandomNumber();
Toast.makeText(this, "number: " + number, Toast.LENGTH_LONG).show();
} else {
Log.i("MainActivity", "未绑定上");
}
});
}
private final ServiceConnection connection = new ServiceConnection() {
//连接服务
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
LocalService.LocalBinder binder = (LocalService.LocalBinder) iBinder;
mService = binder.getService();
mBound = true;
}
//断开服务
@Override
public void onServiceDisconnected(ComponentName componentName) {
mBound = false;
}
};
}
- 运行,调用服务中的获取随机数字
Messenger方式
- 创建服务
package com.example.serviceandroidjava.bindServiceMessenger;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
public class MessengerService extends Service {
static final int MSG_SAY_HELLO = 1;
static class IncomingHandler extends Handler {
private Context mContext;
IncomingHandler(Context context) {
mContext = context.getApplicationContext();
}
@Override
public void handleMessage(@NonNull Message msg) {
switch (msg.what) {
case MSG_SAY_HELLO:
Toast.makeText(mContext, "hello!", Toast.LENGTH_SHORT).show();
break;
default:
super.handleMessage(msg);
}
}
}
Messenger messenger;
@Nullable
@Override
public IBinder onBind(Intent intent) {
Toast.makeText(getApplicationContext(), "binding", Toast.LENGTH_SHORT).show();
Handler handler = new IncomingHandler(this);
messenger = new Messenger(handler);
return messenger.getBinder();
}
}
- 绑定服务/解绑服务/发送Message
package com.example.serviceandroidjava.bindServiceMessenger;
import androidx.appcompat.app.AppCompatActivity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.view.View;
import android.widget.Button;
import com.example.serviceandroidjava.R;
public class ActivityMessenger extends AppCompatActivity {
Messenger messenger = null;
boolean bound;
Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_messenger);
button = findViewById(R.id.sayHelloBtn);
button.setOnClickListener(this::sayHello);
}
//绑定服务
@Override
protected void onStart() {
super.onStart();
Intent intent = new Intent(this, MessengerService.class);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
//解绑服务
@Override
protected void onStop() {
super.onStop();
if (bound) {
unbindService(mConnection);
bound = false;
}
}
//发送Message
private void sayHello(View view) {
if (!bound)
return;
Message message = Message.obtain(null, MessengerService.MSG_SAY_HELLO, 0, 0);
try {
messenger.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
}
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
messenger = new Messenger(iBinder);
bound = true;
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
messenger = null;
bound = false;
}
};
}
ServiceConnection
private final ServiceConnection myServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
//系统调用该方法以传递服务的onBind()方法所返回的IBinder
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
//当与服务连接意外中断时,例如服务崩溃或被终止时
//取消绑定不会调用
}
};
管理绑定服务的生命周期
- unbinderService() ->onUnbind()-> stopSelf()/stopService()->onDestory
- unbinderService()->onUnbind()->bindService()->onBind()
- unbinderService()->onUnbind()->bindService()->onRebind()
前台运行服务&通知
- 请求前台服务的权限
<!--前台服务-->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
- 创建服务并创建通知通道
package com.example.serviceandroidjava;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.os.IBinder;
import android.util.Log;
import androidx.annotation.Nullable;
public class ForegroundService extends Service {
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Intent notificationIntent = new Intent(this, MainActivity.class);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent,
PendingIntent.FLAG_IMMUTABLE);
String channelId = createNotification();
Notification notification = new Notification.Builder(this, channelId)
.setContentTitle("通知标题")
.setSmallIcon(R.drawable.ic_launcher_background)
.setTicker("serviceTicker")
.setContentText("通知内容")
.setContentIntent(pendingIntent)
.build();
startForeground(1, notification);
} else {
Log.i("MainActivity", "版本问题");
}
return super.onStartCommand(intent, flags, startId);
}
//创建消息通道
private String createNotification() {
NotificationChannel notificationChannel = null;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
notificationChannel = new NotificationChannel("ForegroundService", "前台服务", NotificationManager.IMPORTANCE_DEFAULT);
notificationChannel.setLightColor(Color.BLUE);
notificationChannel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.createNotificationChannel(notificationChannel);
}
return "ForegroundService";
}
}
- manifest注册服务
<service
android:name=".ForegroundService"
android:exported="false" />
- 启动服务后再作为前台服务
//启动前台服务
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Intent intent = new Intent(this, ForegroundService.class);
startService(intent);
Context context = getApplicationContext();
context.startForegroundService(intent);
} else {
Log.i("MainActivity", "版本问题");
}
- 运行MainActivity
- 声明前台服务的类型
<service
android:name=".ForegroundService"
android:exported="false"
android:foregroundServiceType="location|camera"/>
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
startForeground(1, notification, FOREGROUND_SERVICE_TYPE_LOCATION | FOREGROUND_SERVICE_TYPE_CAMERA);
} else {
startForeground(1, notification);
}
管理服务的生命周期
package com.example.serviceandroidjava;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import androidx.annotation.Nullable;
public class ExampleService extends Service {
@Override
public void onCreate() {
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public boolean onUnbind(Intent intent) {
return super.onUnbind(intent);
}
@Override
public void onRebind(Intent intent) {
super.onRebind(intent);
}
@Override
public void onDestroy() {
super.onDestroy();
}
}
调用顺序:onCreate->onStartCommand->(onBind->onUnbind->onRebind)->onDestory
AIDL(接口定义语言)
AIDL用处
需要不同应用的客户端通过IPC方式访问服务,并且希望在服务中进行多线程处理时,使用。利用它定义服务端与客户端均认可的编程接口,以便二者使用进程间通信(IPC)
- 处理多线程
- 多客户端并发访问(Messenger是单线程)
实现进程间通信(AIDL)
- 创建两个Module(一个为Server,一个为Client)
- 创建AIDL文件(aidl文件须一致,包名也一致)
// IRemoteService.aidl
package com.example.server_aidl;
// Declare any non-default types here with import statements
interface IRemoteService {
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
double aDouble, String aString);
}
- 创建AIDL后要rebuild,从而生成java文件
- 服务端创建服务
server中的manifest
修改server标签,添加action
<service
android:name=".RemoteService"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.example.aidl" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</service>
- 完善RemoteService
package com.example.serveraidl;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import com.example.server_aidl.IRemoteService;
public class RemoteService extends Service {
private final String TAG = "RemoteService";
public RemoteService() {
}
@Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "onCreate()");
}
@Override
public IBinder onBind(Intent intent) {
Log.d(TAG, "onBind()");
return binder;
}
private final IRemoteService.Stub binder = new IRemoteService.Stub() {
@Override
public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {
Log.d(TAG, "basicTypes: anInt: " + anInt);
Log.d(TAG, "basicTypes: aLong: " + aLong);
Log.d(TAG, "basicTypes: aBoolean: " + aBoolean);
Log.d(TAG, "basicTypes: aFloat: " + aFloat);
Log.d(TAG, "basicTypes: aDouble: " + aDouble);
Log.d(TAG, "basicTypes: aString: " + aString);
}
};
}
当客户端连接服务端时,若客户端调用basicTypes方法,则能看到输出日志
- 配置客户端
基本的绑定服务和解绑服务的流程
package com.example.clientaidl;
import androidx.appcompat.app.AppCompatActivity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import com.example.server_aidl.IRemoteService;
public class MainActivity extends AppCompatActivity {
private final String TAG = "MainActivity";
private IRemoteService iRemoteService;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
//绑定服务
@Override
protected void onStart() {
super.onStart();
Intent intent = new Intent();
//对应注册服务的action
intent.setAction("com.example.aidl");
//对应服务端包名
intent.setPackage("com.example.serveraidl");
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
//解绑
@Override
protected void onStop() {
super.onStop();
unbindService(mConnection);
}
ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
Log.d(TAG, "onServiceConnected");
//asInterface
//该方法会接收 IBinder(通常是传递给客户端 onServiceConnected() 回调方法的参数),并返回 Stub 接口的实例。
iRemoteService = IRemoteService.Stub.asInterface(iBinder);
try {
iRemoteService.basicTypes(0, 1, true, 2, 3, "文本");
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
Log.d(TAG, "onServiceDisconnected");
iRemoteService = null;
}
};
}
- 注意此处的Action和Package要对应
- 运行
先运行Server,在运行Client,就看到日志输出了
AIDL传递对象
- 服务端创建Rect.aidl文件,并指定路径
// Rect.aidl
package com.example.server_aidl;
parcelable Rect;
// IRemoteService.aidl
package com.example.server_aidl;
import com.example.server_aidl.Rect;
// Declare any non-default types here with import statements
interface IRemoteService {
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
double aDouble, String aString);
void addRectInOut(inout Rect rect);
}
- 对应路径下创建Rect类,须一致
package com.example.server_aidl;
import android.os.Parcel;
import android.os.Parcelable;
import androidx.annotation.NonNull;
public class Rect implements Parcelable {
private int left;
private int top;
private int right;
private int bottom;
public Rect(int left, int top, int right, int bottom) {
this.left = left;
this.top = top;
this.right = right;
this.bottom = bottom;
}
public static final Creator<Rect> CREATOR = new Creator<Rect>() {
public Rect createFromParcel(Parcel in) {
return new Rect(in);
}
public Rect[] newArray(int size) {
return new Rect[size];
}
};
private Rect(Parcel in) {
readFromParcel(in);
}
@Override
public void writeToParcel(Parcel out, int flags) {
out.writeInt(left);
out.writeInt(top);
out.writeInt(right);
out.writeInt(bottom);
}
public void readFromParcel(Parcel in) {
left = in.readInt();
top = in.readInt();
right = in.readInt();
bottom = in.readInt();
}
@Override
public int describeContents() {
return 0;
}
@NonNull
@Override
public String toString() {
return "Rect[left:" + left + ",top:" + top + ",right:" + right + ",bottom:" + bottom + "]";
}
}
- 创建好了之后,rebuild一下,IRemoteService.java就会更新一个新的方法addRectInOut
- 客户端也一致,先创建Rect.aidl
// Rect.aidl
package com.example.server_aidl;
// Declare Rect so AIDL can find it and knows that it implements
// the parcelable protocol.
parcelable Rect;
- 在IRemoteService.aidl中也引用Rect,并声明方法
// IRemoteService.aidl
package com.example.server_aidl;
import com.example.server_aidl.Rect;
// Declare any non-default types here with import statements
interface IRemoteService {
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
double aDouble, String aString);
void addRectInOut(inout Rect rect);
}
- 在同样的路径下创建Rect.java类
package com.example.server_aidl;
import android.os.Parcel;
import android.os.Parcelable;
import androidx.annotation.NonNull;
public class Rect implements Parcelable {
private int left;
private int top;
private int right;
private int bottom;
public Rect(int left, int top, int right, int bottom) {
this.left = left;
this.top = top;
this.right = right;
this.bottom = bottom;
}
public static final Creator<Rect> CREATOR = new Creator<Rect>() {
public Rect createFromParcel(Parcel in) {
return new Rect(in);
}
public Rect[] newArray(int size) {
return new Rect[size];
}
};
private Rect(Parcel in) {
readFromParcel(in);
}
@Override
public void writeToParcel(Parcel out, int flags) {
out.writeInt(left);
out.writeInt(top);
out.writeInt(right);
out.writeInt(bottom);
}
public void readFromParcel(Parcel in) {
left = in.readInt();
top = in.readInt();
right = in.readInt();
bottom = in.readInt();
}
@Override
public int describeContents() {
return 0;
}
@NonNull
@Override
public String toString() {
return "Rect[left:" + left + ",top:" + top + ",right:" + right + ",bottom:" + bottom + "]";
}
}
- rebuild之后,也会生成一个方法
- 修改服务端中的RemoteService.java,实现addRectInput,接受Rect对象,输出日志
package com.example.serveraidl;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import com.example.server_aidl.IRemoteService;
import com.example.server_aidl.Rect;
public class RemoteService extends Service {
private final String TAG = "RemoteService";
public RemoteService() {
}
@Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "onCreate()");
}
@Override
public IBinder onBind(Intent intent) {
Log.d(TAG, "onBind()");
return binder;
}
private final IRemoteService.Stub binder = new IRemoteService.Stub() {
@Override
public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {
Log.d(TAG, "basicTypes: anInt: " + anInt);
Log.d(TAG, "basicTypes: aLong: " + aLong);
Log.d(TAG, "basicTypes: aBoolean: " + aBoolean);
Log.d(TAG, "basicTypes: aFloat: " + aFloat);
Log.d(TAG, "basicTypes: aDouble: " + aDouble);
Log.d(TAG, "basicTypes: aString: " + aString);
}
//实现addRectInOut,接受Rect对象
@Override
public void addRectInOut(Rect rect) throws RemoteException {
Log.d(TAG, "addRectInOut:" + rect.toString());
}
};
}
- 客户端调用服务的方法addRectInOut,传入Rect实例
package com.example.clientaidl;
import androidx.appcompat.app.AppCompatActivity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import com.example.server_aidl.IRemoteService;
import com.example.server_aidl.Rect;
public class MainActivity extends AppCompatActivity {
private final String TAG = "MainActivity";
private IRemoteService iRemoteService;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
//绑定服务
@Override
protected void onStart() {
super.onStart();
Intent intent = new Intent();
//对应注册服务的action
intent.setAction("com.example.aidl");
//对应服务端包名
intent.setPackage("com.example.serveraidl");
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
//解绑
@Override
protected void onStop() {
super.onStop();
unbindService(mConnection);
}
ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
Log.d(TAG, "onServiceConnected");
//asInterface
//该方法会接收 IBinder(通常是传递给客户端 onServiceConnected() 回调方法的参数),并返回 Stub 接口的实例。
iRemoteService = IRemoteService.Stub.asInterface(iBinder);
try {
iRemoteService.basicTypes(0, 1, true, 2, 3, "文本");
iRemoteService.addRectInOut(new Rect(1, 2, 3, 4));
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
Log.d(TAG, "onServiceDisconnected");
iRemoteService = null;
}
};
}
- 运行service和client(先service开启,后开启client),查看日志,技能看到接受了Rect对象