显示internet连接上的Android Sqlite数据库同步中的错误

显示internet连接上的Android Sqlite数据库同步中的错误,android,android-sqlite,Android,Android Sqlite,我正在开发一个android应用程序,我需要将本地SQLite数据库同步到互联网上的MySql数据库。 步骤1:当应用程序与internet连接运行时,数据将发送到real server。 步骤2:当应用程序在没有连接互联网的情况下运行时,数据将存储在本地sqlite数据库中。当应用程序连接到互联网时,存储的数据将同步到real server数据库 在我的应用程序中,第1步工作正常。但当数据试图同步时,应用程序正在崩溃 我在下面提供了我的错误日志和类 [ERROR] FATAL EXCEPTIO

我正在开发一个android应用程序,我需要将本地SQLite数据库同步到互联网上的MySql数据库。 步骤1:当应用程序与internet连接运行时,数据将发送到real server。 步骤2:当应用程序在没有连接互联网的情况下运行时,数据将存储在本地sqlite数据库中。当应用程序连接到互联网时,存储的数据将同步到real server数据库

在我的应用程序中,第1步工作正常。但当数据试图同步时,应用程序正在崩溃

我在下面提供了我的错误日志和类

[ERROR] FATAL EXCEPTION: main Process: com.w3xplorers.syncdb, PID: 3357
                                                                 java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase: /data/data/com.w3xplorers.syncdb/databases/sqlite_db
                                                                     at android.database.sqlite.SQLiteClosable.acquireReference(SQLiteClosable.java:55)
                                                                     at android.database.sqlite.SQLiteDatabase.updateWithOnConflict(SQLiteDatabase.java:1545)
                                                                     at android.database.sqlite.SQLiteDatabase.update(SQLiteDatabase.java:1522)
                                                                     at com.w3xplorers.syncdb.DBHelper.updateDatabase(DBHelper.java:52)
                                                                     at com.w3xplorers.syncdb.NetworkMonitor$1.onResponse(NetworkMonitor.java:48)
                                                                     at com.w3xplorers.syncdb.NetworkMonitor$1.onResponse(NetworkMonitor.java:41)
                                                                     at com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:60)
                                                                     at com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:30)
                                                                     at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:99)
                                                                     at android.os.Handler.handleCallback(Handler.java:739)
                                                                     at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                     at android.os.Looper.loop(Looper.java:135)
                                                                     at android.app.ActivityThread.main(ActivityThread.java:5254)
                                                                     at java.lang.reflect.Method.invoke(Native Method)
                                                                     at java.lang.reflect.Method.invoke(Method.java:372)
                                                                     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
                                                                     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
Dbhelper类:

public class DBHelper extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 1;
private static final String CREATE_TABLE = "create table " + DBContact.TABLE_NAME+
        " (id integer primary key autoincrement,"+DBContact.NAME+" text,"+DBContact.STATUS+" integer);";
private static final String DROP_TABLE = "drop table if exists "+DBContact.TABLE_NAME;

public DBHelper(Context context) {
    super(context, DBContact.DATABASE_NAME, null, DATABASE_VERSION);
}

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

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    db.execSQL(DROP_TABLE);
    onCreate(db);
}

public void saveToLocalDatabase(String name,int sync_status,SQLiteDatabase database){
    ContentValues contentValues = new ContentValues();
    contentValues.put(DBContact.NAME,name);
    contentValues.put(DBContact.STATUS,sync_status);
    database.insert(DBContact.TABLE_NAME,null,contentValues);

}

public Cursor readFromLocalDb(SQLiteDatabase database){
    String[] projections = {DBContact.NAME,DBContact.STATUS};
    return (database.query(DBContact.TABLE_NAME,projections,null,null,null,null,null));
}

public void updateDatabase(String name,int sync_status,SQLiteDatabase database){
    ContentValues contentValues = new ContentValues();
    contentValues.put(DBContact.STATUS,sync_status);
    String selection = DBContact.NAME+" Like ?";
    String[] selection_args = {name};
    database.update(DBContact.TABLE_NAME,contentValues,selection,selection_args);
}
}
NetworkMonitor.java

