android中广播服务后UI更新失败
我正在尝试使用广播服务将数据同步到服务器。当用户在线时,并没有问题,但当他们从离线(或飞行模式)在线时,服务会意外停止,但数据会保存到服务器。 在RecyclerAdapter.java中我正在从秒表更新图像,以确保其成功。它不起作用android中广播服务后UI更新失败,android,Android,我正在尝试使用广播服务将数据同步到服务器。当用户在线时,并没有问题,但当他们从离线(或飞行模式)在线时,服务会意外停止,但数据会保存到服务器。 在RecyclerAdapter.java中我正在从秒表更新图像,以确保其成功。它不起作用 @Override public void onBindViewHolder(MyViewHolder holder, int position) { holder.Name.setText(arrayList.get(position).getName
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.Name.setText(arrayList.get(position).getName());
int sync_status = arrayList.get(position).getSync_status();
if(sync_status==DbContact.SYNC_STATUS_OK){
holder.Sync_Status.setImageResource(R.drawable.success);
}else {
holder.Sync_Status.setImageResource(R.drawable.stopwatch);
}
}
这是我的MainActivity.java
我调用广播服务的onReceive方法。还有两个方法onStart()和onPause()
这可能是多次实例化DbHelper
类的原因。确保只实例化一次DbHelper类。以下是克服此问题的可能方法示例,
将DbHelper类作为一个单例进行管理-
public class DatabaseHelper extends SQLiteOpenHelper {
private static DatabaseHelper sInstance;
private SQLiteDatabase jewlotDB;
private static String DB_PATH = "";
private static final String DB_NAME = "my_db.db";
private static final String DATABASE_NAME = "database_name";
private static final String DATABASE_TABLE = "table_name";
private static final int DATABASE_VERSION = 1;
public static synchronized DatabaseHelper getInstance(Context context) {
// Use the application context, which will ensure that you
// don't accidentally leak an Activity's context.
if (sInstance == null) {
sInstance = new DatabaseHelper(context.getApplicationContext());
}
return sInstance;
}
/**
* Constructor should be private to prevent direct instantiation.
* make call to static method "getInstance()" instead.
*/
private DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
// your stuffs
}
@Override
public void onCreate(SQLiteDatabase db) {
// do your creating stuffs here
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
public void openDataBase() throws SQLException {
// open the database...
try {
String myPath = DB_PATH + DB_NAME;
jewlotDB = SQLiteDatabase.openDatabase(myPath, null,
SQLiteDatabase.OPEN_READWRITE);
} catch (Exception e) {
e.printStackTrace();
}
}
// check the state of db ??....
public boolean isOpen() {
return jewlotDB != null && jewlotDB.isOpen();
}
@Override
public synchronized void close() {
if (jewlotDB != null)
jewlotDB.close();
super.close();
}
public void updateLocalDatabase(String name, int sync_status) {
if (!isOpen()) openDataBase();
SQLiteDatabase database = this.getReadableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(DbContact.SYNC_STATUS, sync_status);
String selection = DbContact.NAME + " LIKE ?";
String[] selection_args = {name};
database.update(DbContact.TABLE_NAME, contentValues, selection, selection_args);
database.close();
}
}
静态的getInstance()
方法确保在任何给定时间只有一个DatabaseHelper
。如果sInstance
对象尚未初始化。您不应该使用with new
DatabaseHelper(context)
初始化助手对象!相反,请始终使用DatabaseHelper.getInstance(context)
,因为它保证在整个应用程序的生命周期中只存在一个数据库帮助程序。
您的活动是否在前台可用?是的,它在前台。您的错误日志是什么?您是否尝试调试代码?编辑代码,请检查错误登录我正在尝试调试代码。在NetWorkMonitor中,而不是在final DbHelper DbHelper=new DbHelper(上下文);final DbHelper DbHelper=new DbHelper.getInstance(上下文);显示error@Priya,Replace
DbHelper DbHelper=newdbhelper(上下文)在整个应用程序中使用DatabaseHelper.getInstance(context)
进行编码,并让我知道会发生什么,因为这是处理DatabaseHelper类public void updateLocalDatabase(字符串名称,int sync_状态,SQLiteDatabase数据库){ContentValues ContentValues=new ContentValues();ContentValues.put的良好实践(DbContact.SYNC_STATUS,SYNC_STATUS);String selection=DbContact.NAME+“LIKE?”;String[]selection_args={NAME};database.update(DbContact.TABLE_NAME,contentValues,selection,selection_args);}在UpdateToLocalDatabase上好的,编辑了我的代码。正如您可以看到的更新的updateLocalDatabase
方法-我们不获取数据库作为参数,而是在我们的方法中打开一个关闭的数据库
。如果您想将它们添加到DatabaseHelper
中,还有两个方法。请深入挖掘,我确定你会明白的。原因是dbHelper.close();
语句,它是在onReceive方法中编写的。onResponse
将在关闭数据库后被调用。当你调用dbHelper.updateLocalDatabase(Name,DbContact.SYNC\u STATUS\u OK,database)时
在onResponse
中。因此,在执行该行之前,数据库将关闭。无论如何..如果答案有用,您可以向上投票并将其作为正确答案接受。顺便说一句,欢迎您。
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.readFromLocalDatabase(database);
while (cursor.moveToNext()){
int sync_status = cursor.getInt(cursor.getColumnIndex(DbContact.SYNC_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 response) {
try {
JSONObject jsonObject = new JSONObject(response);
String Response = jsonObject.getString("response");
if(Response.equals("OK")){
dbHelper.updateLocalDatabase(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 error) {
}
})
{
@Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String,String> params = new HashMap<>();
params.put("name",Name);
return params;
}
} ;
VolleySingleton.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());
}
}
at android.database.sqlite.SQLiteClosable.acquireReference(SQLiteClosable.java:55)
at android.database.sqlite.SQLiteDatabase.updateWithOnConflict(SQLiteDatabase.java:1662)
at android.database.sqlite.SQLiteDatabase.update(SQLiteDatabase.java:1639)
at net.simplifiedcoding.androidmysqlsync.oneMore.DbHelper.updateLocalDatabase(DbHelper.java:85)
at net.simplifiedcoding.androidmysqlsync.oneMore.NetworkMonitor$1.onResponse(NetworkMonitor.java:51)
at net.simplifiedcoding.androidmysqlsync.oneMore.NetworkMonitor$1.onResponse(NetworkMonitor.java:43)
at com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:60)
at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:99)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5584)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1268)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1084)
at dalvik.system.NativeStart.main(Native Method)
public class DatabaseHelper extends SQLiteOpenHelper {
private static DatabaseHelper sInstance;
private SQLiteDatabase jewlotDB;
private static String DB_PATH = "";
private static final String DB_NAME = "my_db.db";
private static final String DATABASE_NAME = "database_name";
private static final String DATABASE_TABLE = "table_name";
private static final int DATABASE_VERSION = 1;
public static synchronized DatabaseHelper getInstance(Context context) {
// Use the application context, which will ensure that you
// don't accidentally leak an Activity's context.
if (sInstance == null) {
sInstance = new DatabaseHelper(context.getApplicationContext());
}
return sInstance;
}
/**
* Constructor should be private to prevent direct instantiation.
* make call to static method "getInstance()" instead.
*/
private DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
// your stuffs
}
@Override
public void onCreate(SQLiteDatabase db) {
// do your creating stuffs here
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
public void openDataBase() throws SQLException {
// open the database...
try {
String myPath = DB_PATH + DB_NAME;
jewlotDB = SQLiteDatabase.openDatabase(myPath, null,
SQLiteDatabase.OPEN_READWRITE);
} catch (Exception e) {
e.printStackTrace();
}
}
// check the state of db ??....
public boolean isOpen() {
return jewlotDB != null && jewlotDB.isOpen();
}
@Override
public synchronized void close() {
if (jewlotDB != null)
jewlotDB.close();
super.close();
}
public void updateLocalDatabase(String name, int sync_status) {
if (!isOpen()) openDataBase();
SQLiteDatabase database = this.getReadableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(DbContact.SYNC_STATUS, sync_status);
String selection = DbContact.NAME + " LIKE ?";
String[] selection_args = {name};
database.update(DbContact.TABLE_NAME, contentValues, selection, selection_args);
database.close();
}
}