通过bindservice方法开启的服务,通过什么方法解绑_controller调用多个service

通过bindservice方法开启的服务,通过什么方法解绑_controller调用多个service绑定本地服务AndroidManifest.xml中声明服务:<serviceandroid:name=".TestLocalService"><intent-filter><actionandroid:name="maureen.intent.action.BIND_LOCAL…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

绑定本地服务

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)

源码位置

Android/MyTestBindService at master · maureenLiu/Android · GitHub

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/192242.html原文链接:https://javaforall.net

赞 (0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 本地数据库同步到云主机上

    本地数据库同步到云主机上同步前的准备:首先你本地跟云主机上都要有数据库、可视化的辅助工具(我用的NavicatPremium,其他的也都一个道理),这里靠的就是这个NavicatPremium工具1.首先在云主机上创建一个链接,建一个数据库,最好是与本地数据库同名2.在本地新建一个连接,可以点击下边的链接测试,测试一下看看是否能连接成功3.找到工具栏里的:工具->数据传输4.经过上述三步你最起码有了两个连接

    2022年5月25日
  • 推荐一款免费的数据库管理工具,比Navicat还要好用,功能还很强大

    点击上方“全栈程序员社区”,星标公众号 重磅干货,第一时间送达 作者:不剪发的Tony老师 blog.csdn.net/horses/article/details/8968342…

    2021年6月25日
  • 基于SSM框架的毕业设计管理系统的设计与实现(附资源下载)

    基于SSM框架的毕业设计管理系统的设计与实现(附资源下载)我的毕业设计就叫毕业设计管理系统的设计与实现,哈哈目录1.摘要2.需求分析3.数据库设计4.功能模块的设计与实现5.项目截图6.项目源码1.摘要毕业设计是本科教育的最后一个环节,整个过程包括课题拟定与审核、师生双选、开题报告、文档审核、中期检查、毕业答辩等多个环节,是一项系统而复杂的工作。开发一个适合本校的毕业设计管理系统,不仅能够极大地减少教务管理人员的…

    2022年7月12日
  • 解决新版chrome跨域问题:cookie丢失以及samesite属性问题「建议收藏」

    解决新版chrome跨域问题:cookie丢失以及samesite属性问题「建议收藏」最近在使用前后端分离开发的时候,遇到了一个诡异的问题,无论如何设置跨域,同一个页面获取到的session始终不一致。发现问题:登录界面前后端分离,ajax提交登录时出错验证码接口和登录接口的session不一致(跨域问题)在网上搜索跨域问题,重新设置,问题依旧错因排除:ajax允许cookie(已经设置xhrFields:{withCredentials:true})springboot尝试设置了多种跨域方法(springboot解决跨域)深入分析:使用其它浏览器(fi

    2022年6月9日
  • 浏览器被hao360劫持解决办法

    浏览器被hao360劫持解决办法浏览器被hao360劫持怎么办chromeedge被hao360劫持解决办法建议chromeedge被hao360劫持chrome和edge被hao360劫持后的样子解决办法在该目录下C:\ProgramData\Microsoft\Windows\StartMenu\Programs删除被hao360修改快捷方式(edge为例chrome我已删除了)最后浏览器回复正常。建议安装软件到对应官网下载正规软件安装…

    2022年7月26日
  • java标识符命名_java标识符命名规则「建议收藏」

    java标识符命名_java标识符命名规则「建议收藏」1.标识符概念:对于java中的类、接口、变量、常量、方法、属性等等命名的字段被称作标识符。通俗的说就是起名字的地方就是标示符。2标识符命名规则:(1).标识符一般有字母、数字、下划线_、美元符$、人民币符号¥组成。(2).注意数字不能放开头(3).不能把java关键字(例如publicint)作为标识符(4).不能把java保留字(goto,const)作为标识符(5).标识符没有长度限制,并…

    2022年7月26日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号