Android进程间通信方式总结(IPC)

第一种:Intent方式

Intent分为两种,一种是显式Intent,只适合在同一进程内的不同组件之间通信,例如 new Intent(this,Target.class).

另外一种是隐式Intent,在AndroidMainifest.xml中注册,一般可以用户跨进程通信,例如new Intent(String action).

下面就介绍隐式Intent跨进程通信的例子:

Project A 中的代码比较简单,主要就是在的button onClick事件中:

button.setOnClickListener(new OnClickListener()
        {           
            @Override public void onClick(View v)
            {     
                Intent intent = new Intent();
                intent.setAction("com.example.IPCByIntent");
                intent.putExtra("data", "this is ipc by intent");
                startActivity(intent);
             
            }
        });

其中intent.SetAction里面的值是Project B中定义的。


在Project B中的AndroidMainifest.xml,在MainActivity的第二个intent-filter中,添加在Project A中用到的action值

      
            
                

                
            
            
                
                
            
        

在Project B的MainActivity.java的OnCreate方法中,添加如下代码

       Intent intent = this.getIntent();
       if(null != intent.getStringExtra("data")){
           tv.setText(intent.getStringExtra("data"));
       }


先运行Project B,在运行Project A,点击 Porject A 的button,则Project B上的textview 将会显示 this is ipc by intent.

Intent 可以非常方便的通信,但是它是非实时的,无法进行实时的像函数调用那样的实时通信。


第二种方式:AIDL方式

AIDL方式应该是应用的比较多的一种方式,下面介绍一个简单的例子来实现用AIDL解决进程之间的数据传递。

有两个Project,AIDLDemo 和AIDLDemoClient,AIDLDemo里面有一个Service,我们当作是Server Project,另外一个AIDLDemoClient我们当作是Client.


首先看Server Project,首先新建一个File,myAidl.aidl,注意后缀名要是.aidl.其实就是一个接口文件,在该文件中:

1.我们不需要使用public,protected,private等修饰符.

2.对于基本类型,如int,String等我们不需要import.

3.如果在文件中引用别的aidl文件接口,需要import进来,即使在一个包下面也需要import.

package com.sha.aidl;

interface myAidl{
   int add(int x,int y);
   String get();
}


定义好myAidl.aidl文件以后,build project,系统会给我们自动生成一个myAidl.java文件,在gen下面


然后在AndroidMainifest.xml中注册静态Service如下:

        
            
                
            
            
        


定义Service文件

这里面核心的步骤就是定义了一个 myAidl.Stub的 Binder,然后在onBinder函数里面,返回这个Binder.

package com.example.adildemo;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;

import com.sha.aidl.myAidl;

public class myService extends Service
{
    @Override public IBinder onBind(Intent intent)
    {
        return myBinder;
    }

    private myAidl.Stub myBinder = new myAidl.Stub()
    {

        @Override public int add(int x, int y) throws RemoteException
        {
            return x + y;
        }

        @Override public String get() throws RemoteException
        {
            return "test";
        }
       
    };    
}

至此,Server Project的工作就完成了。


下面看看Client Project的内容:

把ADILDemo里面的myAidl.aidl拷贝到ADILDemo_Client项目中,注意myAidl.aidl的包名一定要一致,如果不一致会出现错误。


Android进程间通信方式总结(IPC)_第1张图片 Android进程间通信方式总结(IPC)_第2张图片


在ADIDemo_Client的MainActivity.java文件中:


首先在OnCreate函数里面,绑定Service,定义一个ServiceConnection变量,通过调用myAidl.stub.asInterface(IBinder)方法获取myAidl变量,然后调用myAidl变量的get方法

package com.example.adildemo;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.example.adildem.R;
import com.sha.aidl.myAidl;

public class MainActivity extends Activity
{
    private Button button;
    private myAidl aidl;
    private TextView tv;
    
    private ServiceConnection sc = new ServiceConnection()
    {
        
        @Override public void onServiceDisconnected(ComponentName name)
        {
            aidl = null;
            
        }
        
        @Override public void onServiceConnected(ComponentName name, IBinder service)
        {
           aidl = myAidl.Stub.asInterface(service);
            
        }
    };
    
    @Override protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        button = (Button)findViewById(android.R.id.button1);
        tv = (TextView)findViewById(android.R.id.text1);
        
        Intent intent = new Intent("com.example.adildemo.myService");
        bindService(intent, sc, Context.BIND_AUTO_CREATE);
        
     /*  Intent intent = this.getIntent();
       if(null != intent.getStringExtra("data")){
           tv.setText(intent.getStringExtra("data"));
       }*/
        
        button.setOnClickListener(new OnClickListener()
        {
            
            @Override public void onClick(View v)
            {
                
                String result = "";
                try
                {
                    result = aidl.get();
                }
                catch (RemoteException e)
                {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                Toast.makeText(MainActivity.this, result+"", Toast.LENGTH_SHORT).show();
            }
        });
        
    }
    
}

先运行AIDLDemo project,再运行AIDLDemoClient project,点击button,弹出toast,表示client调用server成功

第三种方式:Messenger方式

AndroidMainifest.xml中注册静态Service如下:

        
            
                
            
        


Service文件:

package com.example.aidldemomessager;

import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.widget.Toast;

public class myService extends Service
{

    private Handler serviceHandler = new Handler(){

        @Override public void handleMessage(Message msg)
        {
            Toast.makeText(getApplicationContext(), "test", Toast.LENGTH_LONG).show();
        }
        
    };
    
    private Messenger messager = new Messenger(serviceHandler);
    
    @Override public IBinder onBind(Intent intent)
    {
        return messager.getBinder();
    }

}

MainActivity文件

package com.example.aidldemomessager;


import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;


public class MainActivity extends Activity
{


    private Button button;
    
    @Override protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        Intent intent = new Intent("com.example.aidldemomessager.myService");
        bindService(intent, sc, Context.BIND_AUTO_CREATE);
        
        button = (Button)findViewById(R.id.button);
        
        button.setOnClickListener(new OnClickListener()
        {
            
            @Override public void onClick(View v)
            {
               
                Message msg = new Message();
                msg.what = 1;
                try
                {
                    messenger.send(msg);
                }
                catch (RemoteException e)
                {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        });
    }


    private Messenger messenger;
    
    private ServiceConnection sc = new ServiceConnection()
    {
        
        @Override public void onServiceDisconnected(ComponentName name)
        {
            messenger = null;
        }
        
        @Override public void onServiceConnected(ComponentName name, IBinder service)
        {
            messenger = new Messenger(service);
        }
    };
    
    


}


你可能感兴趣的:(Android)