AIDL学习笔记(三)----客户端和服务端相互远程调用

这里写图片描述

先看一下文件目录:
service端:

这里写图片描述

然后是客户端:

这里写图片描述

service端代码:

AIDL文件:

IOnNewBookArrivedListener

// IOnNewBookArrivedListener.aidl
package com.sjq.service;

// Declare any non-default types here with import statements
import com.sjq.service.Book;
interface IOnNewBookArrivedListener {
    void onNewBookArrived(in Book newbook);
}

interface IBookManager:

// IBookManager.aidl
package com.sjq.service;

// Declare any non-default types here with import statements
import com.sjq.service.Book;
import com.sjq.service.IOnNewBookArrivedListener;
interface IBookManager {
    void addBook(in Book book);
       List<Book> getBookList();
       void  registerOnNewBookArrivedListener(in IOnNewBookArrivedListener listener);
       void  unregisterOnNewBookArrivedListener(in IOnNewBookArrivedListener listener);
}

Book:

// Book.aidl
package com.sjq.service;

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

parcelable Book;

Service代码:

package com.sjq.service;

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

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;

public class MyService extends Service {
    //书本集合
    CopyOnWriteArrayList<Book> list;
    //所有注册过的监听的客户端
    RemoteCallbackList<IOnNewBookArrivedListener> listeners;

    private AtomicBoolean isServiceDestoryed = new AtomicBoolean(false);

    public MyService() {

    }

    @Override
    public IBinder onBind(Intent intent) {
        list = new CopyOnWriteArrayList<>();
        list.add(new Book(0, "深入理解Java虚拟机" + 0));
        list.add(new Book(list.size() + 1, "深入理解Java虚拟机" + list.size() + 1));
        listeners = new RemoteCallbackList<>();
        new Thread(new AddBookRunnable()).start();
        return binder;
    }

    IBookManager.Stub binder = new IBookManager.Stub() {

        @Override
        public void addBook(Book book) throws RemoteException {
            list.add(book);
           // Log.i("Book", "addBook:---------->" + book.toString());
        }

        @Override
        public List<Book> getBookList() throws RemoteException {
           // Log.i("Book", "getBookList:---------->" + list.toString());
            return list;
        }

        @Override
        public void registerOnNewBookArrivedListener(IOnNewBookArrivedListener listener) throws RemoteException {
           listeners.register(listener);
        }

        @Override
        public void unregisterOnNewBookArrivedListener(IOnNewBookArrivedListener listener) throws RemoteException {
           listeners.unregister(listener);
        }
    };


    class AddBookRunnable implements Runnable {

        @Override
        public void run() {
            while (!isServiceDestoryed.get()) {
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                int bookId = list.size() + 1;
                Book book = new Book(bookId, "深入理解Java虚拟机");
                AddBook(book);
            }
        }
    }
    //在service线程中增加新书
    private void AddBook(Book book) {
        list.add(book);
        final int n = listeners.beginBroadcast();
        for (int i = 0; i < n; i++) {
            IOnNewBookArrivedListener lis = listeners.getBroadcastItem(i);
            try {
                if(lis!=null){
                    //和普通的回调是一样的,不过此处的回调实现是在客户端实现的
                    //通知所有注册过的客户端,有新书
                    lis.onNewBookArrived(book);
                }

            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
        listeners.finishBroadcast();
    }

}

Book:

package com.sjq.service;

import android.os.Parcel;
import android.os.Parcelable;

/**
 * Created by cs001 on 2016/6/29.
 */
public class Book implements Parcelable{
    int BookId;
    String BookName;

    public Book(int bookId, String bookName) {
        this.BookId = bookId;
        this.BookName = bookName;
    }

    protected Book(Parcel in) {
        this.BookId = in.readInt();
        this.BookName = in.readString();
    }

    public static final Creator<Book> CREATOR = new Creator<Book>() {
        @Override
        public Book createFromParcel(Parcel in) {
            return new Book(in);
        }

        @Override
        public Book[] newArray(int size) {
            return new Book[size];
        }
    };

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel parcel, int i) {
        parcel.writeInt(BookId);
        parcel.writeString(BookName);
    }

    @Override
    public String toString() {
        return "Book{" +
                "BookId=" + BookId +
                ", BookName='" + BookName + '\'' +
                '}';
    }
}

然后是客户端,复制过来的AIDL文件和实体类文件目录结构还是要和service完全一致:

package com.sjq.aidl_client;

import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;

import com.sjq.service.Book;
import com.sjq.service.IBookManager;
import com.sjq.service.IOnNewBookArrivedListener;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {

    Button btn;
    ArrayList<Book> books;


    private IBookManager manager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btn = (Button) findViewById(R.id.btn);
        Intent intent = new Intent();
        intent.setComponent(new ComponentName("com.sjq.service", "com.sjq.service.MyService"));
        bindService(intent, conn, BIND_AUTO_CREATE);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                try {
                    books = (ArrayList<Book>) manager.getBookList();
                    Log.i("Book", books.toString());
                    manager.addBook(new Book(books.size() + 1, "Java虚拟机" + books.size() + 1));
                    books = (ArrayList<Book>) manager.getBookList();
                    Log.i("Book", books.toString());
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        });

    }
    //连接成功回调
    ServiceConnection conn = new ServiceConnection() {
        //运行在UI线程
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            Log.i("Book", "------onServiceConnected-------");
            //连接成功,将Binder对象转换为IBookManager接口对象,同一个进程返回IBookManager.Stub
            //不同进程返回IBookManager.Stub.Proxy
            manager = IBookManager.Stub.asInterface(iBinder);
            try {

                //注册监听器
                manager.registerOnNewBookArrivedListener(listener);

                Log.i("listener", "manager.registerOnNewBookArrivedListener(listener)");
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

        //运行在UI线程
        @Override
        public void onServiceDisconnected(ComponentName componentName) {

        }
    };


    //有新书监听 实现AIDL接口的子类
    IOnNewBookArrivedListener.Stub listener = new IOnNewBookArrivedListener.Stub() {

        @Override
        public void onNewBookArrived(Book newbook) throws RemoteException {
            Log.i("Book", "onNewBookArrived:--------> " + "来新书了!!!!");

        }


    };





    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (listener != null && manager.asBinder().isBinderAlive()) {
            try {
                manager.unregisterOnNewBookArrivedListener(listener);
                Log.i("listener", "manager.unregisterOnNewBookArrivedListener(listener)");
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
    }
}

个人理解:

这里写图片描述

猜你喜欢

转载自blog.csdn.net/lantiankongmo/article/details/51783558