Application: Build OkHttpClient in onCreate(), rather than in static code.

This commit is contained in:
Andreas Schildbach 2019-11-22 19:01:04 +01:00
parent b5d827b495
commit 6bb38b08e4
11 changed files with 69 additions and 48 deletions

View file

@ -55,25 +55,7 @@ import okhttp3.logging.HttpLoggingInterceptor;
public class Application extends android.app.Application {
private PackageInfo packageInfo;
public static final OkHttpClient OKHTTP_CLIENT;
static {
final OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.followRedirects(false);
builder.followSslRedirects(true);
builder.connectTimeout(5, TimeUnit.SECONDS);
builder.writeTimeout(5, TimeUnit.SECONDS);
builder.readTimeout(15, TimeUnit.SECONDS);
final HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
@Override
public void log(final String message) {
log.debug(message);
}
});
interceptor.setLevel(HttpLoggingInterceptor.Level.BASIC);
builder.addNetworkInterceptor(interceptor);
OKHTTP_CLIENT = builder.build();
}
private OkHttpClient okHttpClient;
private static final Logger log = LoggerFactory.getLogger(Application.class);
@ -91,10 +73,26 @@ public class Application extends android.app.Application {
throw new RuntimeException(x);
}
initMaps();
log.info("=== Starting app version {} ({})", packageInfo.versionName, packageInfo.versionCode);
final OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.followRedirects(false);
builder.followSslRedirects(true);
builder.connectTimeout(5, TimeUnit.SECONDS);
builder.writeTimeout(5, TimeUnit.SECONDS);
builder.readTimeout(15, TimeUnit.SECONDS);
final HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
@Override
public void log(final String message) {
log.debug(message);
}
});
interceptor.setLevel(HttpLoggingInterceptor.Level.BASIC);
builder.addNetworkInterceptor(interceptor);
okHttpClient = builder.build();
initMaps();
final Stopwatch watch = Stopwatch.createStarted();
// clean up databases
@ -234,6 +232,10 @@ public class Application extends android.app.Application {
return packageInfo;
}
public OkHttpClient okHttpClient() {
return okHttpClient;
}
public static final String versionName(final Application application) {
return application.packageInfo().versionName;
}

View file