public class NetworkMonitor extends BroadcastReceiver {
@Override
public void onReceive(final Context context, Intent intent) {
    if(checkNetworkConnection(context)){
        final DBHelper dbHelper = new DBHelper(context);
        final SQLiteDatabase database = dbHelper.getWritableDatabase();
        Cursor cursor = dbHelper.readFromLocalDb(database);

        while (cursor.moveToNext()){

            int sync_status = cursor.getInt(cursor.getColumnIndex(DBContact.STATUS));
            if(sync_status==DBContact.sync_status_failed){
                final String name = cursor.getString(cursor.getColumnIndex(DBContact.NAME));
                StringRequest stringRequest= new StringRequest(Request.Method.POST, DBContact.SERVER_URL,
                        new Response.Listener<String>() {
                            @Override
                            public void onResponse(String s) {
                                try {
                                    JSONObject jsonObject = new JSONObject(s);
                                    String Response = jsonObject.getString("response");
                                    if(Response.equals("OK")){
                                        dbHelper.updateDatabase(name,DBContact.sync_status_ok,database);
                                        context.sendBroadcast(new Intent(DBContact.UI_UPDATE_BROADCAST));
                                    }
                                } catch (JSONException e) {
                                    e.printStackTrace();
                                }

                            }
                        }, new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError volleyError) {

                    }
                })
                {
                    @Override
                    protected Map<String, String> getParams() throws AuthFailureError {
                        Map<String ,String> params = new HashMap<>();
                        params.put("name",name);
                        return params;
                    }
                };

                MySingleton.getInstance(context).addToRequestQueue(stringRequest);
            }
        }

        dbHelper.close();
    }
}

public boolean checkNetworkConnection(Context context){
    ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
    return (networkInfo!=null && networkInfo.isConnected());
}
}
公共类网络监视器扩展广播接收器{
@凌驾
公共void onReceive(最终上下文、意图){
if(检查网络连接(上下文)){
final DBHelper DBHelper=新的DBHelper(上下文);
最终SQLiteDatabase=dbHelper.getWritableDatabase();
Cursor Cursor=dbHelper.readFromLocalDb(数据库);
while(cursor.moveToNext()){
int sync_status=cursor.getInt(cursor.getColumnIndex(DBContact.status));
if(sync_status==DBContact.sync_status_失败){
最终字符串名称=cursor.getString(cursor.getColumnIndex(DBContact.name));
StringRequest StringRequest=新的StringRequest(Request.Method.POST、DBContact.SERVER\u URL、,
新的Response.Listener(){
@凌驾
公共void onResponse(字符串s){
试一试{
JSONObject JSONObject=新的JSONObject;
字符串响应=jsonObject.getString(“响应”);
如果(响应等于(“确定”)){
dbHelper.updateDatabase(名称,DBContact.sync\u status\u ok,数据库);
sendBroadcast(新意图(DBContact.UI_UPDATE_BROADCAST));
}
}捕获(JSONException e){
e、 printStackTrace();
}
}
},new Response.ErrorListener(){
@凌驾
公共错误响应(截击错误截击错误){
}
})
{
@凌驾
受保护的映射getParams()引发AuthFailureError{
Map params=新的HashMap();
参数put(“名称”,名称);
返回参数;
}
};
getInstance(上下文).addToRequestQueue(stringRequest);
}
}
dbHelper.close();
}
}
公共布尔值checkNetworkConnection(上下文){
ConnectivityManager ConnectivityManager=(ConnectivityManager)context.getSystemService(context.CONNECTIVITY_服务);
NetworkInfo NetworkInfo=connectivityManager.getActiveNetworkInfo();
return(networkInfo!=null&&networkInfo.isConnected());
}
}

我认为问题出在onReceive结束语句中的网络监视器类中 你正在关闭数据库吗

dbHelper.close();
但是在onResponseu中访问相同的dbHelper,因此必须删除dbHelper.close()并在onResponse中关闭它


最好在DBHelper类函数中创建SQLiteDatabase实例,以便使用它来避免此类问题

(DBHelper.java:52)database.update(DBContact.TABLE_NAME、contentValues、selection、selection_args);(NetworkMonitor.java:48)dbHelper.updateDatabase(名称,DBContact.sync\u status\u ok,数据库);您现在遇到了什么问题?在调用dbHelper.updateDatabase创建新的dbHelper对象并检查它是否正常工作之前,请做一件事。但是dbHelper对象有什么问题吗?想建议您为什么不在SqlitHelper类中创建SQLiteDatabase实例,这将是更好的创建方法,在您的情况下,SQLiteDatabase对象可能在第一次操作后关闭,因此您必须调用dbHelper.getWritableDatabase();