** 由於前一版閱讀紀錄有部份問題, 所以書籤中的書籍必須長按選擇"清除紀錄" **
* 新增"保持螢幕開啟"的設定
> 點選選單, 選擇設定
BUGS:
* 解決加入bookmark後, 啟動會 FC 的問題
* 修正卡提諾小說論壇顯示錯誤的問題
* 修正部份載入錯誤
* 修正搜尋後加入書籤會產生錯誤的問題
Google Play: 小說閱讀器 v1.0.3
sudo rmmod ehci_hcd; sudo modprobe ehci-hcd
git clone --depth 1 https://android.googlesource.com/platform/frameworks/volley
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <GridView android:id="@+id/gridview" android:layout_width="match_parent" android:layout_height="wrap_content" android:drawSelectorOnTop="true" android:alwaysDrawnWithCache="false" android:fadeScrollbars="true" android:cacheColorHint="@android:color/transparent" android:numColumns="3" android:columnWidth="160dp"/> </RelativeLayout>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:id="@+id/imageview" android:layout_width="160dp" android:layout_height="160dp" android:layout_centerInParent="true" android:scaleType="center" android:contentDescription="@null"/> </RelativeLayout>
public class BitmapLruCache implements ImageLoader.ImageCache {
final LinkedHashMap<String, Bitmap> map;
private final int maxSize;
private int size;
/**
* Create a cache using an appropriate portion of the available RAM as the maximum size.
*/
public BitmapLruCache(Context context) {
this(calculateMaxSize(context));
}
/**
* Create a cache with a given maximum size in bytes.
*/
public BitmapLruCache(int maxSize) {
if (maxSize <= 0) {
throw new IllegalArgumentException("Max size must be positive.");
}
this.maxSize = maxSize;
this.map = new LinkedHashMap<String, Bitmap>(0, 0.75f, true);
}
private Bitmap get(String key) {
if (key == null) {
throw new NullPointerException("key == null");
}
Bitmap mapValue;
synchronized (this) {
mapValue = map.get(key);
if (mapValue != null) {
return mapValue;
}
}
return null;
}
private void set(String key, Bitmap bitmap) {
if (key == null || bitmap == null) {
throw new NullPointerException("key == null || bitmap == null");
}
Bitmap previous;
synchronized (this) {
size += getBitmapBytes(bitmap);
previous = map.put(key, bitmap);
if (previous != null) {
size -= getBitmapBytes(previous);
}
}
trimToSize(maxSize);
}
private void trimToSize(int maxSize) {
while (true) {
String key;
Bitmap value;
synchronized (this) {
if (size < 0 || (map.isEmpty() && size != 0)) {
throw new IllegalStateException(
getClass().getName() + ".sizeOf() is reporting inconsistent results!");
}
if (size <= maxSize || map.isEmpty()) {
break;
}
Map.Entry<String, Bitmap> toEvict = map.entrySet().iterator().next();
key = toEvict.getKey();
value = toEvict.getValue();
map.remove(key);
size -= getBitmapBytes(value);
}
}
}
/**
* Clear the cache.
*/
public final void clear() {
trimToSize(-1); // -1 will evict 0-sized elements
}
private static int calculateMaxSize(Context context) {
ActivityManager am = (ActivityManager) context.getSystemService(ACTIVITY_SERVICE);
boolean largeHeap = (context.getApplicationInfo().flags & FLAG_LARGE_HEAP) != 0;
int memoryClass = am.getMemoryClass();
if (largeHeap && Build.VERSION.SDK_INT <= Build.VERSION_CODES.HONEYCOMB) {
memoryClass = ActivityManagerHoneycomb.getLargeMemoryClass(am);
}
return 1024 * 1024 * memoryClass / 6;
}
@Override
public Bitmap getBitmap(String url) {
return get(url);
}
@Override
public void putBitmap(String url, Bitmap bitmap) {
set(url, bitmap);
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
private static class ActivityManagerHoneycomb {
static int getLargeMemoryClass(ActivityManager activityManager) {
return activityManager.getLargeMemoryClass();
}
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1)
private static class BitmapHoneycombMR1 {
static int getByteCount(Bitmap bitmap) {
return bitmap.getByteCount();
}
}
private static int getBitmapBytes(Bitmap bitmap) {
int result;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1) {
result = BitmapHoneycombMR1.getByteCount(bitmap);
} else {
result = bitmap.getRowBytes() * bitmap.getHeight();
}
if (result < 0) {
throw new IllegalStateException("Negative size: " + bitmap);
}
return result;
}
}
RequestQueue mRequestQ;
ImageLoader mImageLoader;
mRequestQ = Volley.newRequestQueue(getActivity());
mImageLoader = new ImageLoader(mRequestQ, new BitmapLruCache(getActivity()));
holder.container = mImageLoader.get(item.url, new ImageLoader.ImageListener() {
@Override
public void onResponse(ImageLoader.ImageContainer response, boolean isImmediate) {
holder.iv.setImageBitmap(response.getBitmap());
}
@Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getContext(), error.getMessage(), Toast.LENGTH_SHORT).show();
}
}, 160,160);




<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Example</title>
<meta name="viewport" content="user-scalable=yes,target-densityDpi=device-dpi,width=device-width" />
<script type='text/javascript'>
function showMsg() {
prompt("This is prompt");
}
</script>
</head>
<body>
<input type='button' value='Click Me' onclick='showMsg();' />
</body>
</html>

WebChromeClient mWebChromeClient = new WebChromeClient() {
@Override
public boolean onJsPrompt(WebView view, String url, String message,
String defaultValue, JsPromptResult result) {
if ((defaultValue != null) && (defaultValue.length() != 0)) {
if (defaultValue.equalsIgnoreCase("jstesting")) {
Toast.makeText(MainActivity.this, R.string.msg_js_call_toast, Toast.LENGTH_SHORT).show();
result.cancel();
return true;
}
}
return super.onJsPrompt(view, url, message, defaultValue, result);
}
};
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Example</title>
<meta name="viewport" content="user-scalable=yes,target-densityDpi=device-dpi,width=device-width" />
<script type='text/javascript'>
function showMsg() {
prompt("This is prompt", "jstesting");
}
</script>
</head>
<body>
<input type='button' value='Click Me' onclick='showMsg();' />
</body>
</html>
mWebView.setWebChromeClient(new WebChromeClient()); mWebView.getSettings().setJavaScriptEnabled(true);
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Example</title>
<meta name="viewport" content="user-scalable=yes,target-densityDpi=device-dpi,width=device-width" />
<script type='text/javascript'>
function showMsg() {
alert('This is alert dialog');
}
</script>
</head>
<body>
<input type='button' value='Click Me' onclick='showMsg();'/>
</body>
</html>

mWebView.loadUrl("javasript:showMsg();");
效果跟上圖一樣, 也是會跳出一個訊息視窗.