zoukankan      html  css  js  c++  java
  • android Service 跨进程通信

    最近做项目一直没能理解清楚Service是如何跨进程通信的,既然是跨进程通信,那么也就意味着多个app可以通过一个Service服务进行数据的交互了。带着这些猜想,花了一天的时间终于把这个猜想实现了。关于Service的生命周期就不说了,网上一大堆。

    本地Activity和Service之间的交互demo:

    首先定义一个接口,用来进行数据之间的交互。

    IService .java
    
    package com.tanlon.localservice;
    
    public interface IService {
      long getCurrentTime();
    }

    接着完成Service类:

    package com.tanlon.localservice;
    
    import android.app.Service;
    import android.content.Intent;
    import android.os.Binder;
    import android.os.IBinder;
    import android.util.Log;
    
    public class LocalService extends Service{
        //log标记
        private static final String TAG="MyService";
        //获取绑定接口
        private MyBind myBind=new MyBind();
        
        public IBinder onBind(Intent intent) {
            // TODO Auto-generated method stub
            Log.d(TAG, "localService onBind");
            return myBind;
        }
    
        public void onCreate() {
            // TODO Auto-generated method stub
            Log.d(TAG, "localService onCreate");
            super.onCreate();
        }
    
        public void onDestroy() {
            // TODO Auto-generated method stub
            Log.d(TAG, "localService onDestroy");
            super.onDestroy();
        }
    
        public void onStart(Intent intent, int startId) {
            // TODO Auto-generated method stub
            Log.d(TAG, "localService onStart");
            super.onStart(intent, startId);
        }
    
        public boolean onUnbind(Intent intent) {
            // TODO Auto-generated method stub
            Log.d(TAG, "localService onUnbind");
            return super.onUnbind(intent);
        }
        //本地服务中的绑定
        public class MyBind extends Binder implements IService{
    
            public long getCurrentTime() {
                // TODO Auto-generated method stub
                return System.currentTimeMillis();
            }
            
        }
    
    }

    本地调用Service:

    package com.tanlon.localservice;
    
    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.util.Log;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    
    public class LocalServiceActivity extends Activity {
        private IService iService=null;
        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            Button startServiceButton=(Button) findViewById(R.id.startServiceButton);
            Button stopServiceButton=(Button) findViewById(R.id.stopServiceButton);
            Button bindServiceButton=(Button) findViewById(R.id.bindServiceButton);
            Button unbindServiceButton=(Button) findViewById(R.id.unbindServiceButton);
            startServiceButton.setOnClickListener(onClickListener);
            stopServiceButton.setOnClickListener(onClickListener);
            bindServiceButton.setOnClickListener(onClickListener);
            unbindServiceButton.setOnClickListener(onClickListener);
        }
        
        private OnClickListener onClickListener=new OnClickListener() {
            
            public void onClick(View v) {
                // TODO Auto-generated method stub
                int id=v.getId();
                switch (id) {
                case R.id.startServiceButton://启动服务(这里用到getApplicationContext是为了提升应用等级,避免出现“android.app.ServiceConnectionLeaked”这样的错误)
                    startService(new Intent(getApplicationContext(), LocalService.class));
                    break;
                case R.id.stopServiceButton://停止服务(这里用到getApplicationContext是为了提升应用等级,避免出现“android.app.ServiceConnectionLeaked”这样的错误)
                    stopService(new Intent(getApplicationContext(), LocalService.class));
                    break;
                case R.id.bindServiceButton://绑定服务
                    bindservice();
                    break;
                case R.id.unbindServiceButton://解绑定
                    unbindService(connection);
                    break;
                default:
                    break;
                }
            }
        };
        
        //绑定服务
        private void bindservice() {
            // TODO Auto-generated method stub
            //这里用到getApplicationContext是为了提升应用等级,避免出现“android.app.ServiceConnectionLeaked”这样的错误
            Intent intent=new Intent(getApplicationContext(), LocalService.class);
            this.bindService(intent, connection, BIND_AUTO_CREATE);
        }
        
        //连接服务接口
        ServiceConnection connection=new ServiceConnection() {
            
            public void onServiceDisconnected(ComponentName name) {
                // TODO Auto-generated method stub
                iService=null;
            }
            
            public void onServiceConnected(ComponentName name, IBinder service) {
                // TODO Auto-generated method stub
                //获取连接的服务对象
                iService=(IService) service;
                //调用服务,获取服务中的接口方法
                if(iService!=null)
                    Log.d("MyService", "iService bindService getCurrentTime"+iService.getCurrentTime());
            }
        };
        
        protected void onDestroy() {
            // TODO Auto-generated method stub
            Log.d("MyService", "localServiceActivity onDestroy");
            super.onDestroy();
        }
        
        
    }

    最后在mainfest中注册服务:

    <service android:name="com.tanlon.localservice.LocalService"></service>

    运行效果:

    运行结果:

    跨进程通信:

    第一步:建立服务端(ServiceServer) :配置aidl接口

    package com.tanlon.server;
    
    interface IService {
      long getCurrentTime();
      void setValue(in String from,in int value);
      String getValue();
    }

    配置服务类

    package com.tanlon.server;
    
    import com.tanlon.server.IService.Stub;
    import android.app.Service;
    import android.content.Intent;
    import android.os.IBinder;
    import android.os.RemoteException;
    import android.util.Log;
    
    public class MyService extends Service{
        //log标记
        private static final String TAG="MyService";
        
        private String str;
        
        private IService.Stub bind=new Stub() {
            
            public long getCurrentTime() throws RemoteException {
                // TODO Auto-generated method stub
                return System.currentTimeMillis();
            }
    
            public void setValue(String from, int value) throws RemoteException {
                // TODO Auto-generated method stub
                str="value from-------"+from+" and value is-------"+value;
                Log.d(TAG, "ServiceServer setValue from-------"+from+" value is-------"+value);
            }
    
            public String getValue() throws RemoteException {
                // TODO Auto-generated method stub
                return str;
            }
        };
        
        public IBinder onBind(Intent intent) {
            // TODO Auto-generated method stub
            Log.d(TAG, "ServiceServer onBind");
            return bind;
        }
    
        public void onCreate() {
            // TODO Auto-generated method stub
            Log.d(TAG, "ServiceServer onCreate");
            super.onCreate();
        }
    
        public void onDestroy() {
            // TODO Auto-generated method stub
            Log.d(TAG, "ServiceServer onDestroy");
            super.onDestroy();
        }
    
        public void onStart(Intent intent, int startId) {
            // TODO Auto-generated method stub
            Log.d(TAG, "ServiceServer onStart");
            super.onStart(intent, startId);
        }
    
        public boolean onUnbind(Intent intent) {
            // TODO Auto-generated method stub
            Log.d(TAG, "ServiceServer onUnbind");
            return super.onUnbind(intent);
        }
    
    }

    第二步:配置客户端1(ServiceClientOne):用来和服务端、其他的客户端交互数据(此处主要通过Service来设置值,其他的进程则通过Service来取这里设置的值)。

    先将服务端的com.tanlon.server包以及其下的IService.aidl一起拷到客户端下面来。

    接着就是客户端连接Service的代码:

    package com.tanlon.client;
    
    import java.text.SimpleDateFormat;
    import com.tanlon.server.IService;
    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;
    
    public class ServiceClientActivity extends Activity {
        private IService iService=null;
        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            //绑定服务,获取远程服务
            bindService(new Intent(IService.class.getName()), connection, BIND_AUTO_CREATE);
        }
        //连接服务
        private ServiceConnection connection=new ServiceConnection() {
            
            public void onServiceDisconnected(ComponentName name) {
                // TODO Auto-generated method stub
                iService=null;
            }
            
            public void onServiceConnected(ComponentName name, IBinder service) {
                // TODO Auto-generated method stub
                //获取绑定的接口
                iService=IService.Stub.asInterface(service);
                try {
                    if(iService!=null){
                        //调用远程服务中的方法
                        long date=iService.getCurrentTime();
                        Log.d("MyService", "IService getCurrentTime------"+getDate(date));
                        //为交互进程间的交互设置值
                        iService.setValue(ServiceClientActivity.class.getName(), 10);
                    }
                } catch (RemoteException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            
        };
        //将long型系统时间转换成当前时间
        private String getDate(long date){
            SimpleDateFormat formatter;  
            formatter = new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss");  
            String ctime = formatter.format(date);
            return ctime; 
        }
    
        protected void onDestroy() {
            // TODO Auto-generated method stub
            unbindService(connection);
            super.onDestroy();
        }
        
        
    }

    第三步:配置客户端2(ClientDemo):通过Service来获取客户端1设置的值。

    先将服务端的com.tanlon.server包以及其下的IService.aidl一起拷到客户端下面来。

    接着就是客户端连接Service的代码:

    package com.tanlon.clientdemo;
    
    import java.text.SimpleDateFormat;
    
    import com.tanlon.server.IService;
    
    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;
    
    public class ClientDemoActivity extends Activity {
        private IService iService=null;
        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            bindService(new Intent(IService.class.getName()), connection, BIND_AUTO_CREATE);
        }
        //连接服务
        private ServiceConnection connection=new ServiceConnection() {
            
            public void onServiceDisconnected(ComponentName name) {
                // TODO Auto-generated method stub
                iService=null;
            }
            
            public void onServiceConnected(ComponentName name, IBinder service) {
                // TODO Auto-generated method stub
                //获取绑定的接口
                iService=IService.Stub.asInterface(service);
                try {
                    if(iService!=null){
                        //调用远程服务中的方法
                        long date=iService.getCurrentTime();
                        Log.d("MyService", "IService getCurrentTime------"+getDate(date));
                        //获取进程间的交互值
                        String str=iService.getValue();
                        Log.d("MyService", "IService getValue------"+str);
                    }
                } catch (RemoteException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            
        };
        //将long型系统时间转换成当前时间
        private String getDate(long date){
            SimpleDateFormat formatter;  
            formatter = new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss");  
            String ctime = formatter.format(date);
            return ctime; 
        }
    
        protected void onDestroy() {
            // TODO Auto-generated method stub
            unbindService(connection);
            super.onDestroy();
        }
    }

    运行结果:

  • 相关阅读:
    Flipping with Physis: Motion Editing for Acrobatics
    Practicle Character Physics For Animators
    html5 files属性
    ASP.NET大文件上传设置。maxRequestLength无效的情况
    elasticsearch
    html用Css来关闭sougou输入框
    模拟form提交
    疯狂的跨域技术
    日志记录用NLog
    备份iis站点信息
  • 原文地址:https://www.cnblogs.com/sevenyuan/p/2975682.html
Copyright © 2011-2022 走看看