首页 > 解决方案 > 如何解决此 unregisterReceiver() 错误?

问题描述

我正在尝试将数据从本地数据库发送到服务器中的 Mysql 数据库。数据未发送。我使用测试了我的 php 脚本,Postman并且我的Php代码运行良好。但是,我无法解决以下错误:

代码源 = https://www.simplifiedcoding.net/android-sync-sqlite-database-with-server/

2019-10-09 18:21:30.313 17393-17393/com.example.forgot_password E/ActivityThread: Activity com.example.forgot_password.MainActivity has leaked IntentReceiver com.example.forgot_password.NetworkStateChecker@fdc2b4a that was originally registered here. Are you missing a call to unregisterReceiver()?
android.app.IntentReceiverLeaked: Activity com.example.forgot_password.MainActivity has leaked IntentReceiver com.example.forgot_password.NetworkStateChecker@fdc2b4a that was originally registered here. Are you missing a call to unregisterReceiver()?
    at android.app.LoadedApk$ReceiverDispatcher.<init>(LoadedApk.java:1424)
    at android.app.LoadedApk.getReceiverDispatcher(LoadedApk.java:1201)
    at android.app.ContextImpl.registerReceiverInternal(ContextImpl.java:1476)
    at android.app.ContextImpl.registerReceiver(ContextImpl.java:1449)
    at android.app.ContextImpl.registerReceiver(ContextImpl.java:1437)
    at android.content.ContextWrapper.registerReceiver(ContextWrapper.java:623)
    at com.example.forgot_password.MainActivity.onCreate(MainActivity.java:94)

代码

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

/*
 * this is the url to our webservice
 * make sure you are using the ip instead of localhost
 * it will not work if you are using localhost
 * */
public static final String URL_SAVE_NAME = "http://192.168.26.2/SqliteSync/saveName.php";

//database helper object
private DatabaseHelper db;

//View objects
private Button buttonSave;
private EditText editTextName;
private ListView listViewNames;

//List to store all the names
private List<Name> names;

//1 means data is synced and 0 means data is not synced
public static final int NAME_SYNCED_WITH_SERVER = 1;
public static final int NAME_NOT_SYNCED_WITH_SERVER = 0;

//a broadcast to know weather the data is synced or not
public static final String DATA_SAVED_BROADCAST = "net.simplifiedcoding.datasaved";

//Broadcast receiver to know the sync status
private BroadcastReceiver broadcastReceiver;

//adapterobject for list view
private NameAdapter nameAdapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    //initializing views and objects
    db = new DatabaseHelper(this);
    names = new ArrayList<>();

    buttonSave = (Button) findViewById(R.id.login);
    editTextName = (EditText) findViewById(R.id.email);
    listViewNames = (ListView) findViewById(R.id.listViewNames);

    //adding click listener to button
    buttonSave.setOnClickListener(this);

    //calling the method to load all the stored names
    loadNames();

    //the broadcast receiver to update sync status
    broadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intents) {

            //loading the names again
            loadNames();
        }
    };
    registerReceiver(broadcastReceiver, new IntentFilter(DATA_SAVED_BROADCAST));
    registerReceiver(new NetworkStateChecker(), new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));

}

/*
 * this method will
 * load the names from the database
 * with updated sync status
 * */
private void loadNames() {
    names.clear();
    Cursor cursor = db.getNames();
    if (cursor.moveToFirst()) {
        do {
            Name name = new Name(
                    cursor.getString(cursor.getColumnIndex(DatabaseHelper.Column2)),
                    cursor.getInt(cursor.getColumnIndex(DatabaseHelper.Column3))
            );
            names.add(name);
        } while (cursor.moveToNext());
    }

    nameAdapter = new NameAdapter(this, R.layout.names, names);
    listViewNames.setAdapter(nameAdapter);
}

/*
 * this method will simply refresh the list
 * */
private void refreshList() {
    nameAdapter.notifyDataSetChanged();
}

/*
 * this method is saving the name to ther server
 * */
private void saveNameToServer() {
    final ProgressDialog progressDialog = new ProgressDialog(this);
    progressDialog.setMessage("Saving Name...");
    progressDialog.show();

    final String name = editTextName.getText().toString().trim();

    StringRequest stringRequest = new StringRequest(Request.Method.POST, URL_SAVE_NAME,
            new Response.Listener<String>() {
                @Override
                public void onResponse(String response) {
                    progressDialog.dismiss();
                    try {
                        JSONObject obj = new JSONObject(response);
                        if (!obj.getBoolean("error")) {
                            //if there is a success
                            //storing the name to sqlite with status synced
                            saveNameToLocalStorage(name, NAME_SYNCED_WITH_SERVER);
                        } else {
                            //if there is some error
                            //saving the name to sqlite with status unsynced
                            saveNameToLocalStorage(name, NAME_NOT_SYNCED_WITH_SERVER);
                        }
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
            },
            new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    progressDialog.dismiss();
                    //on error storing the name to sqlite with status unsynced
                    saveNameToLocalStorage(name, NAME_NOT_SYNCED_WITH_SERVER);
                }
            }) {
        @Override
        protected Map<String, String> getParams() throws AuthFailureError {
            Map<String, String> params = new HashMap<>();
            params.put("name", name);
            return params;
        }
    };

    VolleySingleton.getInstance(this).addToRequestQueue(stringRequest);
}

//saving the name to local storage
private void saveNameToLocalStorage(String name, int status) {
    editTextName.setText("");
    db.insert(name, status);
    Name n = new Name(name, status);
    names.add(n);
    refreshList();
}

@Override
public void onClick(View view) {
    saveNameToServer();
}
}

数据无法发送到服务器我收到此错误。

标签: javaandroidsqliteandroid-volley

解决方案


似乎您正在注册您的BroadcastReceiver,但您没有删除它们。

我会做:

//Broadcast receiver to know the sync status
private BroadcastReceiver broadcastReceiver;

//Broadcast receiver for the network state
private NetworkStateChecker networkStateChecker;

protected void onCreate(Bundle savedInstanceState) {
    ...
    broadcastReceiver = new BroadcastReceiver();
    networkStateChecker = new NetworkStateChecker();
}

@Override
protected onStart() {
    super.onStart();
    registerReceiver(broadcastReceiver, new IntentFilter(DATA_SAVED_BROADCAST));
    registerReceiver(networkStateChecker, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
}

@Override
protected onStop() {
    super.onStop();
    unregisterReceiver(broadcastReceiver);
    unregisterReceiver(networkStateChecker);
}

推荐阅读