ContentProviderを使用すると、マルチスレッドappの値が一致しません.

4108 ワード

安卓の中で4大コンポーネントの1つContentProviderプロセスが一致しないで、そこで私は自分のこちらのロジックを直して、データを取って変えて私のみんなを通じてきっとよく知らないで、私は最近自分のモジュールを最適化する時1つのBUGが発生して、私はProviderデータのappを提供して、しかしその彼は私のデータのappを取りに来て私の保存した値と違います.
その後、私はSharedPreferences+ContentProviderでデータを保存して各アプリに提供したので、私のメインプログラムコードとProviderは1つのプロセスの下にあったが、私のProviderを調整するアプリが多すぎて、私のプログラムがバックグラウンドで退出してもメモリを消費して殺すことができないことを発見し、Providerを別のプロセスから独立させ、メインプロセスはメモリを解放することができた.しかし、以上の問題を引き起こした.
多くの文章を調べた結果、SharedPreferencesはマルチスレッドの下で確かにデータが一致しないため、大物の答えを見て啓発されたのではないかと推敲された.私は以前データを取るのはすべて直接自分のディレクトリの下でSharedPreferencesの中から取ったので、そのプロセスは私のメインプログラムのプロセスで、他のAPPのデータを提供するProviderのプロセスと一致していません.そこで私は自分の論理を変えて、データを取って変更して私のProviderを通じて操作して、やっとこの問題を解決しました.
public static UserInfoBean getLoginedUserInfo () {

    UserInfoBean userInfo = null;

    ContentResolver cr = UcApp.sCtx.getContentResolver();
    Cursor cursor = cr.query(Const.URI.USER_INFO,
            null, null, null, null);

    if ( null == cursor ) {
        LogUtils.w("getLoginedUserInfo cursor == null");
        return userInfo;
    }

    Bundle bundle = cursor.getExtras();

    boolean isLogined = bundle.getBoolean(Const.SpUser.Key.IS_LOGINED, false);
    if ( ! isLogined ) {
        LogUtils.w("getLoginedUserInfo isLogined = false");
        return userInfo;
    }

    userInfo = new UserInfoBean();
    userInfo.isLogined = true;
    userInfo.username = bundle.getString(Const.SpUser.Key.USERNAME, "");
    userInfo.token = bundle.getString(Const.SpUser.Key.TOKEN, "");

    cursor.close();

    LogUtils.w(userInfo.toString());

    return userInfo;
}

        public static void saveLoginedUserInfo (UserInfoBean userInfo, boolean isSaveToken) {

    if ( null == userInfo ) {
        return;
    }

    ContentResolver cr = UcApp.sCtx.getContentResolver();
    ContentValues values = new ContentValues();

    values.put(Const.SpUser.Key.IS_LOGINED, true);
    values.put(Const.SpUser.Key.USERNAME, userInfo.username);
    values.put(Const.SpUser.Key.TOKEN, userInfo.token);

    userInfo.usernameEncode = ComUtils.URLEncoder(userInfo.username);
    values.put(Const.SpUser.Key.USERNAME_ENCODE, userInfo.usernameEncode);

    cr.update(Const.URI.USER_INFO, values, null, null);
}

        @Override
public Cursor query (Uri uri, String[] projection, String selection, String[] selectionArgs,
                     String sortOrder) {

    Cursor cursor = new MatrixCursor(new String[]{});
    Bundle bundle = new Bundle();

        UserInfoBean userInfo = getLoginedUserInfo();

        if ( null != userInfo ) {
            bundle.putBoolean(Const.SpUser.Key.IS_LOGINED, true);
            bundle.putString(Const.SpUser.Key.USERNAME, userInfo.username);
            bundle.putString(Const.SpUser.Key.TOKEN, userInfo.token);
        } else {
            bundle.putBoolean(Const.SpUser.Key.IS_LOGINED, false);
        }
    }

    LogUtils.w(bundle.toString());

    return cursor;
}

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

    if ( null == values ) {
        return 0;
    }

    LogUtils.w(values.toString());

    SpUtils spUtils = new SpUtils(Const.SpUser.NAME);
    Set keys = values.keySet();
    for ( String key : keys ) {
        Object obj = values.get(key);
        if ( null != obj ) {
            spUtils.add(key, obj);
        }
    }
    spUtils.apply();

    notifyChangeUserInfo();

    return 1;
}

private UserInfoBean getLoginedUserInfo () {

    UserInfoBean userInfo = null;
    SpUtils spUtils = new SpUtils(Const.SpUser.NAME);

    boolean isLogined = (boolean) spUtils.get(Const.SpUser.Key.IS_LOGINED, false);
    if ( ! isLogined ) {
        LogUtils.w("isLogined = false");
        return userInfo;
    }

    userInfo = new UserInfoBean();
    userInfo.isLogined = true;
    userInfo.username = (String) spUtils.get(Const.SpUser.Key.USERNAME, "");
    userInfo.token = (String) spUtils.get(Const.SpUser.Key.TOKEN, "");

    return userInfo;
}

転載先:https://blog.51cto.com/14311106/2387802