• [原] 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();
    }
    }

    运行结果:

     

     

     

     

    注:不知道如何上传压缩包,各位如果需要的话,给我留言,我的QQ:745228153。

     

     





      

  • 相关阅读:
    JSON数据格式
    AJAX入门
    SpringMVC如何处理JSON数据和运行流程
    SpringMVC视图解析器与数据类型转换
    SpringMVC入门——基础知识
    SpringMVC自定义拦截器与异常处理
    SpringMVC实现文件的上传和下载
    Eclipse中安装Springtools插件的步骤
    SpringMVC实现员工信息的增删改查
    文件的上传与下载
  • 原文地址:https://www.cnblogs.com/tanlon/p/2195980.html
Copyright © 2020-2023  润新知