Android Service学习总结(下)

本文详细介绍了如何在Android应用中实现远程Service通信,包括注册远程Service、创建AIDL接口、实现服务方法以及在不同进程间调用Service方法的步骤。特别强调了在Android 5.0版本后隐式意图启动Service的方式发生变化,并提供了相应的解决方案。通过实例代码展示了整个过程,确保读者能够理解并实践这一关键概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

关于郭神Service的讲解的学习总结,想看郭神原版请看该链接http://blog.youkuaiyun.com/guolin_blog/article/details/9797169

远程Service

               远程Service,它现在运行在与主线程不同的线程当中,所以我们不能在ServiceConnected方法里面对它的public方法进行调用,只能是通过AIDL来进行通信,与此同时远程Service还可以实现进程间的通信。

步骤一:首先你要在注册Service的Application中将其注册为远程Service,并且指定一个action给Service,以便于其他进程与之进行通信。

Mainfest.xml文件实例代码如下:

        <service android:name=".MyService"
                android:process=":remote">
            <intent-filter>
                <action android:name="com.glimmer.myapplication.MyAIDLService"/>
            </intent-filter>
        </service>
步骤二:在MyApplication中新建一个名为MyAIDLService的AIDL接口。

MyAIDLService的实例代码如下:

interface MyAIDLService {
    /**
     * Demonstrates some basic types that you can use as parameters
     * and return values in AIDL.
     */

      int plus(int a, int b);
      String toUpperCase(String str);

}
步骤三:在MyService里面实现AIDL的接口,具体的做法如下:

  /**
     * 用来建立 Service 和 Activity之间的联系
     */
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return binder;
    }

    MyAIDLService.Stub binder = new MyAIDLService.Stub() {

        @Override
        public int plus(int a, int b) throws RemoteException {
            return a + b;
        }

        @Override
        public String toUpperCase(String str) throws RemoteException {
            if (str != null) {
                return str.toUpperCase();
            }
            return null;
        }
    };

在IBinder方法里返回的就是实现接口的binder,这样在绑定的Activit里面,无论是同一个进程还是不同的进程,都可以调用这两个public方法。

步骤四:在(同一进程下的)MainActivity当中对Service进行绑定,首先就是ServiceConnnection里面的onServiceConnected的方法不同了,它要通过我们定义好的AIDL接口去进行方法的调用,代码如下:

 public void onServiceConnected(ComponentName name, IBinder service) {
            myAIDLService = MyAIDLService.Stub.asInterface(service);
            try {
                int result = myAIDLService.plus(3,5);
                String upperStr = myAIDLService.toUpperCase("hello world");
                Log.d(TAG, "onServiceConnected: result:"+result);
                Log.d(TAG, "onServiceConnected: upperStr:"+upperStr);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

在同一进程中,调用bindService的方法与之前一样,可以看一下我的上一篇总结 点击打开链接,现在主要来讲一下不同进程之间的调用方式。

步骤五:在HappyBirthday的应用中将MyApplication的AIDL的文件整个粘贴过来,如下图:

                                                             

注意:一定要整个文件夹都粘贴过来

步骤六:接下来我们就可以调用我们的Service里面的方法啦,像步骤四一样在(不同进程下的)SecondActivity中生成ServiceConnect的对象connection。代码如下

    private ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            myAIDLService = MyAIDLService.Stub.asInterface(service);
            try {
                int result = myAIDLService.plus(3, 9);
                String upperStr = myAIDLService.toUpperCase("aaa");
                Log.d(TAG, "Result: " + result);
                Log.d(TAG, "UpperStr:" + upperStr);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };
与步骤四没有任何的区别,接下来就是重点要区分的。

步骤七:如何将Service和Activity联系在一起?这里需要注意的是,在不同进程中,我们只能通过action的name来进行意图的指定在Android 5.0版本之前,我们可以直接用这种方式:

  Intent intent = new Intent("com.glimmer.myapplication.MyAIDLService");
               /* intent.setAction("com.glimmer.myapplication.MyAIDLService");
                intent.setPackage("com.glimmer.myapplication");*/
                bindService(intent, connection, BIND_AUTO_CREATE);

但是在实践的过程中,我发现用5.0的系统的手机去启动该应用会出现如下的错误:

  java.lang.IllegalArgumentException: Service Intent must be explicit: Intent { act=com.glimmer.myapplication.MyAIDLService }


经过查资料得知,在Android 5.0版本之后不支持Service的隐式意图启动,并给出了如下解决方案:

                Intent intent = new Intent();
                intent.setAction("com.glimmer.myapplication.MyAIDLService");
                intent.setPackage("com.glimmer.myapplication");
                bindService(intent, connection, BIND_AUTO_CREATE);

这样我们就实现了Service的进程间通信,运行结果如下:


END

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值