UI更新在Android广播服务后失败



我正在尝试使用广播服务将数据同步到服务器。当用户在线时,没有问题,但是当他们从离线(或飞行模式)上网时,不幸的是停止服务,但数据保存到服务器。在 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),因为它可以保证在整个应用程序的生命周期中只有一个数据库助手。

参考博客

最新更新