您的位置:首页 > 移动开发 > Android开发

Android AIDL跨进程通信

2016-07-21 17:48 375 查看
ContentProvider 跨进程通信,什么叫跨进程通信通俗点也就是从一个应用中去访问另一个应用的数据。

1.现在有两个引用A,B,将A作为服务端,B作为客户端

2.服务端A的代码如下:

2.1 首先创建一个数据库(SQLite),存储我们的数据

/**
* Created by yyf on 2016/7/21.
*/
public class DatabaseManager {
private static DatabaseManager instance;
private static SqliteManager manager;

public static DatabaseManager getInstance(Context context) {
if (manager == null) {
manager = new SqliteManager(context.getApplicationContext());
}
if (instance==null){
instance=new DatabaseManager();
}
return instance;
}

/****
* 查询
* @param table 表名
* @param columns  要查询的字段名称
* @param selection  查询条件
* @param selectionArgs   查询条件的值
* @param groupBy  分组
* @param having  过滤
* @param orderBy  排序
* @return
*/
public Cursor query(String table, String[] columns, String selection, String[] selectionArgs
, String groupBy, String having, String orderBy) {
SQLiteDatabase sb = getDatabase();
Cursor cursor = sb.query(table, columns, selection, selectionArgs, groupBy, having, orderBy);
return cursor;
}

/**
* 插入
* @param table   表名
* @param nullColumnHack 当values参数为空或者里面没有内容的时候,我们insert是会失败的(底层数据库不允许插入一个空行)
* @param values  字段-value
* @return
*/
public int insert(String table, String nullColumnHack, ContentValues values) {
SQLiteDatabase sb = getDatabase();
long result = sb.insert(table, nullColumnHack, values);
Log.d("insert",result+"插入成功");
return (int) result;
}

private SQLiteDatabase getDatabase() {
return manager.getWritableDatabase();
}


/**
* Created by yyf on 2016/7/21.
*/
public class SqliteManager extends SQLiteOpenHelper {
private final static String DATABASE_NAME="test";
private final static int VERSION=1;

public SqliteManager(Context context) {
super(context, DATABASE_NAME, null, VERSION);
}

String sql_user="CREATE TABLE IF NOT EXISTS  User (uid INTEGER PRIMARY KEY AUTOINCREMENT,uname TEXT)";

@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(sql_user);
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if (newVersion>oldVersion){
db.execSQL(sql_user);
}
}


2.2 继承ContentProvider

/**
* Created by yyf on 2016/7/21.
*/
public class TestProvider extends ContentProvider {
private static UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
private final static String authority = "com.yyf.test";
private DatabaseManager manager;

static {
matcher.addURI(authority, "user", 0);
}

@Override
public boolean onCreate() {
manager = DatabaseManager.getInstance(getContext());
return false;
}

@Nullable
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
Log.d("query", "query-------->");
String table=getTableName(uri);
if (table!=null){
return manager.query(table,projection,selection,selectionArgs,null,null,sortOrder);
}
return null;
}

private String getTableName(Uri uri) {
int code = matcher.match(uri);
switch (code) {
case 0:
return "User";
default:
return null;
}
}

@Nullable
@Override
public String getType(Uri uri) {
return null;
}

@Nullable
@Override
public Uri insert(Uri uri, ContentValues values) {
Log.d("query", "query-------->");
String table=getTableName(uri);
if (table!=null){
manager.insert(table,null,values);
}
return null;
}

@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
return 0;
}

@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
return 0;
}


2.3 在Manifest.xml中配置

<provider
android:authorities="com.yyf.test"
android:name=".provider.TestProvider"
android:permission="com.yyf.test"
android:multiprocess="true"
android:exported="true"/>


2.4 向系统申请我们的自定义权限

<permission android:name="com.yyf.test"
android:protectionLevel="normal"/>


3.客户端B的代码如下

public class MainActivity extends AppCompatActivity {
private ContentResolver resolver;
private Uri userUri;

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

private void initView() {
resolver=getContentResolver();
userUri=Uri.parse("content://com.yyf.test/user");
ContentValues userValues1 = new ContentValues();
userValues1.put("uname", "yyf");
resolver.insert(userUri,userValues1);
}


3.2 在配置文件中配置我们申请的全向

<uses-permission android:name="com.yyf.test"/>


4.此时运行我们的服务端A,然后运行客户端B 将打印

com.my.test.mytestdemo D/insert: 5插入成功

5.注意在配置文件中的ContentProvider标签中使用

android:permission="com.yyf.test"

一定要在Application同级标签声明
<permission android:name="com.yyf.test"
android:protectionLevel="normal"/>


5.1 android:protectionLevel=["normal"
| "dangerous" | "signature" | "signatureOrSystem"]
/>

normal,
dangerous, signature, signatureOrSystem ,取决于保护级别,在确定是否授予权限时,系统可能采取不同的操作。

normal 表示权限是低风险的,不会对系统、用户或其他应用程序造成危害;

dangerous 表示权限是高风险的,系统将可能要求用户输入相关信息,才会授予此权限;

signature 表示只有当应用程序所用数字签名与声明引权限的应用程序所用数字签名相同时,才能将权限授给它;

signatureOrSystem 表示将权限授给具有相同数字签名的应用程序或android 包类。这一保护级别适和于非常特殊的情况,比如多个供应商需要通过系统映像共享功能时

5.2

android:exported="true"  true表示可以被外部应用访问
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: