多进程使用Provider代替AIDL
来源:互联网 发布:工作流程设计软件 编辑:程序博客网 时间:2024/05/15 07:07
来北京实习之后,涉及到了多进程Binder通信的技术。做了相关学习和一些代码工作后,有一些感想和大家分享下。
虽然在App中使用多进程增加了程序的内存空间,但是也有一些负面的影响。比如:
1. 很多情况下,业务需要接入第三方平台,接入的代码有时运行在第三方应用的进程中,容易出错
2. 单例模式在单进程中用的很爽,但在多进程中就显得鸡肋了,也是比较容易疏忽的地方
3. 使用AIDL完成的稳定性和效率并不是很高,本人做的项目拉取AIDL传来的值一直存在不稳定的问题
针对最后一个问题,相信有一定工作经验的Android工程师都遇到过。
我也对此进行了思考,做出了以下几点猜想:
1. AIDL中使用代理Proxy对象进行处理,降低了直接处理的效率
2. AIDL客户端发出请求后,服务器端挂起,有个等待时间
3. AIDL虽然通过内存映射完成数据传输,但也需要一次拷贝,没有共享内存不用拷贝的优势
4. 这也是最重要的一点,在完成Binder通信时Process的构造函数中,申请内存的交换空间的大小是有限的,最大只有1M
在这种情况下,项目组使用ContentProvider传递一些简单的基础变量。经测试,确实稳定高效很多。虽然ContentProvider也是采用的Binder实现的,但是通过ContentProvider通信,相当于重新开辟了一条client和内核交换数据的通道,减少了原来通道传输大量数据的压力。github地址:https://github.com/leirenbaobao/ShareInProvider
此代码的功能就是跨进程获取一个string变量。在代码就是“张三、李四”的人名。
主Activity是两个button和一个TextView,一个赋值(对其他进程的share),一个取值(从其他进程中取),TextView用来显示结果。
主Activity:
public class MainActivity extends ActionBarActivity { private Button mButtonOpen; private Button mButtonTake; private TextView mTextView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mTextView = (TextView) findViewById(R.id.txt); mButtonOpen = (Button)findViewById(R.id.btn_open); mButtonOpen.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { StringResolver.putString(MainActivity.this, "key", "张三"); } }); mButtonTake = (Button)findViewById(R.id.btn_action); mButtonTake.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { mTextView.setText(StringResolver.getString(MainActivity.this, "key", "李四")); } }); }}
Resolver处理类,两个方法。
/** * Created by DAV on 15/6/25. * Contentresovler处理类 */public class StringResolver { private static final int MATCH_RIGHT_NUM = 1; private static final String CONTENT_TYPE = "prefs_detail"; private static final String CONTENT_KEY = "prefs_key"; private static final String CONTENT_VALUE = "prefs_value"; private static final String sAuthority = "com.baidu.www.shareinprovider.url"; private static final String TAG = "StringResolver"; public static void putString(Context cxt, String key, String str){ UriMatcher sMatcher = new UriMatcher(UriMatcher.NO_MATCH); sMatcher.addURI(sAuthority, CONTENT_TYPE, MATCH_RIGHT_NUM); Uri sUri = Uri.parse("content://"+ sAuthority + "/" + CONTENT_VALUE); ContentValues contentValues = new ContentValues(); contentValues.put(CONTENT_KEY, key); contentValues.put(CONTENT_VALUE, str); cxt.getContentResolver().update(sUri, contentValues, null, null); } public static String getString(Context cxt, String key, String defStr){ UriMatcher sMatcher = new UriMatcher(UriMatcher.NO_MATCH); sMatcher.addURI(sAuthority, CONTENT_TYPE, MATCH_RIGHT_NUM); Uri sUri = Uri.parse("content://"+ sAuthority + "/" + CONTENT_VALUE); ContentValues contentValues = new ContentValues(); contentValues.put(CONTENT_KEY, key); contentValues.put(CONTENT_VALUE, defStr); Uri uri = cxt.getContentResolver().insert(sUri, contentValues); Log.v(TAG, uri.toString()); return uri.toString(); }}
核心provider类
/** * Created by DAV on 15/6/25. */public class StringProvider extends ContentProvider{ private static final int MATCH_RIGHT_NUM = 1; private static final String CONTENT_TYPE = "prefs_detail"; private static final String CONTENT_KEY = "prefs_key"; private static final String CONTENT_VALUE = "prefs_value"; private static final String sAuthority = "com.baidu.www.shareinprovider.url"; private static final String TAG = "StringProvider"; private static final UriMatcher sMatcher = new UriMatcher(UriMatcher.NO_MATCH); @Override public boolean onCreate() { sMatcher.addURI(sAuthority, CONTENT_VALUE, MATCH_RIGHT_NUM); return true; } @Override public Cursor query(Uri uri, String[] strings, String s, String[] strings1, String s1) { return null; } @Override public int delete(Uri uri, String s, String[] strings) { return 0; } @Override public String getType(Uri uri) { int code = sMatcher.match(uri); switch (code){ case MATCH_RIGHT_NUM: return sAuthority + "." + CONTENT_TYPE; default: break; } return null; } @Override public Uri insert(Uri uri, ContentValues contentValues) { Log.v(TAG, "come in insert"); int code = sMatcher.match(uri); switch (code){ case MATCH_RIGHT_NUM: Log.v(TAG, "insert"); return getPrefsValue(getContext(), contentValues); default: break; } return null; } @Override public int update(Uri uri, ContentValues contentValues, String s, String[] strings) { int code = sMatcher.match(uri); Log.v(TAG, uri.toString() + code); switch (code){ case MATCH_RIGHT_NUM: Log.v(TAG, "update"); putPrefsValue(getContext(), contentValues); break; default: break; } return 0; } private Uri getPrefsValue(Context cxt, ContentValues values){ String key = values.getAsString(CONTENT_KEY); String defValue = values.getAsString(CONTENT_VALUE); SharedPreferences prefs = cxt.getSharedPreferences("NameShare", Context.MODE_PRIVATE); return Uri.parse(prefs.getString(key, defValue)); } private void putPrefsValue(Context cxt, ContentValues values){ String key = values.getAsString(CONTENT_KEY); String value = values.getAsString(CONTENT_VALUE); SharedPreferences prefs = cxt.getSharedPreferences("NameShare", Context.MODE_PRIVATE); SharedPreferences.Editor editor = prefs.edit(); editor.putString(key, value); editor.commit(); }}
其中provider类在Manifest中注册为另外进程。
<provider android:authorities="com.baidu.www.shareinprovider.url" android:name=".StringProvider" android:exported="true" android:process=":remote"/>
试验了一下,效果还是不错的。
0 0
- 多进程使用Provider代替AIDL
- Aidl多进程通信
- 使用AIDL进程间通信
- 使用AIDL实现进程通信
- 使用AIDL实现进程通信
- AIDL---使用AIDL实现进程间的通信 .
- aidl ( 二) 多进程调试
- android 多进程之 AIDL
- android进程间通信:使用AIDL
- android进程间通信:使用AIDL
- android进程间通信:使用AIDL
- android进程间通信:使用AIDL
- 使用AIDL实现进程间的通信
- android进程间通信:使用AIDL
- android进程间通信:使用AIDL
- **android进程间通信:使用AIDL .**
- android进程间通信:使用AIDL .
- android进程间通信:使用AIDL
- 不要说谢谢
- shell脚本编程常识
- 测试身材胖瘦小程序
- 【Android】如何使用开源库
- Android多线程与异步任务学习笔记(一)
- 多进程使用Provider代替AIDL
- shell字符串的截取
- Java设计模式之——单例模式
- 计算机图形学知识点总结
- Schlumberger Oil Field Manager(OFM) 2012.1-ISO 1CD(油田日常监控和管理软件包)
- 入职互联网公司一个月
- OJ期末模考H
- 机房收费系统——组合查询
- Linux集中日志服务器rsyslog