1.ContentProvider ContentProvider的底层实现是基于Binder,系统为我们做了深度的封装,让我们使用起来非常容易。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 public class BookProvider extends ContentProvider { private static final String AUTHORITY = "com.gacrnd.gcs.ipc.BookProvider" ; public static final Uri BOOK_CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/book" ); public static final Uri USER_CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/user" ); public static final int BOOK_URI_CODE = 0 ; public static final int USER_URI_CODE = 1 ; private Context mContext; private SQLiteDatabase mDatabase; private static final UriMatcher sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); static { sUriMatcher.addURI(AUTHORITY,"book" ,BOOK_URI_CODE); sUriMatcher.addURI(AUTHORITY,"user" ,USER_URI_CODE); } private String getTableName (Uri uri) { String tableName = null ; switch (sUriMatcher.match(uri)) { case BOOK_URI_CODE: tableName = DbOpenHelper.BOOK_TABLE_NAME; break ; case USER_URI_CODE: tableName = DbOpenHelper.USER_TABLE_NAME; break ; default : break ; } return tableName; } @Override public boolean onCreate () { mContext = getContext(); initDatabase(); return true ; } private void initDatabase () { mDatabase = new DbOpenHelper(mContext).getWritableDatabase(); mDatabase.execSQL("DELETE FROM " + DbOpenHelper.BOOK_TABLE_NAME); mDatabase.execSQL("DELETE FROM " + DbOpenHelper.USER_TABLE_NAME); mDatabase.execSQL("INSERT INTO book VALUES(1,'ANDROID 1');" ); mDatabase.execSQL("INSERT INTO book VALUES(2,'ANDROID 2');" ); mDatabase.execSQL("INSERT INTO book VALUES(3,'ANDROID 3');" ); mDatabase.execSQL("INSERT INTO user VALUES(1,'JackOu',0);" ); mDatabase.execSQL("INSERT INTO user VALUES(2,'DY',1);" ); } @Override public Cursor query (Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { Log.i("JackOu" ,"query:" + Thread.currentThread().getName()); String tableName = getTableName(uri); if (tableName == null ) { throw new IllegalArgumentException("uri illegal!" ); } return mDatabase.query(tableName,projection,selection,selectionArgs,null ,sortOrder,null ); } ...... }
1 2 3 4 5 6 <provider android:authorities="com.gacrnd.gcs.ipc.BookProvider" android:name=".BookProvider" android:permission="com.gacrnd.gcs.PROVIDER" android:process=":provider" />
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 public class DbOpenHelper extends SQLiteOpenHelper { private static final String DB_NAME = "book_provider.db" ; public static final String BOOK_TABLE_NAME = "book" ; public static final String USER_TABLE_NAME = "user" ; private String CREATE_BOOK_TABLE = "CREATE TABLE IF NOT EXISTS " + BOOK_TABLE_NAME + "(_id INTEGER PRIMARY KEY, name TEXT)" ; private String CREATE_USER_TABLE = "CREATE TABLE IF NOT EXISTS " + USER_TABLE_NAME + "(_id INTEGER PRIMARY KEY, name TEXT, sex INT)" ; private static final int DB_VERSION = 1 ; public DbOpenHelper (Context context) { super (context, DB_NAME, null , DB_VERSION); } @Override public void onCreate (SQLiteDatabase db) { db.execSQL(CREATE_BOOK_TABLE); db.execSQL(CREATE_USER_TABLE); } @Override public void onUpgrade (SQLiteDatabase db, int oldVersion, int newVersion) { } }
1 2 3 4 Uri uri = Uri.parse("content://com.gacrnd.gcs.ipc.BookProvider" ); getContentResolver().query(uri,null ,null ,null ,null ); getContentResolver().query(uri,null ,null ,null ,null );
2. Socket Socket称为“套接字”,是网络通信中的概念,分为流式套接字和用户数据报套接字两种,分别对应网络传输控制层的TCP和UDP协议。TCP协议是面向连接的协议,提供稳定的双向通信功能,TCP连接的建立需要经过“三次握手”才能完成,为了提供稳定的数据传输功能,其本身提供了超时重传机制,因此具有很高的稳定性。而UDP是无连接的,提供不稳定的单向/双向通信功能,在性能上,UDP协议不需要握手和挥手,效率会更高
2.1 Socket服务端 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 public class TCPServerService extends Service { private boolean mDestory = false ; @Override public IBinder onBind (Intent intent) { return null ; } @Override public void onCreate () { new Thread(new TcpServer()).start(); super .onCreate(); } private class TcpServer implements Runnable { @Override public void run () { ServerSocket serverSocket = null ; try { serverSocket = new ServerSocket(10000 ); } catch (IOException e) { e.printStackTrace(); return ; } while (!mDestory) { try { final Socket client = serverSocket.accept(); new Thread() { @Override public void run () { try { responseClient(client); } catch (IOException e) { e.printStackTrace(); } } }.start(); } catch (IOException e) { e.printStackTrace(); } } } } private void responseClient (Socket client) throws IOException { BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream())); PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(client.getOutputStream()))); while (!mDestory) { String fromClient = in.readLine(); System.out.println("msg from client:" + fromClient); if (fromClient == null ) { break ; } out.println("收到你的消息" ); } in.close(); out.close(); client.close(); } @Override public void onDestroy () { mDestory = true ; super .onDestroy(); } }
2.2 Socket客户端 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 private void connectServerSocket () { PrintWriter pw = null ; BufferedReader br= null ; Socket socket = null ; try { while (!mDestory) { socket = new Socket("localhost" ,10000 ); pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),true ); pw.println("client send msg" ); br = new BufferedReader(new InputStreamReader(socket.getInputStream())); System.out.println("receive from server:" + br.readLine()); } pw.close(); br.close(); socket.close(); } catch (IOException e) { e.printStackTrace(); } }
3. Binder池 由于项目业务逻辑越来越服务,需要和多个AIDL交互,如果一个一个绑定,调用,这样显得比较麻烦,所以就有了Binder池的概念出来。所有要请求服务端都放在Binder池中,客户端通过Binder池拿到自己需要服务的客户端。
3.1 binder池服务端 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 public class BinderPoolService extends Service { private Binder mBinderPool = new BinderPoolImpl(); @Override public IBinder onBind (Intent intent) { return mBinderPool; } } public class BinderPoolImpl extends IBinderPool .Stub { private static final int SECURITY_SERVICE_PROXY = 0 ; private static final int COMPUTE_SERVICE_PROXY = 1 ; public BinderPoolImpl () { super (); } @Override public IBinder queryBinder (int binderCode) throws RemoteException { IBinder binder = null ; switch (binderCode) { case SECURITY_SERVICE_PROXY: break ; case COMPUTE_SERVICE_PROXY: break ; default : break ; } return binder; } }
3.2 Binder池客户端 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 public class BinderPool { private static volatile BinderPool sInstance = null ; private IBinderPool mBinderPool = null ; private CountDownLatch mCountDownLatch; private ServiceConnection mServiceConnection = new BinderPoolServiceConnection(); private IBinder.DeathRecipient mDeathRecipient = new BinderPoolDeathRecipient(); private Context mContext; public BinderPool (Context context) { this .mContext = context.getApplicationContext(); connectBinderPoolService(); } public static BinderPool getInstance (Context context) { if (sInstance == null ) { synchronized (BinderPool.class) { if (sInstance == null ) { sInstance = new BinderPool(context); } } } return sInstance; } private synchronized void connectBinderPoolService () { mCountDownLatch = new CountDownLatch(1 ); Intent intent = new Intent(mContext, BinderPoolService.class); mContext.bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE); try { mCountDownLatch.await(); } catch (InterruptedException e) { e.printStackTrace(); } } public IBinder queryBinder (int binderCode) { IBinder binder = null ; if (mBinderPool != null ) { try { binder = mBinderPool.queryBinder(binderCode); } catch (RemoteException e) { e.printStackTrace(); } } return binder; } private class BinderPoolServiceConnection implements ServiceConnection { @Override public void onServiceConnected (ComponentName name, IBinder service) { mBinderPool = IBinderPool.Stub.asInterface(service); try { mBinderPool.asBinder().linkToDeath(mDeathRecipient, 0 ); } catch (RemoteException e) { e.printStackTrace(); } mCountDownLatch.countDown(); } @Override public void onServiceDisconnected (ComponentName name) { } } private class BinderPoolDeathRecipient implements IBinder .DeathRecipient { @Override public void binderDied () { mBinderPool.asBinder().unlinkToDeath(mDeathRecipient, 0 ); mBinderPool = null ; connectBinderPoolService(); } } }
版权声明: 此文章版权归Jack Ou所有,如有转载,请註明来自原作者