Android 跨进程调用service学(一)

1.android 系统中,各应用程序都在自己的进程中运行,进程之间一般无法直接交换数据,为了实现这种跨进程通信(interprocess  communication  简称IPC),android 提供了AIDL  Service。今天这篇博客主要讲下ipc,基本数据的交互。下一篇在讲复杂性数据的交互。


2.第一步:需要创建一个AIDL文件。 首先创建一个project,然后在创建一个AIDL文件。如下图


Android 跨进程调用service学(一)_第1张图片


这个文件是一个接口,不过和java接口不同,这个接口里面的抽象方法不能用public修饰。其他的地方和接口差不多。

在这个接口中我声明了俩个抽象方法,如下图:

// IMyAidlInterface.aidl
package com.example.lenovo.aidltest;

// Declare any non-default types here with import statements

interface IMyAidlInterface {

//Aidl接口和java接口不同,方法不能用public接口生命;
    String getcolor();
    double getweight();
    void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
            double aDouble, String aString);
}

一般创建好AIDL,文件,会帮我自己创建一个java接口,这个接口不仅仅实现了IBinder接口,也实现了IMyAidlInterface接口。

刚学习ipc的时候,可能找不到这个文件在哪,很多文章说在aidl文件夹下可以找到 ,但是楼主却没找到。最后发现在

Android 跨进程调用service学(一)_第2张图片


找到了这个抽象类接口。怎样做的呢。就是得到Aidl文件之后,先make-project下  然后再上面图片中的路径下寻找。


第二步: 在创建一个service类,并在里面实现了 这个java接口(在这里我做实验的时候接口是IMyAidlInterface.Stub
抽象类)。具体如下图:

package com.example.lenovo.aidltest;

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

public class MyService extends Service {
    IpcTest test;
    public MyService() {
    }
    @Override
    public void onCreate() {
        super.onCreate();
        test=new IpcTest();
    }
    @Override
    public IBinder onBind(Intent intent) {

        return test;
    }
    class IpcTest extends IMyAidlInterface.Stub{
        @Override
        public String getcolor() throws RemoteException {
            return "黑色";
        }
        @Override
        public double getweight() throws RemoteException {
            return 88.45;
        }
        @Override
        public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {
        }
    }
}
为了方面起见,在重写的方法getcolor,和getweight中,我是直接返回数据的。

然后再AndroidManifest 文件中声明这个Service ,并加上Intent-Filter 设置好action。


第三步:创建新的project,这个项目就是调用Service的项目。之后把含有Aidl文件的project的目录 ,也就是

Android 跨进程调用service学(一)_第3张图片

这个文件都要拷贝到新建的项目中。注意要完全一模一样。包括里面的package,我做的时候,虽然你是直接copy到新项目中的,但是as会自动把你的这个package名称改掉。于是报错了。


第四步:在MainActivity里面直接调用这个Service。具体详细代码如下:


package com.example.lenovo.ipcclient;

import android.app.Service;
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.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.example.lenovo.aidltest.IMyAidlInterface;

public class MainActivity extends AppCompatActivity {
    IMyAidlInterface test;
    private ServiceConnection conn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            test= IMyAidlInterface.Stub.asInterface(service);
            try {
                String s=test.getcolor();
                Toast.makeText(MainActivity.this,s,Toast.LENGTH_LONG).show();
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button but= (Button) findViewById(R.id.but);
        TextView color= (TextView) findViewById(R.id.color);
        TextView weight= (TextView) findViewById(R.id.weight);

        but.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent=new Intent();
                intent.setAction("android.intent.action.ipc");
                //this is important
                intent.setPackage("com.example.lenovo.aidltest");
                bindService(intent, conn, Service.BIND_AUTO_CREATE);
            }
        });
        final Button unbind= (Button) findViewById(R.id.unbind);
        unbind.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                unbindService(conn);
            }
        });

    }
}

主activity怎么调用这个Service呢。如:我标记颜色的代码:然后通过“绑定式"  启动Service,在
ServiceConnection con 这个地方需要主要,asInterface(service)这个静态方法拿到,那个抽象类的。这个方法可以在  java接口中看到。拿到了那个对象,就可以直接调用getcolor方法了。

好了调用简单数据类型的 IPC,就到这里了,大家可以试试瞧,有什么不懂的,可以留言。


你可能感兴趣的:(android-知识)