@ -52,7 +52,8 @@ public abstract class OeffiActivity extends Activity {
this.application = (Application) getApplication();
this.prefs = PreferenceManager.getDefaultSharedPreferences(this);
ErrorReporter.getInstance().check(this, applicationVersionCode(), applicationVersionFlavor());
ErrorReporter.getInstance().check(this, applicationVersionCode(), applicationVersionFlavor(),
application.okHttpClient());
}
protected void updateFragments(final int listFrameResId, final int mapFrameResId) {

View file

@ -378,7 +378,8 @@ public abstract class OeffiMainActivity extends OeffiActivity {
remoteUrl.addQueryParameter("task", taskName());
final File localFile = new File(getFilesDir(), "messages.txt");
final Downloader downloader = new Downloader(getCacheDir());
final ListenableFuture<Integer> download = downloader.download(remoteUrl.build(), localFile);
final ListenableFuture<Integer> download = downloader.download(application.okHttpClient(), remoteUrl.build(),
localFile);
Futures.addCallback(download, new FutureCallback<Integer>() {
public void onSuccess(final @Nullable Integer status) {
processMessages(network);
@ -530,7 +531,7 @@ public abstract class OeffiMainActivity extends OeffiActivity {
.addEncodedPathSegment(id + (Locale.getDefault().getLanguage().equals("de") ? "-de" : "") + ".txt");
final Request.Builder request = new Request.Builder();
request.url(url.build());
final Call call = Application.OKHTTP_CLIENT.newCall(request.build());
final Call call = application.okHttpClient().newCall(request.build());
call.enqueue(new Callback() {
public void onResponse(final Call call, final Response r) throws IOException {
try (final Response response = r) {

View file

@ -35,6 +35,7 @@ import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import de.schildbach.oeffi.Application;
import de.schildbach.oeffi.Constants;
import de.schildbach.oeffi.R;
import de.schildbach.oeffi.StationsAware;
@ -102,6 +103,8 @@ public class PlanActivity extends Activity {
context.startActivity(intent(context, planId, selectedStationId));
}
private Application application;
private ViewAnimator viewAnimator;
private ScrollImageView plan;
private View bubble;
@ -122,6 +125,7 @@ public class PlanActivity extends Activity {
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.application = (Application) getApplication();
// background thread
backgroundThread = new HandlerThread("queryDeparturesThread", Process.THREAD_PRIORITY_BACKGROUND);
@ -214,7 +218,7 @@ public class PlanActivity extends Activity {
final Downloader downloader = new Downloader(getCacheDir());
final HttpUrl remoteUrl = planUrlStr != null ? HttpUrl.parse(planUrlStr)
: Constants.PLANS_BASE_URL.newBuilder().addEncodedPathSegment(planFilename).build();
final ListenableFuture<Integer> download = downloader.download(remoteUrl, planFile);
final ListenableFuture<Integer> download = downloader.download(application.okHttpClient(), remoteUrl, planFile);
Futures.addCallback(download, new FutureCallback<Integer>() {
public void onSuccess(final @Nullable Integer status) {
if (status == HttpURLConnection.HTTP_OK)

View file

@ -48,6 +48,7 @@ import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors;
import de.schildbach.oeffi.Application;
import de.schildbach.oeffi.Constants;
import de.schildbach.oeffi.util.Downloader;
import de.schildbach.pte.NetworkId;
@ -83,6 +84,7 @@ public class PlanContentProvider extends ContentProvider {
public static final String KEY_STATION_X = "station_x";
public static final String KEY_STATION_Y = "station_y";
private Application application;
private Downloader downloader;
private static final Logger log = LoggerFactory.getLogger(PlanContentProvider.class);
@ -102,7 +104,8 @@ public class PlanContentProvider extends ContentProvider {
@Override
public boolean onCreate() {
downloader = new Downloader(getContext().getCacheDir());
this.application = (Application) getContext();
downloader = new Downloader(application.getCacheDir());
return true;
}
@ -127,13 +130,13 @@ public class PlanContentProvider extends ContentProvider {
final File indexFile = new File(getContext().getFilesDir(), Constants.PLAN_INDEX_FILENAME);
final HttpUrl remoteIndexUrl = Constants.PLANS_BASE_URL.newBuilder()
.addPathSegment(Constants.PLAN_INDEX_FILENAME).build();
final ListenableFuture<Integer> download = downloader.download(remoteIndexUrl, indexFile);
final ListenableFuture<Integer> download = downloader.download(application.okHttpClient(), remoteIndexUrl, indexFile);
Futures.addCallback(download, notifyChangeCallback, MoreExecutors.directExecutor());
final File stationsFile = new File(getContext().getFilesDir(), Constants.PLAN_STATIONS_FILENAME);
final HttpUrl remoteStationsUrl = Constants.PLANS_BASE_URL.newBuilder()
.addPathSegment(Constants.PLAN_STATIONS_FILENAME + ".bz2").build();
final ListenableFuture<Integer> stationsDownload = downloader.download(remoteStationsUrl, stationsFile, true);
final ListenableFuture<Integer> stationsDownload = downloader.download(application.okHttpClient(), remoteStationsUrl, stationsFile, true);
Futures.addCallback(stationsDownload, notifyChangeCallback, MoreExecutors.directExecutor());
final List<String> pathSegments = uri.getPathSegments();

View file

@ -122,7 +122,7 @@ public class PlansPickerActivity extends OeffiMainActivity implements ActivityCo
listView = (RecyclerView) findViewById(android.R.id.list);
listView.setLayoutManager(new LinearLayoutManager(this));
listView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL_LIST));
listAdapter = new PlansAdapter(this, cursor, thumbCache, this, this);
listAdapter = new PlansAdapter(this, cursor, thumbCache, this, this, application.okHttpClient());
listView.setAdapter(listAdapter);
connectivityWarningView = (TextView) findViewById(R.id.plans_picker_connectivity_warning_box);
@ -253,7 +253,7 @@ public class PlansPickerActivity extends OeffiMainActivity implements ActivityCo
if (filter != null)
uri.appendPath(SearchManager.SUGGEST_URI_PATH_QUERY).appendPath(filter);
cursor = getContentResolver().query(uri.build(), null, null, null, sortOrder);
listAdapter = new PlansAdapter(this, cursor, thumbCache, this, this);
listAdapter = new PlansAdapter(this, cursor, thumbCache, this, this, application.okHttpClient());
listView.setAdapter(listAdapter);
findViewById(android.R.id.empty).setVisibility(cursor.getCount() > 0 ? View.GONE : View.VISIBLE);
@ -299,8 +299,8 @@ public class PlansPickerActivity extends OeffiMainActivity implements ActivityCo
final Downloader downloader = new Downloader(getCacheDir());
final HttpUrl remoteUrl = plan.url != null ? plan.url
: Constants.PLANS_BASE_URL.newBuilder().addEncodedPathSegment(planFilename).build();
final ListenableFuture<Integer> download = downloader.download(remoteUrl, planFile, false,
(contentRead, contentLength) -> runOnUiThread(() -> {
final ListenableFuture<Integer> download = downloader.download(application.okHttpClient(), remoteUrl,
planFile, false, (contentRead, contentLength) -> runOnUiThread(() -> {
final RecyclerView.ViewHolder holder = listView.findViewHolderForItemId(plan.rowId);
if (holder != null) {
final int position = holder.getAdapterPosition();

View file

@ -67,7 +67,8 @@ public class PlansAdapter extends RecyclerView.Adapter<PlanViewHolder> {
private final OkHttpClient cachingOkHttpClient;
public PlansAdapter(final Context context, final Cursor cursor, final Cache thumbCache,
final PlanClickListener clickListener, final PlanContextMenuItemListener contextMenuItemListener) {
final PlanClickListener clickListener, final PlanContextMenuItemListener contextMenuItemListener,
final OkHttpClient okHttpClient) {
this.context = context;
this.res = context.getResources();
this.inflater = LayoutInflater.from(context);
@ -85,7 +86,7 @@ public class PlansAdapter extends RecyclerView.Adapter<PlanViewHolder> {
setHasStableIds(true);
cachingOkHttpClient = Application.OKHTTP_CLIENT.newBuilder().cache(thumbCache).build();
cachingOkHttpClient = okHttpClient.newBuilder().cache(thumbCache).build();
}
public void setProgressPermille(final int position, final int progressPermille) {

View file

@ -46,9 +46,12 @@ public class DecodeForeignActivity extends Activity {
private static final Pattern PATTERN_META_REFRESH = Pattern
.compile("<meta\\s+http-equiv=\"refresh\"\\s+content=\"0;\\s+URL=([^\"]*)\"");
private Application application;
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.application = (Application) getApplication();
final Intent intent = getIntent();
final Uri uri = intent.getData();
@ -66,7 +69,7 @@ public class DecodeForeignActivity extends Activity {
final Request.Builder request = new Request.Builder();
request.url(HttpUrl.parse(uri.toString()));
final Call call = Application.OKHTTP_CLIENT.newCall(request.build());
final Call call = application.okHttpClient().newCall(request.build());
call.enqueue(new Callback() {
public void onResponse(final Call call, final Response r) throws IOException {
try (final Response response = r) {

View file

@ -35,6 +35,7 @@ import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors;
import de.schildbach.oeffi.Application;
import de.schildbach.oeffi.Constants;
import de.schildbach.oeffi.util.Downloader;
import de.schildbach.pte.NetworkId;
@ -64,6 +65,7 @@ public final class NetworkContentProvider extends ContentProvider {
public static final String QUERY_PARAM_Q = "q";
private Application application;
private Downloader downloader;
private final List<SQLiteDatabase> databasesToClose = new LinkedList<>();
private static final int NUM_DATABASES_TO_KEEP = 4;
@ -83,7 +85,8 @@ public final class NetworkContentProvider extends ContentProvider {
@Override
public boolean onCreate() {
downloader = new Downloader(getContext().getCacheDir());
this.application = (Application) getContext();
downloader = new Downloader(application.getCacheDir());
return true;
}
@ -104,7 +107,7 @@ public final class NetworkContentProvider extends ContentProvider {
final NetworkId networkId = NetworkId.valueOf(uri.getPathSegments().get(0));
final File dbFile = new File(getContext().getFilesDir(), dbName(networkId));
final HttpUrl remoteUrl = downloadUrl(networkId);
final ListenableFuture<Integer> download = downloader.download(remoteUrl, dbFile, true, null);
final ListenableFuture<Integer> download = downloader.download(application.okHttpClient(), remoteUrl, dbFile, true, null);
Futures.addCallback(download, new FutureCallback<Integer>() {
public void onSuccess(final @Nullable Integer status) {
if (status == HttpURLConnection.HTTP_OK)

View file

@ -39,7 +39,6 @@ import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.SettableFuture;
import com.google.common.util.concurrent.Striped;
import de.schildbach.oeffi.Application;
import de.schildbach.oeffi.util.bzip2.BZip2CompressorInputStream;
import androidx.annotation.Nullable;
@ -47,6 +46,7 @@ import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Headers;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
@ -66,16 +66,18 @@ public class Downloader {
this.cacheDir = cacheDir;
}
public ListenableFuture<Integer> download(final HttpUrl remoteUrl, final File targetFile) {
return download(remoteUrl, targetFile, false, null);
public ListenableFuture<Integer> download(final OkHttpClient okHttpClient, final HttpUrl remoteUrl,
final File targetFile) {
return download(okHttpClient, remoteUrl, targetFile, false, null);
}
public ListenableFuture<Integer> download(final HttpUrl remoteUrl, final File targetFile, final boolean unzip) {
return download(remoteUrl, targetFile, unzip, null);
public ListenableFuture<Integer> download(final OkHttpClient okHttpClient, final HttpUrl remoteUrl,
final File targetFile, final boolean unzip) {
return download(okHttpClient, remoteUrl, targetFile, unzip, null);
}
public ListenableFuture<Integer> download(final HttpUrl remoteUrl, final File targetFile, final boolean unzip,
@Nullable final ProgressCallback progressCallback) {
public ListenableFuture<Integer> download(final OkHttpClient okHttpClient, final HttpUrl remoteUrl,
final File targetFile, final boolean unzip, @Nullable final ProgressCallback progressCallback) {
final SettableFuture<Integer> future = SettableFuture.create();
final Semaphore semaphore = semaphores.get(targetFile);
if (semaphore.tryAcquire()) {
@ -98,7 +100,7 @@ public class Downloader {
if (etag != null)
request.header("If-None-Match", etag);
}
final Call call = Application.OKHTTP_CLIENT.newCall(request.build());
final Call call = okHttpClient.newCall(request.build());
call.enqueue(new Callback() {
private final File tempFile = new File(cacheDir,
targetFile.getName() + ".part." + String.format("%04x", random.nextInt(0x10000)));

View file

@ -38,7 +38,6 @@ import org.slf4j.LoggerFactory;
import com.google.common.base.Joiner;
import com.google.common.base.Strings;
import de.schildbach.oeffi.Application;
import de.schildbach.oeffi.Constants;
import de.schildbach.oeffi.R;
import de.schildbach.pte.NetworkId;
@ -65,6 +64,7 @@ import androidx.core.content.FileProvider;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
@ -321,7 +321,8 @@ public class ErrorReporter implements Thread.UncaughtExceptionHandler {
private final static Pattern PATTERN_VERSION = Pattern.compile("<dt id=\"(\\d+)\">([^<]*)</dt>");
public void check(final Context context, final int applicationVersionCode, final String applicationVersionFlavor) {
public void check(final Context context, final int applicationVersionCode, final String applicationVersionFlavor,
final OkHttpClient okHttpClient) {
if (!stackTraceFile.exists())
return;
@ -332,7 +333,7 @@ public class ErrorReporter implements Thread.UncaughtExceptionHandler {
url.addQueryParameter("sdk", Integer.toString(Build.VERSION.SDK_INT));
url.addQueryParameter("check", null);
final Request.Builder request = new Request.Builder().url(url.build());
final Call call = Application.OKHTTP_CLIENT.newCall(request.build());
final Call call = okHttpClient.newCall(request.build());
final Handler callbackHandler = new Handler(Looper.myLooper());
call.enqueue(new Callback() {
public void onResponse(final Call call, final Response r) throws IOException {