Skip to content

Commit

Permalink
fix: PI-33483 修复多进程访问db导致的崩溃问题 (#66)
Browse files Browse the repository at this point in the history
* fix: PI-33483 修复多线程访问db导致的崩溃问题

* fix:event数据库使用contentProvider

* fix: 优化代码

* fix: 动态设置ContentProvider 中的 Authority

* fix: 修改错误的删除语句
  • Loading branch information
gio-yanruixue authored May 18, 2021
1 parent 549df96 commit d9c0fdb
Show file tree
Hide file tree
Showing 9 changed files with 455 additions and 101 deletions.
4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
buildscript {
ext {
buildConfiguration = [
compileVersion : 29,
compileVersion : 30,
minSdkVersion : 17,
targetSdkVersion : 29,
targetSdkVersion : 30,
sourceCompatibility: JavaVersion.VERSION_1_8,
targetCompatibility: JavaVersion.VERSION_1_8,
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,14 @@ public void onCreate() {
Log.e(TAG, "onCreate: ");
super.onCreate();

//不允许多个进程共享一个 WebView 数据目录
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
String processName = getProcessName();
if (!getPackageName().equals(processName)) {
WebView.setDataDirectorySuffix(processName);
}
}

if (isMainProcess()) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
WebView.setWebContentsDebuggingEnabled(true);
Expand Down
9 changes: 9 additions & 0 deletions growingio-tracker-core/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,13 @@
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />

<application>
<provider
android:name="com.growingio.android.sdk.track.middleware.EventsContentProvider"
android:authorities="${applicationId}.EventsContentProvider"
android:grantUriPermissions="true"
android:exported="false" />
</application>


</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
/*
* Copyright (C) 2020 Beijing Yishu Technology Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.growingio.android.sdk.track.middleware;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import static com.growingio.android.sdk.track.middleware.EventsInfoTable.TABLE_EVENTS;

public class EventsContentProvider extends ContentProvider {

//Uri info
//authority

public static String eventsInfoAuthority;
public static Uri authorityUri;

private static final UriMatcher MATCHER;
private static final String TAG = "EventsContentProvider";
//code
private static final int EVENTS_INFO_CODE = 1;

static {
MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
}

private final Object mLock = new Object();
public EventsSQLiteOpenHelper dbHelper;

@Override
public boolean onCreate() {

eventsInfoAuthority = this.getContext().getPackageName() + ".EventsContentProvider";
authorityUri = Uri.parse("content://" + eventsInfoAuthority);

MATCHER.addURI(eventsInfoAuthority, TABLE_EVENTS, EVENTS_INFO_CODE);

this.dbHelper = new EventsSQLiteOpenHelper(this.getContext(), "growing3.db");
return true;
}

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

try {
synchronized (mLock) {
SQLiteDatabase db = dbHelper.getReadableDatabase();
switch (MATCHER.match(uri)) {
case EVENTS_INFO_CODE:

if ("rawQuery".equals(sortOrder)) {
return db.rawQuery(selection, null);
}
return db.query(TABLE_EVENTS, projection, selection, selectionArgs, null, null, sortOrder);
default:
throw new IllegalArgumentException("UnKnow Uri: " + uri.toString());
}
}
} catch (SQLException e) {
Log.e(TAG, "query error: " + e.getMessage());
return null;
}
}

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

@Nullable
@Override
public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {

SQLiteDatabase db = dbHelper.getWritableDatabase();
switch (MATCHER.match(uri)) {

case EVENTS_INFO_CODE:
long rowId = db.insert(TABLE_EVENTS, null, values);
Uri insertUri = ContentUris.withAppendedId(uri, rowId);
this.getContext().getContentResolver().notifyChange(uri, null);
return insertUri;

default:
throw new IllegalArgumentException("UnKnow Uri:" + uri.toString());
}
}

@Override
public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
int count = 0;
switch (MATCHER.match(uri)) {

case EVENTS_INFO_CODE:
count = db.delete(TABLE_EVENTS, selection, selectionArgs);
return count;

default:
throw new IllegalArgumentException("UnKnow Uri:" + uri.toString());
}
}

@Override
public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
int count = 0;
switch (MATCHER.match(uri)) {

case EVENTS_INFO_CODE:
count = db.update(TABLE_EVENTS, values, selection, selectionArgs);
return count;
default:
throw new IllegalArgumentException("UnKnow Uri:" + uri.toString());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Copyright (C) 2020 Beijing Yishu Technology Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.growingio.android.sdk.track.middleware;

import java.util.Arrays;

public class EventsInfo {

private String mEventType;
private int mPolicy;
private byte[] mData;

public String getEventType() {
return mEventType;
}

public void setEventType(String eventType) {
this.mEventType = eventType;
}

public int getPolicy() {
return mPolicy;
}

public void setPolicy(int policy) {
this.mPolicy = policy;
}

public byte[] getData() {
return mData;
}

public void setData(byte[] data) {
this.mData = data;
}

public EventsInfo(String eventType, int policy, byte[] data) {
this.mEventType = eventType;
this.mPolicy = policy;
this.mData = data;
}

@Override
public String toString() {
return "EventsInfo{" +
"eventType='" + mEventType + '\'' +
", policy=" + mPolicy +
", data=" + Arrays.toString(mData) +
'}';
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* Copyright (C) 2020 Beijing Yishu Technology Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.growingio.android.sdk.track.middleware;

import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;

public class EventsInfoTable {

private static final int DATABASE_VERSION = 1;

public static final String TABLE_EVENTS = "events";
public static final String COLUMN_ID = "_id";
public static final String COLUMN_CREATE_TIME = "_created";
public static final String COLUMN_LAST_MODIFIED = "_modified";
public static final String COLUMN_DATA = "_data";
public static final String COLUMN_EVENT_TYPE = "_event_type";
public static final String COLUMN_POLICY = "_policy";

private EventsInfoTable() { }

public static final String CREATE_TABLE_EVENTS =
"CREATE TABLE IF NOT EXISTS " + TABLE_EVENTS + "(\n"
+ COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT,\n"
+ COLUMN_CREATE_TIME + " INTEGER NOT NULL, \n"
+ COLUMN_LAST_MODIFIED + " INTEGER NOT NULL, \n"
+ COLUMN_DATA + " BLOB NOT NULL, \n"
+ COLUMN_EVENT_TYPE + " TEXT NOT NULL, \n"
+ COLUMN_POLICY + " INTEGER NOT NULL \n"
+ ");";

public static final String DROP_TABLE_EVENTS = "DROP TABLE IF EXISTS " + TABLE_EVENTS + ";";

private static final Uri CONTENT_URI = Uri.withAppendedPath(EventsContentProvider.authorityUri, TABLE_EVENTS);

public static Uri getContentUri() {
return CONTENT_URI;
}

public static ContentValues putValues(EventsInfo info) {
long current = System.currentTimeMillis();
ContentValues contentValues = new ContentValues();
contentValues.put(COLUMN_CREATE_TIME, current);
contentValues.put(COLUMN_LAST_MODIFIED, current);
contentValues.put(COLUMN_DATA, info.getData());
contentValues.put(COLUMN_EVENT_TYPE, info.getEventType());
contentValues.put(COLUMN_POLICY, info.getPolicy());
return contentValues;
}

public static EventsInfo getValues(Cursor cursor) {
String eventType = cursor.getString(cursor.getColumnIndex(COLUMN_EVENT_TYPE));
int policy = cursor.getInt(cursor.getColumnIndex(COLUMN_POLICY));
byte[] data = cursor.getBlob(cursor.getColumnIndex(COLUMN_DATA));
return new EventsInfo(eventType, policy, data);
}

}
Loading

0 comments on commit d9c0fdb

Please sign in to comment.