@@ -47,18 +47,17 @@ class DataFileLoader {
47
47
}
48
48
49
49
@ RequiresApi (api = Build .VERSION_CODES .HONEYCOMB )
50
- boolean getDataFile (@ NonNull String projectId , @ Nullable DataFileLoadedListener dataFileLoadedListener ) {
50
+ void getDataFile (@ NonNull String projectId , @ Nullable DataFileLoadedListener dataFileLoadedListener ) {
51
51
taskChain .start (projectId , dataFileLoadedListener );
52
52
53
53
logger .info ("Refreshing data file" );
54
-
55
- return true ;
56
54
}
57
55
58
56
static class TaskChain {
59
57
60
58
@ NonNull private final DataFileService dataFileService ;
61
59
@ NonNull private final Executor executor ;
60
+ @ Nullable DataFileLoadedListener dataFileLoadedListener ;
62
61
63
62
TaskChain (@ NonNull DataFileService dataFileService ) {
64
63
this .dataFileService = dataFileService ;
@@ -67,6 +66,7 @@ static class TaskChain {
67
66
68
67
@ RequiresApi (api = Build .VERSION_CODES .HONEYCOMB )
69
68
void start (@ NonNull String projectId , @ Nullable DataFileLoadedListener dataFileLoadedListener ) {
69
+ this .dataFileLoadedListener = dataFileLoadedListener ;
70
70
DataFileClient dataFileClient = new DataFileClient (
71
71
new Client (new OptlyStorage (dataFileService ), LoggerFactory .getLogger (OptlyStorage .class )),
72
72
LoggerFactory .getLogger (DataFileClient .class ));
@@ -76,27 +76,30 @@ void start(@NonNull String projectId, @Nullable DataFileLoadedListener dataFileL
76
76
LoggerFactory .getLogger (DataFileCache .class ));
77
77
RequestDataFileFromClientTask requestDataFileFromClientTask =
78
78
new RequestDataFileFromClientTask (projectId ,
79
- dataFileService , dataFileCache ,
79
+ dataFileService ,
80
+ dataFileCache ,
80
81
dataFileClient ,
81
- dataFileLoadedListener ,
82
+ this ,
82
83
LoggerFactory .getLogger (RequestDataFileFromClientTask .class ));
83
- LoadDataFileFromCacheTask loadDataFileFromCacheTask = new LoadDataFileFromCacheTask (dataFileCache , dataFileLoadedListener );
84
+ LoadDataFileFromCacheTask loadDataFileFromCacheTask = new LoadDataFileFromCacheTask (dataFileCache , this );
84
85
85
86
// Execute tasks in order
86
87
loadDataFileFromCacheTask .executeOnExecutor (executor );
87
88
requestDataFileFromClientTask .executeOnExecutor (executor );
88
89
}
90
+
91
+
89
92
}
90
93
91
94
static class LoadDataFileFromCacheTask extends AsyncTask <Void , Void , JSONObject > {
92
95
93
96
@ NonNull private final DataFileCache dataFileCache ;
94
- @ Nullable private final DataFileLoadedListener dataFileLoadedListener ;
97
+ @ NonNull private final TaskChain taskChain ;
95
98
96
99
LoadDataFileFromCacheTask (@ NonNull DataFileCache dataFileCache ,
97
- @ Nullable DataFileLoadedListener dataFileLoadedListener ) {
100
+ @ NonNull TaskChain taskChain ) {
98
101
this .dataFileCache = dataFileCache ;
99
- this .dataFileLoadedListener = dataFileLoadedListener ;
102
+ this .taskChain = taskChain ;
100
103
}
101
104
102
105
@ Override
@@ -107,8 +110,14 @@ protected JSONObject doInBackground(Void... params) {
107
110
@ Override
108
111
protected void onPostExecute (JSONObject dataFile ) {
109
112
if (dataFile != null ) {
110
- if (dataFileLoadedListener != null ) {
111
- dataFileLoadedListener .onDataFileLoaded (dataFile .toString ());
113
+ if (taskChain .dataFileLoadedListener != null ) {
114
+ taskChain .dataFileLoadedListener .onDataFileLoaded (dataFile .toString ());
115
+ // Prevents the callback from being hit twice
116
+ // if the CDN datafile is different from the cached
117
+ // datafile. The service will still get the remote
118
+ // datafile and update the cache but Optimizely
119
+ // will be started from the cached datafile.
120
+ taskChain .dataFileLoadedListener = null ;
112
121
}
113
122
}
114
123
}
@@ -122,51 +131,51 @@ static class RequestDataFileFromClientTask extends AsyncTask<Void, Void, String>
122
131
@ NonNull private final DataFileCache dataFileCache ;
123
132
@ NonNull private final DataFileClient dataFileClient ;
124
133
@ NonNull private final Logger logger ;
125
- @ Nullable private final DataFileLoadedListener optimizelyStartedListener ;
134
+ @ NonNull private final TaskChain taskChain ;
126
135
127
136
RequestDataFileFromClientTask (@ NonNull String projectId ,
128
137
@ NonNull DataFileService dataFileService ,
129
138
@ NonNull DataFileCache dataFileCache ,
130
139
@ NonNull DataFileClient dataFileClient ,
131
- @ Nullable DataFileLoadedListener dataFileLoadedListener ,
140
+ @ NonNull TaskChain taskChain ,
132
141
@ NonNull Logger logger ) {
133
142
this .projectId = projectId ;
134
143
this .dataFileService = dataFileService ;
135
144
this .dataFileCache = dataFileCache ;
136
145
this .dataFileClient = dataFileClient ;
137
- this .optimizelyStartedListener = dataFileLoadedListener ;
146
+ this .taskChain = taskChain ;
138
147
this .logger = logger ;
139
148
}
140
149
141
150
@ Override
142
151
protected String doInBackground (Void ... params ) {
143
152
String dataFile = dataFileClient .request (String .format (FORMAT_CDN_URL , projectId ));
144
- if (dataFile != null ) {
153
+ if (dataFileClient . isModifiedResponse ( dataFile ) ) {
145
154
if (dataFileCache .exists ()) {
146
155
if (!dataFileCache .delete ()) {
147
156
logger .warn ("Unable to delete old data file" );
148
- return null ; // Unable to delete
149
157
}
150
158
}
151
159
if (!dataFileCache .save (dataFile )) {
152
160
logger .warn ("Unable to save new data file" );
153
- return null ;
154
161
}
155
162
}
156
163
157
164
return dataFile ;
158
165
}
159
166
160
167
@ Override
161
- protected void onPostExecute (String dataFile ) {
162
- // If dataFile isn't null the dataFile has been modified on the CDN because we are
163
- // using last-modified and since-last-modified headers.
164
- if (dataFile != null ) {
165
- if (optimizelyStartedListener != null ) {
166
- optimizelyStartedListener .onDataFileLoaded (dataFile );
168
+ protected void onPostExecute (@ Nullable String dataFile ) {
169
+ // If this is null either this is a background sync
170
+ // Or a locally cached datafile was already loaded.
171
+ if (taskChain .dataFileLoadedListener != null ) {
172
+ // An empty datafile (304) should not be possible unless someone manually
173
+ // deleted the cached datafile and not the caching headers
174
+ // on a rooted device.
175
+ if (dataFileClient .isNotModifiedResponse (dataFile )) {
176
+ taskChain .dataFileLoadedListener .onDataFileLoaded (dataFile );
167
177
}
168
178
}
169
-
170
179
// We are running in the background so stop the service
171
180
dataFileService .stop ();
172
181
}
0 commit comments