Browse Source

Use built in OkHttpCache instead of manual cache

master
anthony restaino 8 years ago
parent
commit
ba1bad6d95
  1. 99
      app/src/main/java/acr/browser/lightning/search/BaseSuggestionsModel.java
  2. 5
      app/src/main/java/acr/browser/lightning/search/DuckSuggestionsModel.java
  3. 7
      app/src/main/java/acr/browser/lightning/search/GoogleSuggestionsModel.java
  4. 4
      app/src/main/java/acr/browser/lightning/search/SuggestionsAdapter.java
  5. 13
      app/src/main/java/acr/browser/lightning/utils/FileUtils.java

99
app/src/main/java/acr/browser/lightning/search/BaseSuggestionsModel.java

@ -1,31 +1,28 @@ @@ -1,31 +1,28 @@
package acr.browser.lightning.search;
import android.app.Application;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.Log;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.TimeUnit;
import java.util.zip.GZIPInputStream;
import acr.browser.lightning.database.HistoryItem;
import acr.browser.lightning.utils.FileUtils;
import acr.browser.lightning.utils.Utils;
import okhttp3.Cache;
import okhttp3.CacheControl;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
@ -35,26 +32,27 @@ abstract class BaseSuggestionsModel { @@ -35,26 +32,27 @@ abstract class BaseSuggestionsModel {
private static final String TAG = BaseSuggestionsModel.class.getSimpleName();
static final int MAX_RESULTS = 5;
private static final long INTERVAL_DAY = TimeUnit.DAYS.toMillis(1);
private static final long INTERVAL_DAY = TimeUnit.DAYS.toSeconds(1);
@NonNull private static final String DEFAULT_LANGUAGE = "en";
@Nullable private static String sLanguage;
@NonNull private final Application mApplication;
@NonNull private final OkHttpClient mHttpClient = new OkHttpClient();
@NonNull private final OkHttpClient mHttpClient;
@NonNull private final CacheControl mCacheControl;
@NonNull private final ConnectivityManager mConnectivityManager;
@NonNull
protected abstract String createQueryUrl(@NonNull String query, @NonNull String language);
protected abstract void parseResults(@NonNull FileInputStream inputStream, @NonNull List<HistoryItem> results) throws Exception;
protected abstract void parseResults(@NonNull InputStream inputStream, @NonNull List<HistoryItem> results) throws Exception;
@NonNull
protected abstract String getEncoding();
BaseSuggestionsModel(@NonNull Application application) {
mApplication = application;
File suggestionsCache = new File(application.getCacheDir(), "suggestion_responses");
mHttpClient = new OkHttpClient.Builder()
.cache(new Cache(suggestionsCache, FileUtils.megabytesToBytes(1)))
.addNetworkInterceptor(REWRITE_CACHE_CONTROL_INTERCEPTOR)
.build();
mCacheControl = new CacheControl.Builder().maxStale(1, TimeUnit.DAYS).build();
mConnectivityManager = getConnectivityManager(mApplication);
}
@NonNull
@ -76,20 +74,18 @@ abstract class BaseSuggestionsModel { @@ -76,20 +74,18 @@ abstract class BaseSuggestionsModel {
} catch (UnsupportedEncodingException e) {
Log.e(TAG, "Unable to encode the URL", e);
}
File cache = downloadSuggestionsForQuery(query, getLanguage(), mApplication);
if (!cache.exists()) {
InputStream inputStream = downloadSuggestionsForQuery(query, getLanguage());
if (inputStream == null) {
// There are no suggestions for this query, return an empty list.
return filter;
}
FileInputStream fileInput = null;
try {
fileInput = new FileInputStream(cache);
parseResults(fileInput, filter);
parseResults(inputStream, filter);
} catch (Exception e) {
Log.e(TAG, "Unable to parse results", e);
return filter;
} finally {
Utils.close(fileInput);
Utils.close(inputStream);
}
return filter;
@ -102,68 +98,37 @@ abstract class BaseSuggestionsModel { @@ -102,68 +98,37 @@ abstract class BaseSuggestionsModel {
* @param query the query to get suggestions for
* @return the cache file containing the suggestions
*/
@NonNull
private File downloadSuggestionsForQuery(@NonNull String query, String language, @NonNull Application app) {
@Nullable
private InputStream downloadSuggestionsForQuery(@NonNull String query, String language) {
String queryUrl = createQueryUrl(query, language);
File cacheFile = new File(app.getCacheDir(), queryUrl.hashCode() + SuggestionsAdapter.CACHE_FILE_TYPE);
if (System.currentTimeMillis() - INTERVAL_DAY < cacheFile.lastModified()) {
return cacheFile;
}
if (!isNetworkConnected()) {
return cacheFile;
}
InputStream in = null;
FileOutputStream fos = null;
try {
URL url = new URL(queryUrl);
// OkHttp automatically gzips requests
Request suggestionsRequest = new Request.Builder().url(url)
.addHeader("Accept-Encoding", "gzip")
.addHeader("Accept-Charset", getEncoding())
.cacheControl(mCacheControl)
.build();
Response suggestionsResponse = mHttpClient.newCall(suggestionsRequest).execute();
if (suggestionsResponse.code() >= HttpURLConnection.HTTP_MULT_CHOICE ||
suggestionsResponse.code() < HttpURLConnection.HTTP_OK) {
Log.e(TAG, "Search API Responded with code: " + suggestionsResponse.code());
suggestionsResponse.body().close();
return cacheFile;
}
in = suggestionsResponse.body().byteStream();
if (in != null) {
in = new GZIPInputStream(in);
//noinspection IOResourceOpenedButNotSafelyClosed
fos = new FileOutputStream(cacheFile);
int buffer;
while ((buffer = in.read()) != -1) {
fos.write(buffer);
}
fos.flush();
}
suggestionsResponse.body().close();
cacheFile.setLastModified(System.currentTimeMillis());
return suggestionsResponse.body().byteStream();
} catch (Exception e) {
Log.w(TAG, "Problem getting search suggestions", e);
} finally {
Utils.close(in);
Utils.close(fos);
}
return cacheFile;
Log.e(TAG, "Problem getting search suggestions", e);
}
private boolean isNetworkConnected() {
NetworkInfo networkInfo = mConnectivityManager.getActiveNetworkInfo();
return networkInfo != null && networkInfo.isConnected();
return null;
}
@NonNull
private static ConnectivityManager getConnectivityManager(@NonNull Context context) {
return (ConnectivityManager) context
.getApplicationContext()
.getSystemService(Context.CONNECTIVITY_SERVICE);
private static final Interceptor REWRITE_CACHE_CONTROL_INTERCEPTOR = new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Response originalResponse = chain.proceed(chain.request());
return originalResponse.newBuilder()
.header("cache-control", "max-age=" + INTERVAL_DAY + ", max-stale=" + INTERVAL_DAY)
.build();
}
};
}

5
app/src/main/java/acr/browser/lightning/search/DuckSuggestionsModel.java

@ -7,6 +7,7 @@ import org.json.JSONArray; @@ -7,6 +7,7 @@ import org.json.JSONArray;
import org.json.JSONObject;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.List;
import acr.browser.lightning.R;
@ -30,8 +31,8 @@ final class DuckSuggestionsModel extends BaseSuggestionsModel { @@ -30,8 +31,8 @@ final class DuckSuggestionsModel extends BaseSuggestionsModel {
}
@Override
protected void parseResults(@NonNull FileInputStream inputStream, @NonNull List<HistoryItem> results) throws Exception {
String content = FileUtils.readStringFromFile(inputStream, ENCODING);
protected void parseResults(@NonNull InputStream inputStream, @NonNull List<HistoryItem> results) throws Exception {
String content = FileUtils.readStringFromStream(inputStream, ENCODING);
JSONArray jsonArray = new JSONArray(content);
int counter = 0;
for (int n = 0, size = jsonArray.length(); n < size; n++) {

7
app/src/main/java/acr/browser/lightning/search/GoogleSuggestionsModel.java

@ -10,6 +10,7 @@ import org.xmlpull.v1.XmlPullParserFactory; @@ -10,6 +10,7 @@ import org.xmlpull.v1.XmlPullParserFactory;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.List;
import acr.browser.lightning.R;
@ -33,10 +34,10 @@ class GoogleSuggestionsModel extends BaseSuggestionsModel { @@ -33,10 +34,10 @@ class GoogleSuggestionsModel extends BaseSuggestionsModel {
}
@Override
protected void parseResults(@NonNull FileInputStream inputStream, @NonNull List<HistoryItem> results) throws Exception {
BufferedInputStream fileInput = new BufferedInputStream(inputStream);
protected void parseResults(@NonNull InputStream inputStream, @NonNull List<HistoryItem> results) throws Exception {
BufferedInputStream bufferedInput = new BufferedInputStream(inputStream);
XmlPullParser parser = getParser();
parser.setInput(fileInput, ENCODING);
parser.setInput(bufferedInput, ENCODING);
int eventType = parser.getEventType();
int counter = 0;
while (eventType != XmlPullParser.END_DOCUMENT) {

4
app/src/main/java/acr/browser/lightning/search/SuggestionsAdapter.java

@ -96,6 +96,7 @@ public class SuggestionsAdapter extends BaseAdapter implements Filterable { @@ -96,6 +96,7 @@ public class SuggestionsAdapter extends BaseAdapter implements Filterable {
}
public void clearCache() {
// We don't need these cache files anymore
Schedulers.io().execute(new ClearCacheRunnable(BrowserApp.get(mContext)));
}
@ -382,14 +383,11 @@ public class SuggestionsAdapter extends BaseAdapter implements Filterable { @@ -382,14 +383,11 @@ public class SuggestionsAdapter extends BaseAdapter implements Filterable {
public void run() {
File dir = new File(app.getCacheDir().toString());
String[] fileList = dir.list(new NameFilter());
long earliestTimeAllowed = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(1);
for (String fileName : fileList) {
File file = new File(dir.getPath() + fileName);
if (earliestTimeAllowed > file.lastModified()) {
file.delete();
}
}
}
private static class NameFilter implements FilenameFilter {

13
app/src/main/java/acr/browser/lightning/utils/FileUtils.java

@ -138,7 +138,8 @@ public class FileUtils { @@ -138,7 +138,8 @@ public class FileUtils {
}
@NonNull
public static String readStringFromFile(@NonNull InputStream inputStream, @NonNull String encoding) throws IOException {
public static String readStringFromStream(@NonNull InputStream inputStream,
@NonNull String encoding) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, encoding));
StringBuilder result = new StringBuilder();
String line;
@ -148,4 +149,14 @@ public class FileUtils { @@ -148,4 +149,14 @@ public class FileUtils {
return result.toString();
}
/**
* Converts megabytes to bytes.
*
* @param megaBytes the number of megabytes.
* @return the converted bytes.
*/
public static long megabytesToBytes(long megaBytes) {
return megaBytes * 1024 * 1024;
}
}

Loading…
Cancel
Save