Android 远程服务 Service

1、远程服务:使用 AIDL(Android Interfice Definition Language) 安卓接口定义语言进行 IPC(Inter Process Communication)跨进程通信。
2、注意:

1.AIDL 支持数据类型:1.基本数据类型。2.String、CharSequence。3.ArrayList、HashMap。4.AIDL 接口。5.实现 Parcelable 接口的类。

3、具体应用

1、服务端

  1. 创建共享类
public class Person implements Parcelable {

    private String name;
    private int age;

    public Person() {
        super();
        // TODO Auto-generated constructor stub
    }

    public Person(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public int describeContents() {
        // TODO Auto-generated method stub
        return 0;
    }

    @Override
    public void writeToParcel(Parcel arg0, int arg1) {
        arg0.writeString(name);
        arg0.writeInt(age);

    }

    public static final Creator<Person> CREATOR = new Creator<Person>() {

        @Override
        public Person createFromParcel(Parcel arg0) {
            // TODO Auto-generated method stub
            return new Person(arg0.readString(), arg0.readInt());
        }

        @Override
        public Person[] newArray(int arg0) {
            // TODO Auto-generated method stub
            return new Person[arg0];
        }
    };

}
  1. 创建 AIDL 文件,并编译(Build->Make Project)
// Person.aidl
package com.strugglelin.demo.aidl;
parcelable Person;
// IPersion.aidl
package com.strugglelin.demo.aidl;
import com.strugglelin.demo.aidl.Person;
interface IPerson{
Person getPerson();
}
// ITest.aidl
package com.strugglelin.demo.aidl;
interface ITest{
int getNumber();
}
  1. 创建远程服务 Service
public class AidlService extends Service {

    @Override
    public void onCreate() {
        Log.e("tag", "onCreate");
    }

    @Override
    public boolean onUnbind(Intent intent) {
        Log.e("tag", "onUnbind");
        return true;
    }

    @Override
    public void onDestroy() {
        Log.e("tag", "onDestroy");
    }

    TestBinder bind = new TestBinder();
    ComplexBinder cbind = new ComplexBinder();
    private static final String PACKAGE_SAYHI = "com.strugglelin.client";
    private static final int FLAG_TEST_BINDER = 0;
    private static final int FLAG_COMPLEX_BINDER = 1;
    @Override
    public IBinder onBind(Intent arg0) {
        Log.e("tag", "onBind");
        Bundle bundle = arg0.getExtras();
        if (bundle.getInt("flag") == FLAG_TEST_BINDER) {
            return bind;
        } else if (bundle.getInt("flag") == FLAG_COMPLEX_BINDER) {
            return cbind;
        }
        return null;
    }

    public class TestBinder extends com.strugglelin.demo.aidl.ITest.Stub {

        Random rnd = new Random();

        @Override
        public int getNumber() throws RemoteException {
            return rnd.nextInt(100);
        }
    }

    public class ComplexBinder extends com.strugglelin.demo.aidl.IPerson.Stub {

        @Override
        public Person getPerson() throws RemoteException {
            return new Person("AAA", 123);
        }

        /**
         * 在这里可以做权限认证,return false意味着客户端的调用就会失败,比如下面,只允许包名为com.strugglelin.client 的客户端通过,其他apk将无法完成调用过程
         */
        @Override
        public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
                throws RemoteException {
            String packageName = null;
            String[] packages = AidlService.this.getPackageManager().
                    getPackagesForUid(getCallingUid());
            if (packages != null && packages.length > 0) {
                packageName = packages[0];
            }
            Log.e("tag", "onTransact: " + packageName);
            if (!PACKAGE_SAYHI.equals(packageName)) {
                return false;
            }

            return super.onTransact(code, data, reply, flags);
        }
    }
}

  1. AndroidManifest.xml 注册服务
        <service
            android:name="com.strugglelin.demo.service.AidlService"
            android:process=":remote"
            android:exported="true">
            <intent-filter>
                <category android:name="android.intent.category.LAUNCHER" />
                <action android:name="com.strugglelin.demo.service.AidlService"/>
            </intent-filter>
        </service>

2、客户端

  1. 将服务端的 AIDL 文件复制到客户端。
  2. 绑定远程服务通信。
public class MainActivity extends AppCompatActivity {

    private Button mBindServiceBtn, mGetDataBtn, mUnbindServiceBtn;
    private boolean isConnected = false;
    public static final int FLAG = 1;
    ITest binder;
    IPerson pbind;

    ServiceConnection conn = new ServiceConnection() {

        @Override
        public void onServiceDisconnected(ComponentName arg0) {

            Log.e("tag", "断开连接");
        }

        @SuppressWarnings("unused")
        @Override
        public void onServiceConnected(ComponentName arg0, IBinder arg1) {
            // 服务器建立连接
            Object obj = IPerson.Stub.asInterface(arg1);
            if (FLAG == 0) {
                binder = ITest.Stub.asInterface(arg1);
                Log.e("tag", "ITest建立连接");
            } else {
                pbind = IPerson.Stub.asInterface(arg1);
                Log.e("tag", "IPerson建立连接");
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mBindServiceBtn = findViewById(R.id.mBindServiceBtn);
        mGetDataBtn =  findViewById(R.id.mGetDataBtn);
        mUnbindServiceBtn =  findViewById(R.id.mUnbindServiceBtn);
        mBindServiceBtn.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // 方法一 1.通过action和包名设置
                Intent intent = new Intent("com.strugglelin.demo.service.AidlService").setPackage("com.strugglelin.demo");
                intent.putExtra("flag", FLAG);

//				  方法二 2.通过包名和类名设置
//				  Intent service = new Intent();
//				  service.setComponent(new ComponentName("com.strugglelin.demo","com.strugglelin.demo.service.AidlService"));

                isConnected = bindService(intent, conn, BIND_AUTO_CREATE);
                Log.e("tag", "绑定成功");
            }
        });

        mGetDataBtn.setOnClickListener(new OnClickListener() {

            @SuppressWarnings("unused")
            @Override
            public void onClick(View arg0) {

                try {
                    if (FLAG == 0) {
                        Log.e("tag", binder.getNumber() + "");
                    } else {
                        if (null != pbind) {
                            Person p = pbind.getPerson();
                            if (null != p) {
                                Log.e("tag", pbind.getPerson().getName());
                            } else {
                                Log.e("tag", "Person null");
                            }
                        } else {
                            Log.e("tag", "IPerson null");
                        }
                    }

                } catch (RemoteException e) {
                    Log.e("tag", "异常");
                    e.printStackTrace();
                }

            }
        });
        mUnbindServiceBtn.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                if (isConnected) {
                    unbindService(conn);
                    isConnected = false;
                }
            }
        });
    }

}

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值