«

多进程使用Provider代替AIDL

时间:2024-3-2 19:44     作者:韩俊     分类: Android


来百度之后,涉及到了多进程通信的技术。做了相关学习和一些代码工作后,有一些感想想和大家分享下。

虽然使用多进程增加了程序的内存空间,但是也有很多负面的影响。比如:

使用很多第三方lib扩展额外进程功能时容易混乱单例模式在单进程中用的很爽,但在多进程就鸡肋了使用AIDL完成的稳定性和效率并不是很高,本人做的项目拉取AIDL传来的值一直存在不稳定的问题

最后一个问题最蛋疼。项目组老大也说了,限制使用,因为linux系统中,涉及到多进程通信的句柄数量是有限的。

针对最后一个问题,提出了一个折中的方法。使用ContentProvider传递一些简单的基础变量,经测试,确实稳定高效很多。欢迎大家交流。

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"/>

试验了一下,效果还是不错的。

版权声明:本文为博主原创文章,未经博主允许不得转载。

标签: android

热门推荐