|
43 | 43 |
|
44 | 44 | import com.onesignal.AndroidSupportV4Compat.ContextCompat;
|
45 | 45 |
|
| 46 | +import java.util.concurrent.ArrayBlockingQueue; |
| 47 | +import java.util.concurrent.BlockingQueue; |
| 48 | + |
46 | 49 | /**
|
47 | 50 | This schedules a job to fire later in the background preform player REST calls to make a(n);
|
48 | 51 | - on_focus
|
@@ -209,25 +212,40 @@ public final void run() {
|
209 | 212 | OneSignal.appId = OneSignal.getSavedAppId();
|
210 | 213 | OneSignalStateSynchronizer.initUserState();
|
211 | 214 |
|
212 |
| - LocationGMS.LocationHandler locationHandler = new LocationGMS.LocationHandler() { |
213 |
| - @Override |
214 |
| - public LocationGMS.CALLBACK_TYPE getType() { |
215 |
| - return LocationGMS.CALLBACK_TYPE.SYNC_SERVICE; |
216 |
| - } |
217 |
| - |
218 |
| - @Override |
219 |
| - public void complete(LocationGMS.LocationPoint point) { |
220 |
| - if (point != null) |
221 |
| - OneSignalStateSynchronizer.updateLocation(point); |
222 |
| - |
223 |
| - // Both these calls are synchronous. |
224 |
| - // Thread is blocked until network calls are made or their retry limits are reached |
225 |
| - OneSignalStateSynchronizer.syncUserState(true); |
226 |
| - FocusTimeController.getInstance().doBlockingBackgroundSyncOfUnsentTime(); |
227 |
| - stopSync(); |
228 |
| - } |
229 |
| - }; |
230 |
| - LocationGMS.getLocation(OneSignal.appContext, false, locationHandler); |
| 215 | + // BlockingQueue used to make sure that the complete() callback is completely finished before moving on |
| 216 | + // SyncUserState was moving on and causing a thread lock with the complete() LocationGMS work |
| 217 | + // Issue #650 |
| 218 | + // https://github.com/OneSignal/OneSignal-Android-SDK/issues/650 |
| 219 | + try { |
| 220 | + final BlockingQueue<Object> queue = new ArrayBlockingQueue<>(1); |
| 221 | + LocationGMS.LocationHandler locationHandler = new LocationGMS.LocationHandler() { |
| 222 | + @Override |
| 223 | + public LocationGMS.CALLBACK_TYPE getType() { |
| 224 | + return LocationGMS.CALLBACK_TYPE.SYNC_SERVICE; |
| 225 | + } |
| 226 | + |
| 227 | + @Override |
| 228 | + public void complete(LocationGMS.LocationPoint point) { |
| 229 | + Object object = point != null ? point : new Object(); |
| 230 | + queue.offer(object); |
| 231 | + } |
| 232 | + }; |
| 233 | + LocationGMS.getLocation(OneSignal.appContext, false, locationHandler); |
| 234 | + |
| 235 | + // The take() will return the offered point once the callback for the locationHandler is completed |
| 236 | + Object point = queue.take(); |
| 237 | + if (point instanceof LocationGMS.LocationPoint) |
| 238 | + OneSignalStateSynchronizer.updateLocation((LocationGMS.LocationPoint) point); |
| 239 | + |
| 240 | + } catch (InterruptedException e) { |
| 241 | + e.printStackTrace(); |
| 242 | + } |
| 243 | + |
| 244 | + // Both these calls are synchronous |
| 245 | + // Once the queue calls take the code will continue and move on to the syncUserState |
| 246 | + OneSignalStateSynchronizer.syncUserState(true); |
| 247 | + FocusTimeController.getInstance().doBlockingBackgroundSyncOfUnsentTime(); |
| 248 | + stopSync(); |
231 | 249 | }
|
232 | 250 |
|
233 | 251 | protected abstract void stopSync();
|
|
0 commit comments