我正在尝试使用广播服务将数据同步到服务器。当用户在线时,没有问题,但是当他们从离线(或飞行模式)上网时,不幸的是停止服务,但数据保存到服务器。在 recycleradapter.java 我正在从秒表上更新图像到成功的图像不起作用
@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
我称之为广播服务的接种方法。和两个方法onstart()和onpause()。
public class MainActivity extends AppCompatActivity {
RecyclerView recyclerView;
EditText Name;
RecyclerView.LayoutManager layoutManager;
RecyclerAdapter adapter;
ArrayList<Contact> arrayList = new ArrayList<>();
BroadcastReceiver broadcastReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main1);
recyclerView=(RecyclerView)findViewById(R.id.recyclerView);
Name=(EditText) findViewById(R.id.name);
layoutManager =new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setHasFixedSize(true);
adapter = new RecyclerAdapter(arrayList);
recyclerView.setAdapter(adapter);
readFromLocalStorage();
broadcastReceiver=new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
readFromLocalStorage();
}
};
}
public void submitName(View view){
String name = Name.getText().toString();
saveToAppServer(name);
Name.setText("");
}
private void readFromLocalStorage() {
arrayList.clear();
DbHelper dbHelper = new DbHelper(this);
SQLiteDatabase database = dbHelper.getReadableDatabase();
Cursor cursor = dbHelper.readFromLocalDatabase(database);
//String[] columns = {DbContact.NAME, DbContact.SYNC_STATUS};
// Cursor cursor = database.query(DbContact.TABLE_NAME,
// columns,
// null,
// null, null, null, null);
while (cursor.moveToNext()){
String name = cursor.getString(cursor.getColumnIndex(DbContact.NAME));
int sync_status=cursor.getInt(cursor.getColumnIndex(DbContact.SYNC_STATUS));
arrayList.add(new Contact(name,sync_status));
}
adapter.notifyDataSetChanged();
cursor.close();
dbHelper.close();
}
private void saveToAppServer(final String name){
if(checkNetworkConnection()){
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")){
saveToLocalStorage(name,DbContact.SYNC_STATUS_OK);
}
else{
saveToLocalStorage(name,DbContact.SYNC_STATUS_FAILED);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
saveToLocalStorage(name,DbContact.SYNC_STATUS_FAILED);
}
})
{
@Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params= new HashMap<>();
params.put("name", name);
return params;
}
} ;
VolleySingleton.getInstance(MainActivity.this).addToRequestQueue(stringRequest);
}
else{
saveToLocalStorage(name,DbContact.SYNC_STATUS_FAILED);
}
}
public boolean checkNetworkConnection(){
ConnectivityManager connectivityManager =(ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo=connectivityManager.getActiveNetworkInfo();
return (networkInfo!= null && networkInfo.isConnected());
}
private void saveToLocalStorage(String name, int sync){
DbHelper dbHelper = new DbHelper(this);
SQLiteDatabase database = dbHelper.getWritableDatabase();
dbHelper.saveToLocalDatabase(name, sync, database);
readFromLocalStorage();
dbHelper.close();
}
@Override
protected void onStart() {
super.onStart();
registerReceiver(broadcastReceiver, new IntentFilter(DbContact.UI_UPDATE_BROADCAST));
}
@Override
protected void onPause() {
super.onPause();
unregisterReceiver(broadcastReceiver);
}
}
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.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());
}
}
logcat错误:
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)
这可能是 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
对象尚未初始化。
使用新的DatabaseHelper(context)
初始化助手对象!取而代之的是,始终使用DatabaseHelper.getInstance(context)
,因为它可以保证在整个应用程序的生命周期中只有一个数据库助手。
参考博客