大家好,又见面了,我是你们的朋友全栈君。
绑定本地服务
AndroidManifest.xml中声明服务:
<service android:name=".TestLocalService">
<intent-filter>
<action android:name="maureen.intent.action.BIND_LOCAL_SERVICE"/>
</intent-filter>
</service>
TestLocalService.java
public class TestLocalService extends Service {
private final String TAG = TestLocalService.class.getSimpleName();
private IBinder mServiceBinder = new TestLocalServiceBinder();
public class TestLocalServiceBinder extends Binder {
public TestLocalService getService() {
return TestLocalService.this;
}
}
public void testFunc() {
Log.d(TAG,"testFunc");
Log.d(TAG, Log.getStackTraceString(new Throwable()));
}
@Override
public void onCreate() {
super.onCreate();
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
Log.d(TAG, "onBind:mServiceBinder=" + mServiceBinder);
return mServiceBinder;
}
@Override
public boolean onUnbind(Intent intent) {
return super.onUnbind(intent);
}
@Override
public void onDestroy() {
super.onDestroy();
}
}
TestBindServiceActivity.java
- 点击按钮绑定service
- 绑定成功后调用TestLocalService里的testFunc方法
- 点击back键解绑服务
public class TestBindServiceActivity extends Activity {
private static final String TAG = TestBindServiceActivity.class.getSimpleName();
private static final String ACTION_BIND_LOCAL_SERVICE = "maureen.intent.action.BIND_LOCAL_SERVICE";
private Button mBindLocalServiceBtn;
private static ServiceConnection mLocalConnection;
private static TestLocalService mLocalService = null;
private static class TestLocalConenction implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
Log.d(TAG,"onServiceConnected:iBinder=" + iBinder);
mLocalService = ((TestLocalService.TestLocalServiceBinder)iBinder).getService();
mLocalService.testFunc();
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
mLocalService = null;
}
}
private static class ButtonClickListener implements View.OnClickListener {
private WeakReference<TestBindServiceActivity> mActivity;
public ButtonClickListener(TestBindServiceActivity activity) {
mActivity = new WeakReference<>(activity);
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.bind_local_service:
Intent localIntent = new Intent();
//Without this, throw exception.
localIntent.setPackage("com.example.maureen.mytestbindservice");
localIntent.setAction(ACTION_BIND_LOCAL_SERVICE);
mActivity.get().bindService(localIntent, mLocalConnection, BIND_AUTO_CREATE);
break;
default:
break;
}
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "onCreate");
setContentView(R.layout.activity_test_bind_service);
mLocalConnection = new TestLocalConenction();
mBindLocalServiceBtn = findViewById(R.id.bind_local_service);
mBindLocalServiceBtn.setOnClickListener(new ButtonClickListener(this));
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy");
unbindService(mLocalConnection);
}
}
值得注意的是,在TestLocalService中onBind函数返回的mBinder和TestBindServiceActivity中onServiceConnected中的参数iBinder是相同的:
onBind:mServiceBinder=com.example.maureen.mytestbindservice.TestLocalService$TestLocalServiceBinder@3ef6efd
onServiceConnected:iBinder=com.example.maureen.mytestbindservice.TestLocalService$TestLocalServiceBinder@3ef6efd
从Activity中调用testFunc并未通过Binder调用:
2010-01-02 04:29:32.944 5947-5947/com.example.maureen.mytestbindservice D/TestLocalService: testFunc
2010-01-02 04:29:32.950 5947-5947/com.example.maureen.mytestbindservice D/TestLocalService: java.lang.Throwable
at com.example.maureen.mytestbindservice.TestLocalService.testFunc(TestLocalService.java:22)
at com.example.maureen.mytestbindservice.TestBindServiceActivity$TestLocalConenction.onServiceConnected(TestBindServiceActivity.java:27)
at android.app.LoadedApk$ServiceDispatcher.doConnected(LoadedApk.java:1652)
at android.app.LoadedApk$ServiceDispatcher$RunConnection.run(LoadedApk.java:1681)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6523)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:940)
绑定远程服务
- AndroidManifest.xml中声明service,指定service运行的进程:
<service android:name=".TestRemoteService"
android:process=":remote">
<intent-filter>
<action android:name="maureen.intent.action.BIND_REMOTE_SERVICE"/>
</intent-filter>
</service>
- 编写AIDL文件- IRemoteServiceAidlInterface.aidl
interface IRemoteServiceAidlInterface {
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
void testFunc1();
void testFunc2();
}
生成的对应的java文件-IRemoteServiceAidlInterface.java
public interface IRemoteServiceAidlInterface extends android.os.IInterface {
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements com.example.maureen.mytestbindservice.IRemoteServiceAidlInterface {
private static final java.lang.String DESCRIPTOR = "com.example.maureen.mytestbindservice.IRemoteServiceAidlInterface";
/** Construct the stub at attach it to the interface. */
public Stub() {
this.attachInterface(this, DESCRIPTOR);
}
/**
* Cast an IBinder object into an com.example.maureen.mytestbindservice.IRemoteServiceAidlInterface interface,
* generating a proxy if needed.
*/
public static com.example.maureen.mytestbindservice.IRemoteServiceAidlInterface asInterface(android.os.IBinder obj) {
if ((obj==null)) {
return null;
}
ndroid.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof com.example.maureen.mytestbindservice.IRemoteServiceAidlInterface))) {
return ((com.example.maureen.mytestbindservice.IRemoteServiceAidlInterface)iin);
}
return new com.example.maureen.mytestbindservice.IRemoteServiceAidlInterface.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 {
java.lang.String descriptor = DESCRIPTOR;
switch (code) {
case INTERFACE_TRANSACTION: {
reply.writeString(descriptor);
return true;
}
case TRANSACTION_testFunc1: {
data.enforceInterface(descriptor);
this.testFunc1();
reply.writeNoException();
return true;
}
case TRANSACTION_testFunc2: {
data.enforceInterface(descriptor);
this.testFunc2();
reply.writeNoException();
return true;
}
default: {
return super.onTransact(code, data, reply, flags);
}
}
}
private static class Proxy implements com.example.maureen.mytestbindservice.IRemoteServiceAidlInterface {
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;
}
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
@Override
public void testFunc1() throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
mRemote.transact(Stub.TRANSACTION_testFunc1, _data, _reply, 0);
_reply.readException();
} finally {
_reply.recycle();
_data.recycle();
}
}
@Override
public void testFunc2() throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
mRemote.transact(Stub.TRANSACTION_testFunc2, _data, _reply, 0);
_reply.readException();
} finally {
_reply.recycle();
_data.recycle();
}
}
}
static final int TRANSACTION_testFunc1 = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
static final int TRANSACTION_testFunc2 = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
}
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
public void testFunc1() throws android.os.RemoteException;
public void testFunc2() throws android.os.RemoteException;
}
- TestRemoteService.java
public class TestRemoteService extends Service {
private final String TAG= TestRemoteService.class.getSimpleName();
private IBinder mRemoteBinder = new RemoteServiceImpl(this);
private static class RemoteServiceImpl extends IRemoteServiceAidlInterface.Stub {
private final String TAG= RemoteServiceImpl.class.getSimpleName();
private WeakReference<TestRemoteService> mRemoteService;
public RemoteServiceImpl(TestRemoteService service) {
mRemoteService = new WeakReference<>(service);
}
@Override
public void testFunc1() {
Log.d(TAG,"testFunc1");
Log.d(TAG,Log.getStackTraceString(new Throwable()));
mRemoteService.get().testMyFunc1();
}
@Override
public void testFunc2() {
Log.d(TAG,"testFunc2");
mRemoteService.get().testMyFunc2();
}
}
private void testMyFunc1() {
Log.d(TAG,"testMyFunc1");
Log.d(TAG,Log.getStackTraceString(new Throwable()));
}
private void testMyFunc2() {
Log.d(TAG,"testMyFunc2");
}
@Override
public void onCreate() {
super.onCreate();
Log.d(TAG,"onCreate");
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
Log.d(TAG,"onBind:mRemoteBinder=" + mRemoteBinder);
return mRemoteBinder;
}
@Override
public boolean onUnbind(Intent intent) {
Log.d(TAG,"onUnbind");
return super.onUnbind(intent);
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG,"onDestroy");
}
}
- TestBindServiceActivity.java
① 点击按钮,绑定远程服务
②服务绑定成功后,调用aidl中声明的方法testFunc1和testFunc2
③点击back键,解绑服务
package com.example.maureen.mytestbindservice;
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.util.Log;
import android.view.View;
import android.widget.Button;
import java.lang.ref.WeakReference;
public class TestBindServiceActivity extends Activity {
private static final String TAG = TestBindServiceActivity.class.getSimpleName();
private static final String ACTION_BIND_REMOTE_SERVICE = "maureen.intent.action.BIND_REMOTE_SERVICE";
private Button mBindRemoteServiceBtn;
private static ServiceConnection mRemoteConnection;
private static class TestRemoteConection implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
Log.d(TAG,"onServiceConnected:iBinder=" + iBinder);
IRemoteServiceAidlInterface remoteService = IRemoteServiceAidlInterface.Stub.asInterface(iBinder);
try {
remoteService.testFunc1();
remoteService.testFunc2();
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
}
}
private static class ButtonClickListener implements View.OnClickListener {
private WeakReference<TestBindServiceActivity> mActivity;
public ButtonClickListener(TestBindServiceActivity activity) {
mActivity = new WeakReference<>(activity);
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.bind_remote_service:
Intent remoteIntent = new Intent();
//Without this, throw exception.
remoteIntent.setPackage("com.example.maureen.mytestbindservice");
remoteIntent.setAction(ACTION_BIND_REMOTE_SERVICE);
mActivity.get().bindService(remoteIntent, mRemoteConnection, BIND_AUTO_CREATE);
break;
default:
break;
}
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "onCreate");
setContentView(R.layout.activity_test_bind_service);
mRemoteConnection = new TestRemoteConection();
mBindRemoteServiceBtn = findViewById(R.id.bind_remote_service);
mBindRemoteServiceBtn.setOnClickListener(new ButtonClickListener(this));
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy");
unbindService(mRemoteConnection);
}
}
值得注意的是TestRemoteService.java的onBind函数中返回的mRemoteBinder是一个Binder服务端对象,即RemoteServiceImpl对象:
nBind:mRemoteBinder=com.example.maureen.mytestbindservice.TestRemoteService$RemoteServiceImpl@3920201
而在TestBindServiceActivity的TestRemoteServiceConnection的onServiceConnected函数中iBinder是Binder代理端:
onServiceConnected:iBinder=android.os.BinderProxy@6ff13d8
即Activity调用到TestRemoteService是通过Binder调用完成的。
例如TestRemoteService.RemoteServiceImpl.testFunc1调用堆栈:
2010-01-02 05:05:47.136 6482-6495/com.example.maureen.mytestbindservice:remote D/RemoteServiceImpl: testFunc1
2010-01-02 05:05:47.140 6482-6495/com.example.maureen.mytestbindservice:remote D/RemoteServiceImpl: java.lang.Throwable
at com.example.maureen.mytestbindservice.TestRemoteService$RemoteServiceImpl.testFunc1(TestRemoteService.java:24)
at com.example.maureen.mytestbindservice.IRemoteServiceAidlInterface$Stub.onTransact(IRemoteServiceAidlInterface.java:51)
at android.os.Binder.execTransact(Binder.java:697)
而TestRemoteService.testFunc1调用堆栈:
2010-01-02 05:05:47.140 6482-6495/com.example.maureen.mytestbindservice:remote D/TestRemoteService: testMyFunc1
2010-01-02 05:05:47.143 6482-6495/com.example.maureen.mytestbindservice:remote D/TestRemoteService: java.lang.Throwable
at com.example.maureen.mytestbindservice.TestRemoteService.testMyFunc1(TestRemoteService.java:37)
at com.example.maureen.mytestbindservice.TestRemoteService.access$000(TestRemoteService.java:11)
at com.example.maureen.mytestbindservice.TestRemoteService$RemoteServiceImpl.testFunc1(TestRemoteService.java:25)
at com.example.maureen.mytestbindservice.IRemoteServiceAidlInterface$Stub.onTransact(IRemoteServiceAidlInterface.java:51)
at android.os.Binder.execTransact(Binder.java:697)
源码位置
https://github.com/snowdrift1993/Android/tree/master/MyTestBindService
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/134179.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...