IPC学习之AIDL小试牛刀
来源:互联网 发布:英语同义词词典 知乎 编辑:程序博客网 时间:2024/05/16 09:40
最近在学习IPC进程间通信,在此记录下AIDL的使用,并附上一个Demo:服务端每隔一分钟添加一本书籍,客户端通过进程间通信,获取当前服务端的书籍列表,并且服务端对外开放添加、删除等操作。
终于明白鸿洋所说的App效果图尽力的意思了!Android屏幕截图方法可参考:http://www.jianshu.com/p/9a1825e679b7
服务端:
1、新建一个AIDLServer工程,创建一个Parcelable接口类Book
package com.aa.aidlserver;import android.os.Parcel;import android.os.Parcelable;public class Book implements Parcelable { public String name; public String describe; public Book(String name, String describe) { this.name = name; this.describe = describe; } protected Book(Parcel in) { name = in.readString(); describe = 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.writeString(name); parcel.writeString(describe); }}
2、创建两个aidl文件:Book.aidl和IBookManager.aidl
// Book.aidlpackage com.aa.aidlserver;parcelable Book;
// IBookManager.aidlpackage com.aa.aidlserver;import com.aa.aidlserver.Book;interface IBookManager { //获取书本列表 List<Book> getBookList(); //添加书本 void addBook(in Book book); //删除书本 void deleteBook(in Book book);}
注意:
- 其中Book.aidl用来声明Book实现了Parcelable接口
- 因为在IBookManager中使用了Book参数,所以无论Book.java是否在同一个包名下,都必须进行一次import
3、创建自定义Service,创建一个IBookManager.Stub对象,即一个Binder对象,重写onBind方法返回这个对象。然后在AndroidManifest中声明此Service,并加入action
package com.aa.aidlserver;import android.app.Service;import android.content.Intent;import android.os.Binder;import android.os.IBinder;import android.os.RemoteException;import android.support.annotation.Nullable;import android.util.Log;import java.util.List;import java.util.concurrent.CopyOnWriteArrayList;public class AIDLService extends Service { /** * 书本列表 */ private CopyOnWriteArrayList<Book> mBookList = new CopyOnWriteArrayList<>(); private Binder mBinder = new IBookManager.Stub() { @Override public List<Book> getBookList() throws RemoteException { return mBookList; } @Override public void addBook(Book book) throws RemoteException { mBookList.add(book); } @Override public void deleteBook(Book book) throws RemoteException { mBookList.remove(0); } }; @Nullable @Override public IBinder onBind(Intent intent) { return mBinder; } @Override public int onStartCommand(Intent intent, int flags, int startId) { if(mBookList.size() == 0) { mBookList.add(new Book("他们最幸福", "一个屌丝写的书")); mBookList.add(new Book("晓松奇谈", "矮大紧写的书")); } else { addBook(); } return super.onStartCommand(intent, flags, startId); } /** * 通过定时任务来添加书本信息 */ private void addBook() { Log.e("TAG", "Adding..."); int len = mBookList.size() + 1; String name = "图书" + len; String describe = "这是第" + len + "本书"; Book book = new Book(name, describe); mBookList.add(book); }}
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.aa.aidlserver"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> <service android:name=".AIDLService" android:process=":remote"> <intent-filter> <action android:name="com.aa.aidlserver.AIDLService"/> </intent-filter> </service> </application></manifest>
4、在MainActivity中使用AlarmManager每隔一分钟创建(打开)Service
package com.aa.aidlserver;import android.app.AlarmManager;import android.app.PendingIntent;import android.content.Intent;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initAlarmManager(); } /** * 初始化定时任务 */ private void initAlarmManager() { Intent intent = new Intent(); // 设置Intent的Action 属性 intent.setAction("com.aa.aidlserver.AIDLService"); // Android 5.0以上需要设置包名 intent.setPackage("com.aa.aidlserver"); //创建一个PendingIntent对象,包含了startService操作 PendingIntent pi = PendingIntent.getService(this, 0,intent, PendingIntent.FLAG_UPDATE_CURRENT); AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE); long intervalMillis = 60 * 1000; //创建一个系统级定时器,即使熄屏状态也会每隔一分钟启动一次Service添加书本(注:部分定制系统定时器不准) am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), intervalMillis, pi); }}
5、在app的build.gradle文件的android节点中添加以下代码,可解决找不到Book类的问题
sourceSets { main { manifest.srcFile 'src/main/AndroidManifest.xml' java.srcDirs = ['src/main/java', 'src/main/aidl'] resources.srcDirs = ['src/main/java', 'src/main/aidl'] aidl.srcDirs = ['src/main/aidl'] res.srcDirs = ['src/main/res'] assets.srcDirs = ['src/main/assets'] }}
至此服务端就开发完毕了,相比之下,客户端的就简单一些。
客户端:
1、新建一个AIDLClient工程,将AIDLServer工程的app\src\main\aidl目录拷贝到AIDLClient工程的app\src\main目录下,不需任何修改(注意这里的包名、文件都与AIDLServer是一致的)
2、服务端每隔一分钟会添加一本书,所以在客户端MainActivity中获取当前服务端书本列表并显示,也可进行添加、删除等操作
package com.aa.aidlclient;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.util.Log;import android.view.View;import android.widget.ArrayAdapter;import android.widget.Button;import android.widget.ListView;import android.widget.Toast;import com.aa.aidlserver.Book;import com.aa.aidlserver.IBookManager;import java.util.ArrayList;import java.util.List;public class MainActivity extends AppCompatActivity implements View.OnClickListener { private ListView mListView; private ArrayAdapter<String> mAdapter; private List<String> mBooks = new ArrayList<>(); private Button btnLoadmore, btnAdd, btnDetele; private IBookManager mIBookManager; private ServiceConnection mServiceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName componentName, IBinder iBinder) { //Service已连接 mIBookManager = IBookManager.Stub.asInterface(iBinder); } @Override public void onServiceDisconnected(ComponentName componentName) { //Service已断开 mIBookManager = null; } }; private void toast(String msg) { Toast.makeText(this, msg, Toast.LENGTH_SHORT).show(); Log.e("AA", "收到Log:" + msg); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mListView = (ListView) findViewById(R.id.lv_main); btnLoadmore = (Button) findViewById(R.id.btn_main_loadmore); btnLoadmore.setOnClickListener(this); btnAdd = (Button) findViewById(R.id.btn_main_add); btnAdd.setOnClickListener(this); btnDetele = (Button) findViewById(R.id.btn_main_delete); btnDetele.setOnClickListener(this); bindAIDLService(); } @Override protected void onDestroy() { unbindAIDLService(); super.onDestroy(); } /** * 绑定AIDL服务 */ private void bindAIDLService() { Intent intent = new Intent("com.aa.aidlserver.AIDLService"); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // Android 5.0以上需要设置包名 intent.setPackage("com.aa.aidlserver"); bindService(intent, mServiceConnection, BIND_AUTO_CREATE); } /** * 解绑AIDL服务 */ private void unbindAIDLService() { if(mIBookManager != null) { unbindService(mServiceConnection); } } @Override public void onClick(View view) { switch (view.getId()) { case R.id.btn_main_loadmore: //加载更多 try { List<Book> books = mIBookManager.getBookList(); if(books != null && books.size() > 0) { if(mBooks.size() > 0) { mBooks.clear(); } //解析数据 for(Book book : books) { mBooks.add("Name:" + book.name + " --- Describe:" + book.describe); } //填充数据 mAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, android.R.id.text1, mBooks); mListView.setAdapter(mAdapter); } } catch (RemoteException e) { e.printStackTrace(); } break; case R.id.btn_main_add: //新增图书 int len = mBooks.size() + 1; String name = "图书" + len; String describe = "这是第" + len + "本书"; Book book = new Book(name, describe); try { mIBookManager.addBook(book); mBooks.add("Name:" + book.name + " --- Describe:" + book.describe); mAdapter.notifyDataSetChanged(); } catch (RemoteException e) { e.printStackTrace(); } break; case R.id.btn_main_delete: //删除图书 if(mBooks.size() > 0) { try { Book book1 = mIBookManager.getBookList().get(0); mIBookManager.deleteBook(book1); mBooks.remove(0); mAdapter.notifyDataSetChanged(); } catch (RemoteException e) { e.printStackTrace(); } } else { toast("已经没有书可以删除了"); } break; } }}
3、客户端也需要在app的build.gradle文件的android节点中添加以下代码,解决找不到Book类的问题
sourceSets { main { manifest.srcFile 'src/main/AndroidManifest.xml' java.srcDirs = ['src/main/java', 'src/main/aidl'] resources.srcDirs = ['src/main/java', 'src/main/aidl'] aidl.srcDirs = ['src/main/aidl'] res.srcDirs = ['src/main/res'] assets.srcDirs = ['src/main/assets'] }}
其实,AIDL说简单也不简单,难也并不难,还是需要根据实际需求来做的。
CSDN源码下载
Github AIDLServer
Github AIDLClient
- IPC学习之AIDL小试牛刀
- Android IPC之AIDL
- Android IPC 之AIDL
- Android IPC之AIDL
- IPC之AIDL简析
- Android IPC 之 AIDL
- IPC通信之AIDL
- IPC之AIDL
- Android IPC之AIDL
- Android:IPC之AIDL的学习和总结
- IPC之AIDL(1)实现AIDL
- AIDL学习(一)---IPC通讯
- AIDL与IPC学习总结
- Android IPC之AIDL浅谈
- IPC机制之AIDL、Messenger
- IPC之AIDL&binder关系
- android IPC机制之 AIDL
- android进程间通信(IPC)之AIDL
- 实习生之路(1)---简单的公司项目360商店上传
- 关于数据库连接池的最大空闲时间的配置
- 关于浏览器缓存的知识
- java环境变量配置,java小程序的编译运行规则
- iOS微信支付
- IPC学习之AIDL小试牛刀
- 5-48 银行排队问题之单窗口“夹塞”版 (30分)
- 宣告"主权"
- Tor原理
- Android UI 理解
- Android之Adapter用法总结
- nodejs死亡笔记之实战篇---微信公众号的开发(2)
- elasticsearch-2.3.5安装search-guard-2.3.5.15遇到的问题
- first day