SpartanJ / restafari

restafari is an android library mostly oriented to facilitate REST API calls to a server and storing the server API response to a local SQLite database.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

can't deliver broadcast issue

hrodrick opened this issue · comments

We are facing an issue when we make a request right after (and before) an activity is closed that causes the application to crash with the next exception:

Exception :
E/AndroidRuntime: FATAL EXCEPTION: main
    Process: infosis.billapp.gastronomy, PID: 24386
    android.app.RemoteServiceException: can't deliver broadcast
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1840)
        at android.os.Handler.dispatchMessage(Handler.java:108)
        at android.os.Looper.loop(Looper.java:206)
        at android.app.ActivityThread.main(ActivityThread.java:6735)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:845)

While debugging we reach out that the problem happens instantly after the next line :

Class : RequestResponseProcessor
Method : broadcastRequestResponse
	línea 260 : context.sendBroadcast( resultBroadcast );

The context used to Initialize the RequestService is our App.class that extends Application.

The problem happens in an tablet EXXO wave_i101G with Android 8.0, and in an EXXO wav_i101H with android 8.1. It doesn't happen on Android 6.0 and lower versions, we have not tested on Android 7 or 7.1.

What we do is the next.
Activity A calls Activity B for a result. When the activity B finish his work, the A's onActivityResult is called. In the process we make some logic and after that we start a service to synchronize the data between the App and an external API.

The service is started through a context that is the Activity A and prepares an AsynchronousRequestContent with a RequestConfiguration that haves a request, a response, and a DTO for the response.
The request's response is processed succesfully in our custom ResponseProcessor implementation.
The problem happens right after that, when trying to deliver a broadcast with the response data.

we don't know why the application crashes here and not in the whole app (we use the same mechanism everywhere), the unique difference we see with the rest of the application is that the activity B is beign closed (and destroyed) when the request/response is in process.

While searching why that happens we reach various articles on the web and StackOverflow that indicates the "correct way" of sending broadcasts in-app :

//Register receivers
LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,
          new IntentFilter("custom-event-name"));

//Send the broadcasts
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);

Also, that the problem may occur because the broadcast is sent to a receiver that is beign destroyed (¿activity B?)

I have tryed to extends the RequestResponseProcessor to change this behaviour but it becomes impossible because it is initialized in the RequestService that has a private constructor and is a singleton class. Replacing that class is neither possible because the getInstance method is called inside other classes of the framework that performs different kinds of tasks, and replace everything is not a choice.

PD :
we don't have broadcast receivers in the app.

Framework version used : 0.3.21

As far as I read this looks like a bug, so let's try the fix everyone mentions (switching to LocalBroadcastManager). I released version 0.4.1, you should try that version and let me know if that fixes your problem.
I've made some other changes that will help you in your situation as al alternative solution:
The simple requests, the ones starting with make in RequestService will send any broadcasts, so you can use that requests for this special cases ( RequestService.getInstance().makeJsonRequest ).
RequestService.init now accepts an instance of RequestResponseProcessor, this means that it will use the RequestResponseProcessor you provide to the library, so you can extend it.
Regards

The changes fixed the issue! Thanks for the fast response.
Regards.