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 @@
package acr.browser.lightning.search; package acr.browser.lightning.search;
import android.app.Application; 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.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.IOException;
import java.io.FileOutputStream;
import java.io.InputStream; import java.io.InputStream;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL; import java.net.URL;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.zip.GZIPInputStream;
import acr.browser.lightning.database.HistoryItem; import acr.browser.lightning.database.HistoryItem;
import acr.browser.lightning.utils.FileUtils;
import acr.browser.lightning.utils.Utils; import acr.browser.lightning.utils.Utils;
import okhttp3.Cache;
import okhttp3.CacheControl; import okhttp3.CacheControl;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient; import okhttp3.OkHttpClient;
import okhttp3.Request; import okhttp3.Request;
import okhttp3.Response; import okhttp3.Response;
@ -35,26 +32,27 @@ abstract class BaseSuggestionsModel {
private static final String TAG = BaseSuggestionsModel.class.getSimpleName(); private static final String TAG = BaseSuggestionsModel.class.getSimpleName();
static final int MAX_RESULTS = 5; 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"; @NonNull private static final String DEFAULT_LANGUAGE = "en";
@Nullable private static String sLanguage; @Nullable private static String sLanguage;
@NonNull private final Application mApplication; @NonNull private final OkHttpClient mHttpClient;
@NonNull private final OkHttpClient mHttpClient = new OkHttpClient();
@NonNull private final CacheControl mCacheControl; @NonNull private final CacheControl mCacheControl;
@NonNull private final ConnectivityManager mConnectivityManager;
@NonNull @NonNull
protected abstract String createQueryUrl(@NonNull String query, @NonNull String language); 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 @NonNull
protected abstract String getEncoding(); protected abstract String getEncoding();
BaseSuggestionsModel(@NonNull Application application) { 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(); mCacheControl = new CacheControl.Builder().maxStale(1, TimeUnit.DAYS).build();
mConnectivityManager = getConnectivityManager(mApplication);
} }
@NonNull @NonNull
@ -76,20 +74,18 @@ abstract class BaseSuggestionsModel {
} catch (UnsupportedEncodingException e) { } catch (UnsupportedEncodingException e) {
Log.e(TAG, "Unable to encode the URL", e); Log.e(TAG, "Unable to encode the URL", e);
} }
File cache = downloadSuggestionsForQuery(query, getLanguage(), mApplication); InputStream inputStream = downloadSuggestionsForQuery(query, getLanguage());
if (!cache.exists()) { if (inputStream == null) {
// There are no suggestions for this query, return an empty list. // There are no suggestions for this query, return an empty list.
return filter; return filter;
} }
FileInputStream fileInput = null;
try { try {
fileInput = new FileInputStream(cache); parseResults(inputStream, filter);
parseResults(fileInput, filter);
} catch (Exception e) { } catch (Exception e) {
Log.e(TAG, "Unable to parse results", e); Log.e(TAG, "Unable to parse results", e);
return filter; return filter;
} finally { } finally {
Utils.close(fileInput); Utils.close(inputStream);
} }
return filter; return filter;
@ -102,68 +98,37 @@ abstract class BaseSuggestionsModel {
* @param query the query to get suggestions for * @param query the query to get suggestions for
* @return the cache file containing the suggestions * @return the cache file containing the suggestions
*/ */
@NonNull @Nullable
private File downloadSuggestionsForQuery(@NonNull String query, String language, @NonNull Application app) { private InputStream downloadSuggestionsForQuery(@NonNull String query, String language) {
String queryUrl = createQueryUrl(query, 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 { try {
URL url = new URL(queryUrl); URL url = new URL(queryUrl);
// OkHttp automatically gzips requests
Request suggestionsRequest = new Request.Builder().url(url) Request suggestionsRequest = new Request.Builder().url(url)
.addHeader("Accept-Encoding", "gzip")
.addHeader("Accept-Charset", getEncoding()) .addHeader("Accept-Charset", getEncoding())
.cacheControl(mCacheControl) .cacheControl(mCacheControl)
.build(); .build();
Response suggestionsResponse = mHttpClient.newCall(suggestionsRequest).execute(); Response suggestionsResponse = mHttpClient.newCall(suggestionsRequest).execute();
if (suggestionsResponse.code() >= HttpURLConnection.HTTP_MULT_CHOICE || return suggestionsResponse.body().byteStream();
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());
} catch (Exception e) { } catch (Exception e) {
Log.w(TAG, "Problem getting search suggestions", e); Log.e(TAG, "Problem getting search suggestions", e);
} finally {
Utils.close(in);
Utils.close(fos);
}
return cacheFile;
} }
private boolean isNetworkConnected() { return null;
NetworkInfo networkInfo = mConnectivityManager.getActiveNetworkInfo();
return networkInfo != null && networkInfo.isConnected();
} }
@NonNull private static final Interceptor REWRITE_CACHE_CONTROL_INTERCEPTOR = new Interceptor() {
private static ConnectivityManager getConnectivityManager(@NonNull Context context) { @Override
return (ConnectivityManager) context public Response intercept(Chain chain) throws IOException {
.getApplicationContext() Response originalResponse = chain.proceed(chain.request());
.getSystemService(Context.CONNECTIVITY_SERVICE); 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;
import org.json.JSONObject; import org.json.JSONObject;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.InputStream;
import java.util.List; import java.util.List;
import acr.browser.lightning.R; import acr.browser.lightning.R;
@ -30,8 +31,8 @@ final class DuckSuggestionsModel extends BaseSuggestionsModel {
} }
@Override @Override
protected void parseResults(@NonNull FileInputStream inputStream, @NonNull List<HistoryItem> results) throws Exception { protected void parseResults(@NonNull InputStream inputStream, @NonNull List<HistoryItem> results) throws Exception {
String content = FileUtils.readStringFromFile(inputStream, ENCODING); String content = FileUtils.readStringFromStream(inputStream, ENCODING);
JSONArray jsonArray = new JSONArray(content); JSONArray jsonArray = new JSONArray(content);
int counter = 0; int counter = 0;
for (int n = 0, size = jsonArray.length(); n < size; n++) { 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;
import java.io.BufferedInputStream; import java.io.BufferedInputStream;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.InputStream;
import java.util.List; import java.util.List;
import acr.browser.lightning.R; import acr.browser.lightning.R;
@ -33,10 +34,10 @@ class GoogleSuggestionsModel extends BaseSuggestionsModel {
} }
@Override @Override
protected void parseResults(@NonNull FileInputStream inputStream, @NonNull List<HistoryItem> results) throws Exception { protected void parseResults(@NonNull InputStream inputStream, @NonNull List<HistoryItem> results) throws Exception {
BufferedInputStream fileInput = new BufferedInputStream(inputStream); BufferedInputStream bufferedInput = new BufferedInputStream(inputStream);
XmlPullParser parser = getParser(); XmlPullParser parser = getParser();
parser.setInput(fileInput, ENCODING); parser.setInput(bufferedInput, ENCODING);
int eventType = parser.getEventType(); int eventType = parser.getEventType();
int counter = 0; int counter = 0;
while (eventType != XmlPullParser.END_DOCUMENT) { 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 {
} }
public void clearCache() { public void clearCache() {
// We don't need these cache files anymore
Schedulers.io().execute(new ClearCacheRunnable(BrowserApp.get(mContext))); Schedulers.io().execute(new ClearCacheRunnable(BrowserApp.get(mContext)));
} }
@ -382,14 +383,11 @@ public class SuggestionsAdapter extends BaseAdapter implements Filterable {
public void run() { public void run() {
File dir = new File(app.getCacheDir().toString()); File dir = new File(app.getCacheDir().toString());
String[] fileList = dir.list(new NameFilter()); String[] fileList = dir.list(new NameFilter());
long earliestTimeAllowed = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(1);
for (String fileName : fileList) { for (String fileName : fileList) {
File file = new File(dir.getPath() + fileName); File file = new File(dir.getPath() + fileName);
if (earliestTimeAllowed > file.lastModified()) {
file.delete(); file.delete();
} }
} }
}
private static class NameFilter implements FilenameFilter { private static class NameFilter implements FilenameFilter {

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

@ -138,7 +138,8 @@ public class FileUtils {
} }
@NonNull @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)); BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, encoding));
StringBuilder result = new StringBuilder(); StringBuilder result = new StringBuilder();
String line; String line;
@ -148,4 +149,14 @@ public class FileUtils {
return result.toString(); 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