특정 사이트의 전체 화면 웹보기를 표시하는 Blackberry 응용 프로그램을 만들고 있습니다. 올바르게 작동하는 브라우저 필드가 있지만 페이지 간 탐색은 기본 브라우저보다 느립니다. 브라우저 필드에로드 시간이 느려지도록 내장 된 캐시가없는 것 같습니다. 캐시를 관리하기 위해 다음 코드를 추가하면 사이트가 더 이상 올바르게 표시되지 않습니다.Blackberry BrowserField에서 캐시하는 방법
BrowserFieldScreen.java :
import net.rim.device.api.browser.field2.*;
import net.rim.device.api.script.ScriptEngine;
import net.rim.device.api.system.*;
import net.rim.device.api.ui.*;
import net.rim.device.api.ui.component.*;
import net.rim.device.api.ui.container.*;
import org.w3c.dom.Document;
class BrowserFieldScreen extends MainScreen
{
BrowserField browserField;
LoadingScreen load = new LoadingScreen();;
public BrowserFieldScreen()
{
browserField = new BrowserField();
browserField.getConfig().setProperty(
BrowserFieldConfig.JAVASCRIPT_ENABLED,
Boolean.TRUE);
browserField.getConfig().setProperty(
BrowserFieldConfig.NAVIGATION_MODE,
BrowserFieldConfig.NAVIGATION_MODE_POINTER);
browserField.getConfig().setProperty(
BrowserFieldConfig.CONTROLLER,
new CacheProtocolController(browserField));
browserField.requestContent("http://www.stackoverflow.com");
add(browserField);
}
}
CacheProtocolController.java :
import javax.microedition.io.HttpConnection;
import javax.microedition.io.InputConnection;
import net.rim.device.api.browser.field2.BrowserField;
import net.rim.device.api.browser.field2.BrowserFieldRequest;
import net.rim.device.api.browser.field2.ProtocolController;
public class CacheProtocolController extends ProtocolController{
// The BrowserField instance
private BrowserField browserField;
// CacheManager will take care of cached resources
private CacheManager cacheManager;
public CacheProtocolController(BrowserField browserField) {
super(browserField);
this.browserField = browserField;
}
private CacheManager getCacheManager() {
if (cacheManager == null) {
cacheManager = new CacheManagerImpl();
}
return cacheManager;
}
/**
* Handle navigation requests (e.g., link clicks)
*/
public void handleNavigationRequest(BrowserFieldRequest request)
throws Exception
{
InputConnection ic = handleResourceRequest(request);
browserField.displayContent(ic, request.getURL());
}
/**
* Handle resource request
* (e.g., images, external css/javascript resources)
*/
public InputConnection handleResourceRequest(BrowserFieldRequest request)
throws Exception
{
// if requested resource is cacheable (e.g., an "http" resource),
// use the cache
if (getCacheManager() != null
&& getCacheManager().isRequestCacheable(request))
{
InputConnection ic = null;
// if requested resource is cached, retrieve it from cache
if (getCacheManager().hasCache(request.getURL())
&& !getCacheManager().hasCacheExpired(request.getURL()))
{
ic = getCacheManager().getCache(request.getURL());
}
// if requested resource is not cached yet, cache it
else
{
ic = super.handleResourceRequest(request);
if (ic instanceof HttpConnection)
{
HttpConnection response = (HttpConnection) ic;
if (getCacheManager().isResponseCacheable(response))
{
ic = getCacheManager().createCache(request.getURL(),
response);
}
}
}
return ic;
}
// if requested resource is not cacheable, load it as usual
return super.handleResourceRequest(request);
}
}
CacheManager.java :
import javax.microedition.io.HttpConnection;
import javax.microedition.io.InputConnection;
import net.rim.device.api.browser.field2.BrowserFieldRequest;
public interface CacheManager {
public boolean isRequestCacheable(BrowserFieldRequest request);
public boolean isResponseCacheable(HttpConnection response);
public boolean hasCache(String url);
public boolean hasCacheExpired(String url);
public InputConnection getCache(String url);
public InputConnection createCache(String url, HttpConnection response);
public void clearCache(String url);
}
CacheManagerImpl.java :
0,123,516import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.Hashtable;
import javax.microedition.io.HttpConnection;
import javax.microedition.io.InputConnection;
import net.rim.device.api.browser.field2.BrowserFieldRequest;
import net.rim.device.api.browser.field2.BrowserFieldResponse;
import net.rim.device.api.io.http.HttpHeaders;
public class CacheManagerImpl implements CacheManager {
private static final int MAX_STANDARD_CACHE_AGE = 2592000;
private Hashtable cacheTable;
public CacheManagerImpl() {
cacheTable = new Hashtable();
}
public boolean isRequestCacheable(BrowserFieldRequest request) {
// Only HTTP requests are cacheable
if (!request.getProtocol().equals("http")) {
return false;
}
// Don't cache the request whose method is not "GET".
if (request instanceof HttpConnection) {
if (!((HttpConnection) request).getRequestMethod().equals("GET"))
{
return false;
}
}
// Don't cache the request with post data.
if (request.getPostData() != null) {
return false;
}
// Don't cache authentication request.
if (request.getHeaders().getPropertyValue("Authorization") != null) {
return false;
}
return true;
}
public boolean isResponseCacheable(HttpConnection response) {
try {
if (response.getResponseCode() != 200) {
return false;
}
} catch (IOException ioe) {
return false;
}
if (!response.getRequestMethod().equals("GET")) {
return false;
}
if (containsPragmaNoCache(response)) {
return false;
}
if (isExpired(response)) {
return false;
}
if (containsCacheControlNoCache(response)) {
return false;
}
if (response.getLength() <= 0) {
return false;
}
// additional checks can be implemented here to inspect
// the HTTP cache-related headers of the response object
return true;
}
private boolean isExpired(HttpConnection response) {
try
{
// getExpiration() returns 0 if not known
long expires = response.getExpiration();
if (expires > 0 && expires <= (new Date()).getTime()) {
return true;
}
return false;
} catch (IOException ioe) {
return true;
}
}
private boolean containsPragmaNoCache(HttpConnection response) {
try
{
if (response.getHeaderField("pragma") != null
&& response.getHeaderField("pragma")
.toLowerCase()
.indexOf("no-cache") >= 0)
{
return true;
}
return false;
} catch (IOException ioe) {
return true;
}
}
private boolean containsCacheControlNoCache(HttpConnection response) {
try {
String cacheControl = response.getHeaderField("cache-control");
if (cacheControl != null) {
cacheControl = removeSpace(cacheControl.toLowerCase());
if (cacheControl.indexOf("no-cache") >= 0
|| cacheControl.indexOf("no-store") >= 0
|| cacheControl.indexOf("private") >= 0
|| cacheControl.indexOf("max-age=0") >= 0) {
return true;
}
long maxAge = parseMaxAge(cacheControl);
if (maxAge > 0 && response.getDate() > 0) {
long date = response.getDate();
long now = (new Date()).getTime();
if (now > date + maxAge) {
// Already expired
return true;
}
}
}
return false;
} catch (IOException ioe) {
return true;
}
}
public InputConnection createCache(String url, HttpConnection response) {
byte[] data = null;
InputStream is = null;
try {
// Read data
int len = (int) response.getLength();
if (len > 0) {
is = response.openInputStream();
int actual = 0;
int bytesread = 0 ;
data = new byte[len];
while ((bytesread != len) && (actual != -1)) {
actual = is.read(data, bytesread, len - bytesread);
bytesread += actual;
}
}
} catch (IOException ioe) {
data = null;
} finally {
if (is != null) {
try {
is.close();
} catch (IOException ioe) {
}
}
if (response != null) {
try {
response.close();
} catch (IOException ioe) {
}
}
}
if (data == null) {
return null;
}
// Calculate expires
long expires = calculateCacheExpires(response);
// Copy headers
HttpHeaders headers = copyResponseHeaders(response);
// add item to cache
cacheTable.put(url, new CacheItem(url, expires, data, headers));
return new BrowserFieldResponse(url, data, headers);
}
private long calculateCacheExpires(HttpConnection response) {
long date = 0;
try {
date = response.getDate();
} catch (IOException ioe) {
}
if (date == 0) {
date = (new Date()).getTime();
}
long expires = getResponseExpires(response);
// If an expire date has not been specified assumes the maximum time
if (expires == 0) {
return date + (MAX_STANDARD_CACHE_AGE * 1000L);
}
return expires;
}
private long getResponseExpires(HttpConnection response) {
try {
// Calculate expires from "expires"
long expires = response.getExpiration();
if (expires > 0) {
return expires;
}
// Calculate expires from "max-age" and "date"
if (response.getHeaderField("cache-control") != null) {
String cacheControl = removeSpace(response
.getHeaderField("cache-control")
.toLowerCase());
long maxAge = parseMaxAge(cacheControl);
long date = response.getDate();
if (maxAge > 0 && date > 0) {
return (date + maxAge);
}
}
} catch (IOException ioe) {
}
return 0;
}
private long parseMaxAge(String cacheControl) {
if (cacheControl == null) {
return 0;
}
long maxAge = 0;
if (cacheControl.indexOf("max-age=") >= 0) {
int maxAgeStart = cacheControl.indexOf("max-age=") + 8;
int maxAgeEnd = cacheControl.indexOf(',', maxAgeStart);
if (maxAgeEnd < 0) {
maxAgeEnd = cacheControl.length();
}
try {
maxAge = Long.parseLong(cacheControl.substring(maxAgeStart,
maxAgeEnd));
} catch (NumberFormatException nfe) {
}
}
// Multiply maxAge by 1000 to convert seconds to milliseconds
maxAge *= 1000L;
return maxAge;
}
private static String removeSpace(String s) {
StringBuffer result= new StringBuffer();
int count = s.length();
for (int i = 0; i < count; i++) {
char c = s.charAt(i);
if (c != ' ') {
result.append(c);
}
}
return result.toString();
}
private HttpHeaders copyResponseHeaders(HttpConnection response) {
HttpHeaders headers = new HttpHeaders();
try {
int index = 0;
while (response.getHeaderFieldKey(index) != null) {
headers.addProperty(response.getHeaderFieldKey(index),
response.getHeaderField(index));
index++;
}
} catch (IOException ioe) {
}
return headers;
}
public boolean hasCache(String url) {
return cacheTable.containsKey(url);
}
public boolean hasCacheExpired(String url) {
Object o = cacheTable.get(url);
if (o instanceof CacheItem) {
CacheItem ci = (CacheItem) o;
long date = (new Date()).getTime();
if (ci.getExpires() > date) {
return false;
} else {
// Remove the expired cache item
clearCache(url);
}
}
return true;
}
public void clearCache(String url) {
cacheTable.remove(url);
}
public InputConnection getCache(String url) {
Object o = cacheTable.get(url);
if (o instanceof CacheItem) {
CacheItem ci = (CacheItem) o;
return new BrowserFieldResponse(url,
ci.getData(),
ci.getHttpHeaders());
}
return null;
}
}
CacheItem.java :이쪽으로 제공 할 수있는 모든 도움을 크게 감사합니다
import net.rim.device.api.io.http.HttpHeaders;
public class CacheItem {
private String url;
private long expires;
private byte[] data;
private HttpHeaders httpHeaders;
public CacheItem(String url,
long expires,
byte[] data,
HttpHeaders httpHeaders)
{
this.url = url;
this.expires = expires;
this.data = data;
this.httpHeaders = httpHeaders;
}
public String getUrl() {
return url;
}
public long getExpires() {
return expires;
}
public byte[] getData() {
return data;
}
public HttpHeaders getHttpHeaders() {
return httpHeaders;
}
}
. 이것은 정말로 나를 곤란하게 만든다. 감사.
업데이트 : 캐싱은 특정 수준의 블랙 베리 라이브러리에서만 작동합니다. 현재 소프트웨어 수준을 확인하고 장치의 현재 소프트웨어 수준에서 지원되는 경우 캐싱을 설정하는 논리를 추가했습니다. 이것은 좋은 해결 방법을 제공하지만 모든 장치에서 캐싱을 수행 할 수있는 더 좋은 방법이 있는지 알고 싶습니다.
업데이트 날짜 : 2 설명 : 더 이상 적절하게 표시되지 않는 사이트는 적절한 레이아웃, 이미지 및 텍스트가 표시되지 않는 사이트와 관련이 있습니다. 기본적으로 흰색 배경에 링크 및 글 머리 기호 목록으로 표시되며 모든 서식이 제거됩니다.
"사이트가 더 이상 올바르게 표시되지 않는다"는 것은 무엇을 의미합니까? 캐시를 사용하면 어떻게됩니까? – Tamar
자세한 내용이 도움이 될 것입니다.* 더 이상 올바르게 표시되지 않습니다. * * 캐싱은 특정 레벨에서만 작동합니다. * * 작동 *은 무엇을 의미합니까? 제대로 작동하지 않으면 정확히 무엇이 발생합니까? – nloko
캐시 내용을 잃어 버리면 메인 스크린을 계속 볼 때 또는 화면을 닫았다가 다시 열 때 탐색 중이라는 것을 의미합니까? 로드하는 모든 페이지에 대해 새 브라우저 화면을 만드십니까? –