22
22
import android .content .Context ;
23
23
import android .content .Intent ;
24
24
import android .content .ServiceConnection ;
25
+ import android .content .res .Resources ;
25
26
import android .os .AsyncTask ;
26
27
import android .os .Bundle ;
27
28
import android .os .IBinder ;
28
29
import android .support .annotation .NonNull ;
29
30
import android .support .annotation .Nullable ;
31
+ import android .support .annotation .RawRes ;
30
32
31
33
import com .optimizely .ab .Optimizely ;
32
34
import com .optimizely .ab .android .event_handler .OptlyEventHandler ;
33
35
import com .optimizely .ab .android .shared .ServiceScheduler ;
34
36
import com .optimizely .ab .bucketing .UserExperimentRecord ;
37
+ import com .optimizely .ab .config .parser .ConfigParseException ;
35
38
import com .optimizely .ab .event .internal .payload .Event ;
36
39
import com .optimizely .user_experiment_record .AndroidUserExperimentRecord ;
37
40
38
41
import org .slf4j .Logger ;
39
42
import org .slf4j .LoggerFactory ;
40
43
44
+ import java .io .IOException ;
45
+ import java .io .InputStream ;
41
46
import java .util .concurrent .Executor ;
42
47
import java .util .concurrent .Executors ;
43
48
import java .util .concurrent .TimeUnit ;
@@ -128,6 +133,38 @@ public AndroidOptimizely getOptimizely() {
128
133
return androidOptimizely ;
129
134
}
130
135
136
+ @ NonNull
137
+ public AndroidOptimizely getOptimizely (@ NonNull Context context , @ RawRes int dataFileRes ) {
138
+ AndroidUserExperimentRecord userExperimentRecord =
139
+ (AndroidUserExperimentRecord ) AndroidUserExperimentRecord .newInstance (getProjectId (), context );
140
+ // Blocking File I/O is necessary here in order to provide a synchronous API
141
+ // The User Experiment Record is started off the of the main thread when starting
142
+ // asynchronously. Starting simply creates the file if it doesn't exist so it's not
143
+ // terribly expensive. Blocking the UI the thread prevents touch input...
144
+ userExperimentRecord .start ();
145
+ try {
146
+ androidOptimizely = buildOptimizely (context , loadRawResource (context , dataFileRes ), userExperimentRecord );
147
+ } catch (ConfigParseException e ) {
148
+ logger .error ("Unable to parse compiled data file" , e );
149
+ } catch (IOException e ) {
150
+ logger .error ("Unable to load compiled data file" , e );
151
+ }
152
+
153
+ return androidOptimizely ;
154
+ }
155
+
156
+ private String loadRawResource (Context context , @ RawRes int rawRes ) throws IOException {
157
+ Resources res = context .getResources ();
158
+ InputStream in = res .openRawResource (rawRes );
159
+ byte [] b = new byte [in .available ()];
160
+ int read = in .read (b );
161
+ if (read > -1 ) {
162
+ return new String (b );
163
+ } else {
164
+ throw new IOException ("Couldn't parse raw res fixture, no bytes" );
165
+ }
166
+ }
167
+
131
168
@ NonNull
132
169
public String getProjectId () {
133
170
return projectId ;
@@ -148,16 +185,8 @@ protected void onPostExecute(UserExperimentRecord userExperimentRecord) {
148
185
serviceScheduler .schedule (intent , dataFileDownloadIntervalTimeUnit .toMillis (dataFileDownloadInterval ));
149
186
150
187
try {
151
- OptlyEventHandler eventHandler = OptlyEventHandler .getInstance (context );
152
- eventHandler .setDispatchInterval (eventHandlerDispatchInterval , eventHandlerDispatchIntervalTimeUnit );
153
- Optimizely optimizely = Optimizely .builder (dataFile , eventHandler )
154
- .withUserExperimentRecord (userExperimentRecord )
155
- .withClientEngine (Event .ClientEngine .ANDROID_SDK )
156
- .withClientVersion (BuildConfig .CLIENT_VERSION )
157
- .build ();
188
+ OptimizelyManager .androidOptimizely = buildOptimizely (context , dataFile , userExperimentRecord );
158
189
logger .info ("Sending Optimizely instance to listener" );
159
- AndroidOptimizely androidOptimizely = new AndroidOptimizely (optimizely );
160
- OptimizelyManager .androidOptimizely = androidOptimizely ;
161
190
162
191
if (optimizelyStartListener != null ) {
163
192
optimizelyStartListener .onStart (androidOptimizely );
@@ -176,6 +205,17 @@ protected void onPostExecute(UserExperimentRecord userExperimentRecord) {
176
205
initUserExperimentRecordTask .executeOnExecutor (executor );
177
206
}
178
207
208
+ private AndroidOptimizely buildOptimizely (@ NonNull Context context , @ NonNull String dataFile , @ NonNull UserExperimentRecord userExperimentRecord ) throws ConfigParseException {
209
+ OptlyEventHandler eventHandler = OptlyEventHandler .getInstance (context );
210
+ eventHandler .setDispatchInterval (eventHandlerDispatchInterval , eventHandlerDispatchIntervalTimeUnit );
211
+ Optimizely optimizely = Optimizely .builder (dataFile , eventHandler )
212
+ .withUserExperimentRecord (userExperimentRecord )
213
+ .withClientEngine (Event .ClientEngine .ANDROID_SDK )
214
+ .withClientVersion (BuildConfig .CLIENT_VERSION )
215
+ .build ();
216
+ return new AndroidOptimizely (optimizely );
217
+ }
218
+
179
219
public static class OptlyActivityLifecycleCallbacks implements Application .ActivityLifecycleCallbacks {
180
220
181
221
@ NonNull private OptimizelyManager optimizelyManager ;
0 commit comments