添加列表图片加载栈,添加 httpHelper 类,以后完善

This commit is contained in:
seven332 committed 2014-03-23 16:00:27 +08:00
1 parent 471962e664
commit 57419fd8d1
22 files changed
+362 -40

No files matched your search

BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 KiB

After

Width:  |  Height:  |  Size: 8.4 KiB

BIN
View File
Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.7 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.3 KiB

After

Width:  |  Height:  |  Size: 9.3 KiB

+2 -4
View File
@@ -1,14 +1,12 @@
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:hippo="http://schemas.android.com/apk/res/com.hippo.ehviewer"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<com.hippo.ehviewer.view.OlImageView
<com.hippo.ehviewer.widget.LoadImageView
android:id="@+id/cover"
android:layout_width="67dp"
android:layout_height="wrap_content"
hippo:adjustViewBounds="true"
android:layout_height="100dp"
android:scaleType="fitCenter"
android:layout_gravity="center" />
+1
View File
@@ -7,6 +7,7 @@ Version 0.3.2 (2014-??-??)
* 后台检查登陆状态
* 设置中添加移除所有应用通知项
* 修正清除缓存错误
* 修正 game 拼写为 gmae 错误
* 修正其他问题
Version 0.3.1 (2014-03-14)
@@ -0,0 +1,153 @@
package com.hippo.ehviewer;
import java.util.Stack;
import com.hippo.ehviewer.network.HttpHelper;
import com.hippo.ehviewer.util.Ui;
import com.hippo.ehviewer.util.Util;
import com.hippo.ehviewer.widget.LoadImageView;
import android.graphics.Bitmap;
import android.os.Handler;
import android.os.Message;
import android.support.v4.util.LruCache;
public class ImageLoadManager {
private class LoadTask {
public LoadImageView liv;
public boolean download;
public Bitmap bitmap;
public LoadTask(LoadImageView liv, boolean download) {
this.liv = liv;
this.download = download;
}
}
private final Stack<LoadTask> mLoadCacheTask;
private ImageDownloadManager mImageDownloadTask;
private LruCache<String, Bitmap> mMemoryCache;
private DiskCache mDiskCache;
private LoadTask curLoadTask;
private final LoadTask emptyLoadTask = new LoadTask(null, false);
private static final Handler loadImageHandler =
new Handler() {
@Override
public void handleMessage(Message msg) {
LoadTask task = (LoadTask)msg.obj;
task.liv.setImageBitmap(task.bitmap);
}
};
public ImageLoadManager(LruCache<String, Bitmap> memoryCache,
DiskCache diskCache) {
mLoadCacheTask = new Stack<LoadTask>();
mImageDownloadTask = new ImageDownloadManager();
mMemoryCache = memoryCache;
mDiskCache = diskCache;
}
public synchronized void add(LoadImageView liv, boolean download) {
liv.setState(LoadImageView.LOADING);
mLoadCacheTask.push(new LoadTask(liv, download));
if (curLoadTask == null) {
new Thread(new LoadFromCacheTask()).start();
curLoadTask = emptyLoadTask;
}
}
private class LoadFromCacheTask implements Runnable {
@Override
public void run() {
while (true) {
synchronized (ImageLoadManager.this) {
if (mLoadCacheTask.isEmpty()) {
curLoadTask = null;
break;
}
curLoadTask = mLoadCacheTask.pop();
}
LoadImageView liv = curLoadTask.liv;
String key = liv.getKey();
Bitmap bitmap;
if ((bitmap = mMemoryCache.get(key)) == null) {
bitmap = (Bitmap)mDiskCache.get(key, Util.BITMAP);
if (bitmap != null)
mMemoryCache.put(key, bitmap);
}
Message msg = new Message();
msg.obj = curLoadTask;
if (bitmap == null) { // Load from cache error
curLoadTask.bitmap = Ui.BITMAP_LAUNCH;
if (curLoadTask.download)
mImageDownloadTask.add(curLoadTask);
else
liv.setState(LoadImageView.FAIL);
} else {
curLoadTask.bitmap = bitmap;
liv.setState(LoadImageView.LOADED);
}
loadImageHandler.sendMessage(msg);
}
}
}
private class ImageDownloadManager {
private static final int MAX_DOWNLOAD_THREADS = 3;
private final Stack<LoadTask> mDownloadTask;
private int workingDownloadThreads = 0;
public ImageDownloadManager() {
mDownloadTask = new Stack<LoadTask>();
}
public synchronized void add(LoadTask loadTask) {
mDownloadTask.push(loadTask);
if (workingDownloadThreads < MAX_DOWNLOAD_THREADS) {
new Thread(new DownloadImageTask()).start();
workingDownloadThreads++;
}
}
private class DownloadImageTask implements Runnable {
@Override
public void run() {
LoadTask loadTask;
HttpHelper httpHelper = new HttpHelper();
while (true) {
synchronized (ImageDownloadManager.this) {
if (mDownloadTask.isEmpty()) {
loadTask = null;
workingDownloadThreads--;
break;
}
loadTask = mDownloadTask.pop();
}
LoadImageView liv = loadTask.liv;
Bitmap bitmap = httpHelper.getImage(liv.getUrl(),
liv.getKey(), mMemoryCache, mDiskCache, true);
Message msg = new Message();
msg.obj = loadTask;
if (bitmap == null) {
loadTask.bitmap = Ui.BITMAP_TOUCH;
liv.setState(LoadImageView.FAIL);
liv.setOnClickListener(ImageLoadManager.this);
} else {
loadTask.bitmap = bitmap;
liv.setState(LoadImageView.LOADED);
}
loadImageHandler.sendMessage(msg);
}
}
}
}
}
@@ -1,17 +1,15 @@
package com.hippo.ehviewer.activity;
import java.io.File;
import java.net.MalformedURLException;
import java.util.ArrayList;
import com.hippo.ehviewer.BeautifyScreen;
import com.hippo.ehviewer.ImageLoadManager;
import com.hippo.ehviewer.ListMangaDetail;
import com.hippo.ehviewer.ListUrls;
import com.hippo.ehviewer.R;
import com.hippo.ehviewer.UpdateHelper;
import com.hippo.ehviewer.dialog.DialogBuilder;
import com.hippo.ehviewer.dialog.SuperDialogUtil;
import com.hippo.ehviewer.network.Downloader;
import com.hippo.ehviewer.service.DownloadService;
import com.hippo.ehviewer.service.DownloadServiceConnection;
import com.hippo.ehviewer.util.Cache;
@@ -23,28 +21,24 @@ import com.hippo.ehviewer.util.Ui;
import com.hippo.ehviewer.view.AlertButton;
import com.hippo.ehviewer.view.CheckImage;
import com.hippo.ehviewer.view.GetPaddingRelativeLayout;
import com.hippo.ehviewer.view.OlImageView;
import com.hippo.ehviewer.view.TagListView;
import com.hippo.ehviewer.view.TagsAdapter;
import com.hippo.ehviewer.widget.DrawerLayout;
import com.hippo.ehviewer.widget.LoadImageView;
import com.hippo.ehviewer.widget.PullListView;
import com.hippo.ehviewer.widget.PullListView.OnFooterRefreshListener;
import com.hippo.ehviewer.widget.PullListView.OnHeaderRefreshListener;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.NotificationManager;
import android.app.SearchManager;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Color;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
@@ -77,6 +71,7 @@ import android.widget.Toast;
// TODO add lock to get list
public class MangaListActivity extends Activity {
@SuppressWarnings("unused")
private static String TAG = "MangaListActivity";
private DrawerLayout drawer;
@@ -106,7 +101,10 @@ public class MangaListActivity extends Activity {
private int mStableItemCount;
private ArrayList<ListMangaDetail> lmdArray = new ArrayList<ListMangaDetail>();
private ImageLoadManager mImageLoadManager;
private int longClickItemIndex;
private boolean mListFirst = true;
@@ -134,7 +132,6 @@ public class MangaListActivity extends Activity {
private int visiblePage = 0;
private String title;
private String updateFileName;
private class RefreshPackage {
public ListUrls listUrls;
@@ -897,8 +894,12 @@ public class MangaListActivity extends Activity {
int getChildCount = view.getChildCount();
for (int i = 0; i < getChildCount; i++) {
View v = ((ViewGroup) view.getChildAt(i)).getChildAt(0);
if (v instanceof OlImageView)
((OlImageView)v).loadImage(false);
if (v instanceof LoadImageView) {
LoadImageView liv = (LoadImageView)v;
int status = liv.getState();
if (status != LoadImageView.LOADING && status != LoadImageView.LOADED)
mImageLoadManager.add(liv, true);
}
}
mListFirst = false;
}
@@ -930,8 +931,12 @@ public class MangaListActivity extends Activity {
&& (getChildCount = view.getChildCount()) != 0) {
for (int i = 0; i < getChildCount; i++) {
View v = ((ViewGroup) view.getChildAt(i)).getChildAt(0);
if (v instanceof OlImageView)
((OlImageView) v).loadImage(false);
if (v instanceof LoadImageView) {
LoadImageView liv = (LoadImageView)v;
int status = liv.getState();
if (status != LoadImageView.LOADING && status != LoadImageView.LOADED)
mImageLoadManager.add(liv, true);
}
}
}
}
@@ -965,12 +970,10 @@ public class MangaListActivity extends Activity {
if (convertView == null)
convertView = mInflater.inflate(R.layout.list_item, null);
OlImageView thumb = (OlImageView)convertView.findViewById(R.id.cover);
LoadImageView thumb = (LoadImageView)convertView.findViewById(R.id.cover);
if (!lmd.gid.equals(thumb.getKey())) {
thumb.setUrl(lmd.thumb);
thumb.setKey(lmd.gid);
thumb.setCache(Cache.memoryCache, Cache.cpCache);
thumb.loadFromCache();
thumb.setLoadInfo(lmd.thumb, lmd.gid);
mImageLoadManager.add(thumb, false);
// Set manga name
TextView name = (TextView) convertView.findViewById(R.id.name);
@@ -1031,6 +1034,9 @@ public class MangaListActivity extends Activity {
filterDialog = createFilterDialog();
longClickDialog = createLongClickDialog();
//
mImageLoadManager = new ImageLoadManager(Cache.memoryCache, Cache.cpCache);
getActionBar().setDisplayHomeAsUpEnabled(true);
// For colourfy the activity
@@ -1501,10 +1507,6 @@ public class MangaListActivity extends Activity {
loginDialog.show();
}
class ImageLoadTask {
}
@@ -1,9 +1,6 @@
package com.hippo.ehviewer.activity;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import com.hippo.ehviewer.BeautifyScreen;
import com.hippo.ehviewer.DiskCache;
@@ -20,7 +17,6 @@ import android.annotation.SuppressLint;
import android.app.NotificationManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.net.Uri;
@@ -33,15 +29,12 @@ import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceActivity;
import android.preference.PreferenceScreen;
import android.support.v4.util.LruCache;
import android.text.Html;
import android.util.Log;
import android.webkit.WebView;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;
//TODO Add thanks
public class SettingsActivity extends PreferenceActivity {
@SuppressWarnings("unused")
private static String TAG = "Settings";
private Context mContext;
@@ -86,6 +79,7 @@ public class SettingsActivity extends PreferenceActivity {
setRequestedOrientation(screenOri);
}
@SuppressWarnings("deprecation")
@SuppressLint("NewApi")
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -33,7 +33,7 @@ public class Downloader implements Runnable {
private static final int MAX_REDIRECTS = 5;
private static final int MAX_RETRY = 5;
private static final int DEFAULT_TIMEOUT = 20 * 1000;
private static final int DEFAULT_TIMEOUT = 5 * 1000;
private String mPath;
private String mFileName;
@@ -0,0 +1,95 @@
package com.hippo.ehviewer.network;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.UnknownHostException;
import org.apache.http.conn.ConnectTimeoutException;
import com.hippo.ehviewer.DiskCache;
import com.hippo.ehviewer.R;
import com.hippo.ehviewer.util.Ui;
import com.hippo.ehviewer.util.Util;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.support.v4.util.LruCache;
import android.util.Log;
/**
* It is not thread safe
*
* @author Hippo
*
*/
public class HttpHelper {
private static final String TAG = "HttpHelper";
private static final String userAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.76 Safari/537.36";
private static final int DEFAULT_TIMEOUT = 5 * 1000;
private int lastEMsgId = R.string.em_unknown_error;
/**
* Get last error message id
* @return
*/
public int getLastEMsgId() {
return lastEMsgId;
}
public Bitmap getImage(String urlStr, String key,
LruCache<String, Bitmap> memoryCache,
DiskCache diskCache, boolean getImage) {
HttpURLConnection conn = null;
Bitmap bitmap = null;
try {
Log.d(TAG, "Get Image " + urlStr);
URL url = new URL(urlStr);
conn = (HttpURLConnection)url.openConnection();
conn.setRequestProperty("User-Agent", userAgent);
conn.setConnectTimeout(DEFAULT_TIMEOUT);
conn.setReadTimeout(DEFAULT_TIMEOUT);
conn.connect();
InputStream is = conn.getInputStream();
if (diskCache == null) {
if (getImage
&& (bitmap = BitmapFactory.decodeStream(is, null, Ui.getBitmapOpt())) != null) {
if (memoryCache != null)
memoryCache.put(key, bitmap);
}
} else {
diskCache.put(key, is);
if (memoryCache != null || getImage) {
Bitmap bmp = (Bitmap)diskCache.get(key, Util.BITMAP);
if (bmp != null) {
if (memoryCache != null)
memoryCache.put(key, bmp);
if (getImage)
bitmap = bmp;
}
}
}
} catch (MalformedURLException e) {
lastEMsgId = R.string.em_url_error;
e.printStackTrace();
} catch (ConnectTimeoutException e) {
lastEMsgId = R.string.em_timeout;
e.printStackTrace();
} catch (UnknownHostException e) {
lastEMsgId = R.string.em_no_network_2;
e.printStackTrace();
} catch (IOException e) {
lastEMsgId = R.string.em_network_error;
e.printStackTrace();
} finally {
if (conn != null)
conn.disconnect();
}
return bitmap;
}
}
+8 -4
View File
@@ -40,6 +40,9 @@ public class Ui {
public static Bitmap BITMAP_START_HALF;
public static Bitmap BITMAP_START_EMPTY;
public static Bitmap BITMAP_LAUNCH;
public static Bitmap BITMAP_TOUCH;
private static boolean mInit = false;
/**
@@ -58,7 +61,7 @@ public class Ui {
opt.inPurgeable = true;
opt.inInputShareable = true;
/*
BITMAP_DOUJINSHI = BitmapFactory.decodeStream(mContext.getResources().openRawResource(R.drawable.doujinshi), null, opt);
BITMAP_MANGAI = BitmapFactory.decodeStream(mContext.getResources().openRawResource(R.drawable.manga), null, opt);
BITMAP_ARTIST_CG = BitmapFactory.decodeStream(mContext.getResources().openRawResource(R.drawable.artistcg), null, opt);
@@ -74,9 +77,10 @@ public class Ui {
BITMAP_START = BitmapFactory.decodeStream(mContext.getResources().openRawResource(R.drawable.star), null, opt);
BITMAP_START_HALF = BitmapFactory.decodeStream(mContext.getResources().openRawResource(R.drawable.star_half), null, opt);
BITMAP_START_EMPTY = BitmapFactory.decodeStream(mContext.getResources().openRawResource(R.drawable.star_empty), null, opt);
*/
OlImageView.setDefaultImage(BitmapFactory.decodeStream(mContext.getResources().openRawResource(R.drawable.ic_launcher))
, BitmapFactory.decodeStream(mContext.getResources().openRawResource(R.drawable.ic_touch), null, opt));
BITMAP_LAUNCH = BitmapFactory.decodeStream(mContext.getResources().openRawResource(R.drawable.ic_launcher), null, opt);
BITMAP_TOUCH = BitmapFactory.decodeStream(mContext.getResources().openRawResource(R.drawable.ic_touch), null, opt);
OlImageView.setDefaultImage(BITMAP_LAUNCH, BITMAP_TOUCH);
}
/**
+1
View File
@@ -58,6 +58,7 @@ public class Util {
is.close();
os.flush();
os.close();
buffer = null;
}
public static final int BITMAP = 0x0;
@@ -0,0 +1,74 @@
package com.hippo.ehviewer.widget;
import com.hippo.ehviewer.ImageLoadManager;
import com.hippo.ehviewer.util.Ui;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ImageView;
public class LoadImageView extends ImageView {
@SuppressWarnings("unused")
private static final String TAG = "LoadImageView";
public static final int NONE = 0x0;
public static final int LOADING = 0x1;
public static final int LOADED = 0x2;
public static final int FAIL = 0x3;
private int mState = NONE;
private String mUrl;
private String mKey;
public LoadImageView(Context context) {
super(context);
}
public LoadImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public LoadImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public void setLoadInfo(String url, String key) {
mUrl = url;
mKey = key;
}
public synchronized void setState(int state) {
mState = state;
if (mState != FAIL)
setClickable(false);
}
public void setOnClickListener(ImageLoadManager ilm) {
setOnClickListener(new OnClickListener(ilm));
}
public String getUrl() {
return mUrl;
}
public String getKey() {
return mKey;
}
public synchronized int getState() {
return mState;
}
class OnClickListener implements View.OnClickListener {
private ImageLoadManager mImageLoadManager;
public OnClickListener(ImageLoadManager imageLoadManager) {
mImageLoadManager = imageLoadManager;
}
@Override
public void onClick(View v) {
LoadImageView.this.setImageBitmap(Ui.BITMAP_LAUNCH);
mImageLoadManager.add(LoadImageView.this, true);
}
}
}