public class ArticleProvider extends BaseProvider {
	private static final String TAG = ArticleProvider.class.getSimpleName();
	public static final String TABLENAME = "ARTICLE";

	public static class ArticleColumns {
		public static final String _ID = BaseColumns._ID;
		public static final String TITLE = "TITLE";
		public static final String DESCRIPTION = "DESCRIPTION";
		public static final String THUMBNAIL = "THUMBNAIL";
		public static final String CONTENT = "CONTENT";
		public static final String SUBMIT_DATE = "SUBMIT_DATE";
		public static final String GET_DATE = "GET_DATE";
		public static final String TYPE = "TYPE";
		public static final String URL = "URL";
	}

	public static String getCreateSql() {
		return "CREATE TABLE " + TABLENAME + "(" + ArticleColumns._ID + " INTEGER PRIMARY KEY," + ArticleColumns.TITLE + " TEXT,"
				+ ArticleColumns.DESCRIPTION + " TEXT," + ArticleColumns.THUMBNAIL + " TEXT," + ArticleColumns.CONTENT + " TEXT,"
				+ ArticleColumns.SUBMIT_DATE + " LONG," + ArticleColumns.TYPE + " INTEGER," + ArticleColumns.URL + " TEXT,"
				+ ArticleColumns.GET_DATE + " LONG" + "); ";
	}

	@Override
	protected String getIdColumn() {
		return ArticleColumns._ID;
	}

	@Override
	protected String getTableName() {
		return TABLENAME;
	}

} public class Constant {
	public final static boolean DEBUG = true;
	public final static String DEBUG_USER_ID = "453333657@qq.com";
	public final static String DEBUG_USER_PWD = "chenzipeng";

	/**
	 * 服务器配置
	 */
	public final static String SERVER_HOST = "www.lingganhezi.com";
	public final static int SERVER_PORT = 80;
	public final static String SERVER_PART = "/";
	public final static String SERVER_ADD = "http://" + SERVER_HOST + ":" + SERVER_PORT + SERVER_PART;

	public final static String PROVIDER_AUTHORITY = "com.lingganhezi.myapp.data";

	/**
	 * http 请求队列 ，个数 预先创建多少个 请求队列
	 * 
	 */
	public final static int REQUESTQUEUE_HTTP_REQUEST_SIZE = 4;
	/**
	 * http mulitipat 请求队列 ，个数 预先创建多少个 请求队列
	 * 
	 */
	public final static int REQUESTQUEUE_HTTP_MULITI_REQUEST_SIZE = 2;

	public final static int STATE_CODE_FAILD = 0;
	public final static int STATE_CODE_SUCCESS = 1;

	public final static Uri CONTENT_URI_ARTICLE_PROVIDER = Uri.parse("content://com.lingganhezi.myapp.data.ArticleProvider");
	public final static Uri CONTENT_URI_MESSAGE_SESSION_PROVIDER = Uri.parse("content://com.lingganhezi.myapp.data.MessageSessionProvider");
	public final static Uri CONTENT_URI_USERINFO_PROVIDER = Uri.parse("content://com.lingganhezi.myapp.data.UserInfoProvider");
	public final static Uri CONTENT_URI_PLACE_PROVIDER = Uri.parse("content://com.lingganhezi.myapp.data.PlaceProvider");
	public final static Uri CONTENT_URI_MESSAGE_PROVIDER = Uri.parse("content://com.lingganhezi.myapp.data.MessageProvider");

	/**
	 * 普通文章类型
	 */
	public final static int ARTICLE_TYPE_SPECIAL = -1;
	/**
	 * 专题文章类型，幻灯片
	 */
	public final static int ARTICLE_TYPE_NORMAL = 1;

	/**
	 * 头像 裁剪 图像生成宽高
	 */
	public final static int PERSONAL_AVATAR_CLIP_LENGTH = 200;

	/**
	 * http contenttype
	 */
	public final static ContentType HTTP_CONTENTTYPE_IMAGE_JPEG = ContentType.create("image/jpeg");
	public final static ContentType HTTP_CONTENTTYPE_IMAGE_PNG = ContentType.create("image/png");
	public final static ContentType HTTP_CONTENTTYPE_IMAGE_WBMP = ContentType.create("image/wbmp");

	public final static int SEX_UNKONW = -1;
	public final static int SEX_MAN = 0;
	public final static int SEX_WOMEN = 1;

	/**
	 * 收件箱
	 */
	public final static String MESSAGE_BOX_INBOX = "inbox";
	/**
	 * 发件箱
	 */
	public final static String MESSAGE_BOX_OUTBOX = "outbox";

	public final static int MESSAGE_ID_UNDIFINED = -1;
	public final static int MESSAGE_STATE_SENDING = 0;
	public final static int MESSAGE_STATE_FAILD = -1;
	public final static int MESSAGE_STATE_SENED = 1;

	public final static int MESSAGESESSION_ID_UNDIFINED = -1;
} public class AppContext extends Application {
	private final String TAG = AppContext.class.getSimpleName();
	private static AppContext mInstance;
	private RequestQueuePool mRequestQueuePool;
	private RequestQueuePool mMulitiRequestQueuePool;

	@Override
	public void onCreate() {
		super.onCreate();
		mInstance = this;

		// 创建 请求队列池
		createRequestQueuePool();

		// debug
		if (Constant.DEBUG) {
			if (TextUtils.isEmpty(ConfigHelper.getInstance().loadLoginUserInfoConfig().getUserId())) {
				ConfigHelper.getInstance().saveLoginUserInfoConfig(new LoginUserInfo(Constant.DEBUG_USER_ID, Constant.DEBUG_USER_PWD));
			}
		}

		// 创建的时候自动登录
		LoginService.getInstance().autoLogin();
	}

	public static AppContext getInstance() {
		return mInstance;
	}

	/**
	 * 创建 请求队列管理池
	 */
	private void createRequestQueuePool() {
		mRequestQueuePool = new RequestQueuePool();
		// 创建多个 请求队列
		for (int i = 0; i < Constant.REQUESTQUEUE_HTTP_REQUEST_SIZE; i++) {
			RequestQueue queue = Volley.newRequestQueue(getApplicationContext(), new HurlStack());
			queue.start();
			mRequestQueuePool.put(queue);
		}
		mMulitiRequestQueuePool = new RequestQueuePool();
		for (int i = 0; i < Constant.REQUESTQUEUE_HTTP_MULITI_REQUEST_SIZE; i++) {
			RequestQueue queue = Volley.newRequestQueue(getApplicationContext(), new MultiPartStack());
			queue.start();
			mMulitiRequestQueuePool.put(queue);
		}
	}

	/**
	 * 获取一个请求队列管理池中的 RequestQueue
	 * 
	 * @return
	 */
	public RequestQueue getRequestQueue() {
		return getRequestQueue(false);
	}

	/**
	 * 获取一个 RequestQueue
	 * 
	 * @param isNew
	 *            时候新建一个新的RequestQueue， </br>true:新建一个新的RequestQueue,并启用
	 *            。但是不会加入到 请求队列管理池当中 </br>false:获取管理池中的一个 RequestQueue
	 * @return
	 */
	public RequestQueue getRequestQueue(boolean isNew) {
		if (isNew) {
			RequestQueue q = Volley.newRequestQueue(getApplicationContext());
			q.start();
			return q;
		} else {
			return mRequestQueuePool.getFreeRequestQueue();
		}
	}

	/**
	 * 获取一个请求队列管理池中的 RequestQueue
	 * 
	 * @return
	 */
	public RequestQueue getMulitiRequestQueue() {
		return getMulitiRequestQueue(false);
	}

	/**
	 * 获取一个 Muliti 类型的 RequestQueue
	 * 
	 * @param isNew
	 *            时候新建一个新的RequestQueue， </br>true:新建一个新的RequestQueue,并启用
	 *            。但是不会加入到 请求队列管理池当中 </br>false:获取管理池中的一个 RequestQueue
	 * @return
	 */
	public RequestQueue getMulitiRequestQueue(boolean isNew) {
		if (isNew) {
			RequestQueue q = Volley.newRequestQueue(getApplicationContext(), new MultiPartStack());
			q.start();
			return q;
		} else {
			return mMulitiRequestQueuePool.getFreeRequestQueue();
		}
	}
} public class HttpHelper {
	private final static String TAG = HttpHelper.class.getSimpleName();
	public static Gson gson = new Gson();

	public static String parserParameters(Map<String, String> params) {
		StringBuilder paramsStr = new StringBuilder();
		for (Map.Entry<String, String> entry : params.entrySet()) {
			paramsStr.append(entry.getKey());
			paramsStr.append('=');
			paramsStr.append(entry.getValue());
			paramsStr.append('&');
		}
		if (paramsStr.length() > 0) {
			paramsStr.deleteCharAt(paramsStr.length() - 1);
		}
		return paramsStr.toString();
	}

	public static Object getJsonObject(JSONObject json, Class clazz) {
		return gson.fromJson(json.toString(), clazz);
	}

	public static List getJsonArray(JSONArray json, TypeToken token) {
		return gson.fromJson(json.toString(), token.getType());
	}

	/**
	 * 获取 header 的中cookie
	 * 
	 * @param headers
	 * @return
	 */
	public static Map<String, String> getCookieMap(Map<String, String> headers) {
		final String cookieKey = "Set-Cookie";
		if (headers.containsKey(cookieKey)) {
			return parseCookieString(headers.get(cookieKey));

		} else {
			return new HashMap<String, String>();
		}

	}

	/**
	 * 解析header 特殊封装jsonArray格式的 cookie字符串
	 * 
	 * @param cookieString
	 * 
	 * @return
	 */
	public static Map<String, String> parseCookieString(String cookieJsonArrayStr) {
		JSONArray cookieJsonArray = new JSONArray();
		Map<String, String> cookieMap = new HashMap<String, String>();
		try {

			cookieJsonArray = new JSONArray(cookieJsonArrayStr);

			for (int i = 0; i < cookieJsonArray.length(); i++) {
				String cookieStr = cookieJsonArray.getString(i);
				String[] cookieStrs = cookieStr.split(";");
				for (int j = 0; j < cookieStrs.length; j++) {
					String[] onecookie = cookieStrs[j].split("=");
					cookieMap.put(onecookie[0], onecookie[1]);
				}
			}
		} catch (Exception e) {
			Log.e(TAG, "parseCookieString", e);
		}

		return cookieMap;
	}

	/**
	 * 根据一个map返回cookie字符串 </br>格式: a=b;c=d
	 * 
	 * @param cookieMap
	 * @return
	 */
	public static String converCookieToString(Map<String, String> cookieMap) {
		StringBuffer sb = new StringBuffer();
		for (String key : cookieMap.keySet()) {
			sb.append(key);
			sb.append("=");
			sb.append(cookieMap.get(key));
			sb.append(";");
		}
		return sb.toString();
	}

	/**
	 * 根据 cookie字符串 生成 一个map </br>格式: a=b;c=d
	 * 
	 * @param cookieMap
	 * @return
	 */
	public static Map<String, String> converCookieStringToMap(String cookieMapString) {

		if (TextUtils.isEmpty(cookieMapString)) {
			return new HashMap<String, String>();
		}

		Map<String, String> cookieMap = new HashMap<String, String>();
		String[] cookieStrs = cookieMapString.split(";");
		for (int i = 0; i < cookieStrs.length; i++) {
			try {
				String[] onecookie = cookieStrs[i].split("=");
				cookieMap.put(onecookie[0], onecookie[1]);
			} catch (Exception e) {
				Log.w("converCookieStringToMap", e.getMessage());
			}
		}

		return cookieMap;
	}
} public static class ArticleColumns {
	public static final String _ID = BaseColumns._ID;
	public static final String TITLE = "TITLE";
	public static final String DESCRIPTION = "DESCRIPTION";
	public static final String THUMBNAIL = "THUMBNAIL";
	public static final String CONTENT = "CONTENT";
	public static final String SUBMIT_DATE = "SUBMIT_DATE";
	public static final String GET_DATE = "GET_DATE";
	public static final String TYPE = "TYPE";
	public static final String URL = "URL";
} public class Article {
	private String id;
	private String title;
	private String description;
	private String thumbnail;
	private String content;
	private String submitDate;
	private String type;
	private String url;

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	public String getThumbnail() {
		return thumbnail;
	}

	public void setThumbnail(String thumbnail) {
		this.thumbnail = thumbnail;
	}

	public String getContent() {
		return content;
	}

	public void setContent(String content) {
		this.content = content;
	}

	public String getSubmitDate() {
		return submitDate;
	}

	public void setSubmitDate(String submitDate) {
		this.submitDate = submitDate;
	}

	public String getType() {
		return type;
	}

	public void setType(String type) {
		this.type = type;
	}

	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

} public class ArticleActivity extends BaseActivity {

	private final String BLANK_PAGE_URL = "file:///android_asset/none.html";

	public final static String KEY_URL = "KEY_URL";
	public final static String KEY_TITLE = "KEY_TITLE";
	public final static String KEY_CONTENT = "KEY_CONTENT";

	private WebView mWebView;
	private ProgressBar mProgressBar;
	private Topbar mTopbar;

	@Override
	protected void onCreate(Bundle arg0) {
		super.onCreate(arg0);
		setContentView(R.layout.activity_acticle);
		mTopbar = (Topbar) findViewById(R.id.topbar);
		mProgressBar = (ProgressBar) findViewById(R.id.web_progressbar);

		mWebView = (WebView) findViewById(R.id.webview);
		mWebView.setWebChromeClient(mWebChromeClient);
		configureWebSettings(mWebView.getSettings());

		handleIntent(getIntent());
	}

	@Override
	protected void onNewIntent(Intent intent) {
		super.onNewIntent(intent);
		handleIntent(intent);
	}

	public void handleIntent(Intent intent) {
		String title = intent.getStringExtra(KEY_TITLE);
		mTopbar.setTitle(title);

		String url = intent.getStringExtra(KEY_URL);
		if (TextUtils.isEmpty(url)) {
			url = BLANK_PAGE_URL;
		}
		mWebView.loadUrl(url);
	}

	@Override
	public void onResume() {
		super.onResume();
		mWebView.onResume();
	}

	@Override
	public void onPause() {
		mWebView.onPause();
		super.onPause();
	}

	private static void configureWebSettings(WebSettings settings) {
		settings.setJavaScriptEnabled(true);
	}

	/**
	 * This {@link WebChromeClient} has implementation for handling
	 * {@link PermissionRequest}.
	 */
	private WebChromeClient mWebChromeClient = new WebChromeClient() {

		@Override
		public void onProgressChanged(WebView view, int newProgress) {
			mProgressBar.setProgress(newProgress);
			if (newProgress >= 100) {
				mProgressBar.setVisibility(View.GONE);
			} else {
				mProgressBar.setVisibility(View.VISIBLE);
			}
			super.onProgressChanged(view, newProgress);
		}

	};
} public class JsonArrayRequest extends Request<JSONArray> {
	private Map<String, String> mParams;
	private Listener<JSONArray> mListener;

	public JsonArrayRequest(String url, Map<String, String> params, Listener<JSONArray> listener, ErrorListener errorListener) {
		super(Method.POST, url, errorListener);
		mListener = listener;
		mParams = params;
	}

	@Override
	protected Map<String, String> getParams() throws AuthFailureError {
		return mParams;
	}

	@Override
	protected Response<JSONArray> parseNetworkResponse(NetworkResponse response) {
		try {
			String jsonString = new String(response.data, HttpHeaderParser.parseCharset(response.headers));

			// 保存cookie
			ConfigHelper.getInstance().saveCookie(HttpHelper.getCookieMap(response.headers));

			return Response.success(new JSONArray(jsonString), HttpHeaderParser.parseCacheHeaders(response));
		} catch (UnsupportedEncodingException e) {
			return Response.error(new ParseError(e));
		} catch (JSONException je) {
			return Response.error(new ParseError(je));
		}
	}

	@Override
	protected void deliverResponse(JSONArray response) {
		mListener.onResponse(response);
	}

	@Override
	public Map<String, String> getHeaders() throws AuthFailureError {
		Map<String, String> headers = new HashMap<String, String>();
		String cookieStr = ConfigHelper.getInstance().getCookie();
		if (!TextUtils.isEmpty(cookieStr)) {
			headers.put("Cookie", cookieStr);
		}
		return headers;
	}
} public class LoadImageView extends ImageView {

	/** The URL of the network image to load */
	private String mUrl;

	/**
	 * Resource ID of the image to be used as a placeholder until the network
	 * image is loaded.
	 */
	protected int mDefaultImageId;

	/**
	 * Resource ID of the image to be used if the network response fails.
	 */
	protected int mErrorImageId;

	/** Local copy of the ImageLoader. */
	private ImageLoader mImageLoader;

	/** Current ImageContainer. (either in-flight or finished) */
	private ImageContainer mImageContainer;

	public LoadImageView(Context context) {
		super(context);
		init();
	}

	public LoadImageView(Context context, AttributeSet attrs) {
		super(context, attrs);
		init();
	}

	public LoadImageView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		init();
	}

	private void init() {
		mDefaultImageId = R.drawable.loading;
		mErrorImageId = R.drawable.image_error;
	}

	@Override
	public void setImageResource(int resId) {
		super.setImageResource(resId);
		if (R.drawable.loading == resId) {
			setScaleType(ScaleType.CENTER);
			((AnimationDrawable) getDrawable()).start();
		} else {
			setScaleType(ScaleType.CENTER_CROP);
		}
	}

	@Override
	public void setImageBitmap(Bitmap bm) {
		super.setImageBitmap(bm);
		setScaleType(ScaleType.CENTER_CROP);
	}

	/**
	 * Sets URL of the image that should be loaded into this view. Note that
	 * calling this will immediately either set the cached image (if available)
	 * or the default image specified by
	 * {@link NetworkImageView#setDefaultImageResId(int)} on the view.
	 *
	 * NOTE: If applicable, {@link NetworkImageView#setDefaultImageResId(int)}
	 * and {@link NetworkImageView#setErrorImageResId(int)} should be called
	 * prior to calling this function.
	 *
	 * 当url 与 imageLoader 与之前设置的一样的话就不回去更新
	 * 
	 * @param url
	 *            The URL that should be loaded into this ImageView.
	 * @param imageLoader
	 *            ImageLoader that will be used to make the request.
	 */
	public void setImageUrl(String url, ImageLoader imageLoader) {
		if (url == mUrl && imageLoader == mImageLoader) {
			return;
		}
		mUrl = url;
		mImageLoader = imageLoader;
		// The URL has potentially changed. See if we need to load it.
		loadImageIfNecessary(false);
	}

	/**
	 * Gets the URL of the image that should be loaded into this view, or null
	 * if no URL has been set. The image may or may not already be downloaded
	 * and set into the view.
	 * 
	 * @return the URL of the image to be set into the view, or null.
	 */
	public String getImageURL() {
		return mUrl;
	}

	/**
	 * Loads the image for the view if it isn't already loaded.
	 * 
	 * @param isInLayoutPass
	 *            True if this was invoked from a layout pass, false otherwise.
	 */
	void loadImageIfNecessary(final boolean isInLayoutPass) {
		int width = getWidth();
		int height = getHeight();
		ScaleType scaleType = getScaleType();

		boolean wrapWidth = false, wrapHeight = false;
		if (getLayoutParams() != null) {
			wrapWidth = getLayoutParams().width == LayoutParams.WRAP_CONTENT;
			wrapHeight = getLayoutParams().height == LayoutParams.WRAP_CONTENT;
		}

		// if the view's bounds aren't known yet, and this is not a
		// wrap-content/wrap-content
		// view, hold off on loading the image.
		boolean isFullyWrapContent = wrapWidth && wrapHeight;
		if (width == 0 && height == 0 && !isFullyWrapContent) {
			return;
		}

		// if the URL to be loaded in this view is empty, cancel any old
		// requests and clear the
		// currently loaded image.
		if (TextUtils.isEmpty(mUrl)) {
			if (mImageContainer != null) {
				mImageContainer.cancelRequest();
				mImageContainer = null;
			}
			setDefaultImageOrNull();
			return;
		}

		// if there was an old request in this view, check if it needs to be
		// canceled.
		if (mImageContainer != null && mImageContainer.getRequestUrl() != null) {
			if (mImageContainer.getRequestUrl().equals(mUrl)) {
				// if the request is from the same URL, return.
				return;
			} else {
				// if there is a pre-existing request, cancel it if it's
				// fetching a different URL.
				mImageContainer.cancelRequest();
				setDefaultImageOrNull();
			}
		}

		// Calculate the max image width / height to use while ignoring
		// WRAP_CONTENT dimens.
		int maxWidth = wrapWidth ? 0 : width;
		int maxHeight = wrapHeight ? 0 : height;

		// The pre-existing content of this view didn't match the current URL.
		// Load the new image
		// from the network.
		ImageContainer newContainer = mImageLoader.get(mUrl, new ImageListener() {
			@Override
			public void onErrorResponse(VolleyError error) {
				if (mErrorImageId != 0) {
					setImageResource(mErrorImageId);
				}
			}

			@Override
			public void onResponse(final ImageContainer response, boolean isImmediate) {
				// If this was an immediate response that was delivered
				// inside of a layout
				// pass do not set the image immediately as it will
				// trigger a requestLayout
				// inside of a layout. Instead, defer setting the image
				// by posting back to
				// the main thread.
				if (isImmediate && isInLayoutPass) {
					post(new Runnable() {
						@Override
						public void run() {
							onResponse(response, false);
						}
					});
					return;
				}

				if (response.getBitmap() != null) {
					setImageBitmap(response.getBitmap());
				} else if (mDefaultImageId != 0) {
					setImageResource(mDefaultImageId);
				}
			}
		}, maxWidth, maxHeight, scaleType);

		// update the ImageContainer to be the new bitmap container.
		mImageContainer = newContainer;
	}

	private void setDefaultImageOrNull() {
		if (mDefaultImageId != 0) {
			setImageResource(mDefaultImageId);
			((AnimationDrawable) getDrawable()).start();
		} else {
			setImageBitmap(null);
		}
	}

	@Override
	protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
		super.onLayout(changed, left, top, right, bottom);
		loadImageIfNecessary(true);
	}

	@Override
	protected void onDetachedFromWindow() {
		if (mImageContainer != null) {
			// If the view was bound to an image request, cancel it and clear
			// out the image from the view.
			mImageContainer.cancelRequest();
			setImageBitmap(null);
			// also clear out the container so we can reload the image if
			// necessary.
			mImageContainer = null;
		}
		super.onDetachedFromWindow();
	}

	@Override
	protected void drawableStateChanged() {
		super.drawableStateChanged();
		invalidate();
	}

} public class SlideViewPager extends ViewPager implements Runnable {

	private static final int POST_DELAYED_TIME = 1000 * 2;
	// 手指是否放在上面
	private boolean touching;
	// 滚动处理时间
	private long pageHandlerTime = 0;

	public SlideViewPager(Context context, AttributeSet attrs) {
		super(context, attrs);
		postDelayed(this, POST_DELAYED_TIME);
	}

	@Override
	// 自动滚动关键
	public void run() {
		long currentTime = System.currentTimeMillis();
		if (getAdapter() != null && getAdapter().getCount() > 1 && !touching && (currentTime - pageHandlerTime >= POST_DELAYED_TIME)) {
			int nextItem = getCurrentItem() + 1;
			nextItem = nextItem >= getAdapter().getCount() ? 0 : nextItem;
			setCurrentItem(nextItem, true);
			pageHandlerTime = System.currentTimeMillis();
		}
		postDelayed(this, POST_DELAYED_TIME);
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		pageHandlerTime = System.currentTimeMillis();
		if (event.getAction() == MotionEvent.ACTION_DOWN) {
			this.touching = true;
		} else if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL) {
			this.touching = false;
		}

		return super.onTouchEvent(event);
	}
} public class Slider {
	private Context mContext;
	private SlideViewPager mViewPager;
	private PageIndicator mPageIndicator;

	List<PagerEntry> mEntrys = new ArrayList<PagerEntry>();
	private ImageLoader mImageLoader;
	private CursorLoader mCursorLoader;

	private LoaderManager mLoaderManager;
	private PaperEntryConverter mPaperEntryConverter;
	private SliderAdapter mSliderAdapter;

	/**
	 * 
	 * @param context
	 * @param slideViewPager
	 * @param pageIndicator
	 * @param loaderManager
	 *            * @param cursorloader 用来读取数据的 cursorLoader
	 * @param paperEntryConverter
	 *            吧Cusror 中的字段 转换成PaderEntry
	 */
	public Slider(Context context, SlideViewPager slideViewPager, PageIndicator pageIndicator) {
		super();
		mContext = context;
		mViewPager = slideViewPager;
		mPageIndicator = pageIndicator;
	}

	public void load(LoaderManager loaderManager, CursorLoader cursorloader, PaperEntryConverter paperEntryConverter) {
		mLoaderManager = loaderManager;
		mPaperEntryConverter = paperEntryConverter;
		mCursorLoader = cursorloader;

		// image cache loader
		RequestQueue queue = AppContext.getInstance().getRequestQueue();
		mImageLoader = new ImageLoader(queue, BitmapCache.getInstance());

		// 设置幻灯片绑定
		mSliderAdapter = new SliderAdapter();
		mViewPager.setAdapter(mSliderAdapter);
		mPageIndicator.setViewPager(mViewPager);

		mLoaderManager.initLoader(mCursorLoader.hashCode(), null, new LoaderCallback());

	}

	public interface PaperEntryConverter {
		public PagerEntry convert(Cursor cursor);
	}

	private class LoaderCallback implements LoaderManager.LoaderCallbacks<Cursor> {

		@Override
		public Loader<Cursor> onCreateLoader(int arg0, Bundle arg1) {
			return mCursorLoader;
		}

		@Override
		public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
			mEntrys.clear();
			if (cursor != null) {
				while (cursor.moveToNext()) {
					mEntrys.add(mPaperEntryConverter.convert(cursor));
				}
			}
			mSliderAdapter.notifyDataSetChanged();
		}

		@Override
		public void onLoaderReset(Loader<Cursor> arg0) {
			mEntrys.clear();
			mSliderAdapter.notifyDataSetChanged();
		}

	}

	private class SliderAdapter extends PagerAdapter {

		@Override
		public int getCount() {
			return mEntrys.size();
		}

		@Override
		public boolean isViewFromObject(View view, Object pager) {
			return view == pager;
		}

		@Override
		public void destroyItem(ViewGroup container, int position, Object pager) {
			container.removeView((View) pager);
		}

		@Override
		public Object instantiateItem(ViewGroup container, int position) {
			final PagerEntry entry = mEntrys.get(position);
			SilderPage pager = new SilderPage(container.getContext(), mImageLoader, entry);
			container.addView(pager);
			return pager;
		}

	}

	public static class PagerEntry {
		public String title;
		public String pic;
		public Intent intent;
	}
} public static class PagerEntry {
	public String title;
	public String pic;
	public Intent intent;
} public interface PaperEntryConverter {
	public PagerEntry convert(Cursor cursor);
} public class BitmapCache implements ImageCache {
	private final static String TAG = BitmapCache.class.getSimpleName();

	private final static int APP_VERSION = 1;// 这里长期使用同一个缓存，所以这里版本号不变
	private final static String DEFAULT_CACHE_DIR = "Image";
	private final static int DISK_CACHE_SIZE = 1024 * 1024 * 100; // 100MB
	private final static int MEMORY_CACHE_SIZE = 1024 * 1024 * 20; // 20MB

	private static BitmapCache mInstance;
	private DiskLruCache cacheL2;
	private LruCache<String, Bitmap> cacheL1;

	/**
	 * 处理保存用的线程池
	 */
	private ExecutorService mThreadPool = Executors.newSingleThreadExecutor();

	public static BitmapCache getInstance() {
		if (mInstance == null) {
			mInstance = new BitmapCache();
		}
		return mInstance;
	}

	private BitmapCache() {
		cacheL1 = new LruCache<String, Bitmap>(MEMORY_CACHE_SIZE);
		File cacheDir = new File(AppContext.getInstance().getCacheDir(), DEFAULT_CACHE_DIR);
		try {
			cacheL2 = DiskLruCache.open(cacheDir, APP_VERSION, 1, DISK_CACHE_SIZE);
		} catch (IOException e) {
			Log.e(TAG, "openCache", e);
		}
	}

	@Override
	public Bitmap getBitmap(String url) {
		Bitmap b = cacheL1.get(url);
		if (b == null) {
			b = getDataFromCacheL2(url);
		}
		return b;
	}

	@Override
	public void putBitmap(final String url, final Bitmap bitmap) {
		mThreadPool.execute(new Runnable() {
			@Override
			public void run() {
				cacheL1.put(url, bitmap);
				saveDataToCacheL2(url, bitmap);
			}
		});
	}

	/**
	 * 保存的磁盘
	 * 
	 * @param key
	 * @param bitmap
	 */
	private void saveDataToCacheL2(String key, Bitmap bitmap) {
		try {
			String pKey = StringHelper.MD5Encode(key);
			DiskLruCache.Editor editor = cacheL2.edit(pKey);
			if (editor != null) {
				OutputStream outputStream = editor.newOutputStream(0);
				boolean isSuccessfull = true;
				try {
					bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
				} catch (Exception e) {
					isSuccessfull = false;
				}
				if (isSuccessfull) {
					editor.commit();
				} else {
					editor.abort();
				}
				cacheL2.flush();
			}
		} catch (Exception e) {
			Log.w(TAG, "saveDataToCacheL2");
		}

	}

	// 从DiskLruCache中读取数据
	private Bitmap getDataFromCacheL2(String key) {
		Bitmap bitmap = null;
		try {
			String pKey = StringHelper.MD5Encode(key);
			// 第二步:依据key获取到其对应的snapshot
			DiskLruCache.Snapshot snapshot = cacheL2.get(pKey);
			if (snapshot != null) {
				// 第三步:从snapshot中获取到InputStream
				InputStream inputStream = snapshot.getInputStream(0);
				bitmap = BitmapFactory.decodeStream(inputStream);
			}
		} catch (Exception e) {
			Log.w(TAG, "getDataFroCacheL2");
		}
		return bitmap;

	}

	/**
	 * 清除磁盘缓存
	 * 
	 * @throws IOException
	 */
	public void cleanCacheL2() throws IOException {
		cacheL2.delete();
	}
}
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.json.JSONArray;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.Response.Listener;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.ImageLoader;
import com.google.gson.reflect.TypeToken;
import com.lingganhezi.myapp.ArticleProvider;
import com.lingganhezi.myapp.Constant;
import com.lingganhezi.myapp.AppContext;
import com.lingganhezi.myapp.HttpHelper;
import com.lingganhezi.myapp.R;
import com.lingganhezi.myapp.ArticleProvider.ArticleColumns;
import com.lingganhezi.myapp.entity.Article;
import com.lingganhezi.myapp.ui.activity.ArticleActivity;
import com.lingganhezi.net.JsonArrayRequest;
import com.lingganhezi.ui.widget.LoadImageView;
import com.lingganhezi.ui.widget.SlideViewPager;
import com.lingganhezi.ui.widget.Slider;
import com.lingganhezi.ui.widget.Slider.PagerEntry;
import com.lingganhezi.ui.widget.Slider.PaperEntryConverter;
import com.lingganhezi.utils.BitmapCache;
import com.viewpagerindicator.CirclePageIndicator;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v4.widget.CursorAdapter;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v4.widget.SwipeRefreshLayout.OnRefreshListener;
package com.lingganhezi.myapp.ui.fragment;





/**
 * 使用官方下拉更新组件
 * 
 * @author chenzipeng
 *
 */
@Deprecated
public class ArticlesFragmentOld extends BaseFragment {
	private String TAG = ArticlesFragmentOld.class.getSimpleName();

	RequestQueue mVolleyRequesttQueue;

	// view
	private SwipeRefreshLayout mSwipeArticles;
	private ListView mListViewArticles;

	private final String mGetArticleUrl = "http://192.168.112.126:8080/a/articles.json";

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
		View rootView = inflater.inflate(R.layout.fragment_articles_old, container, false);

		mSwipeArticles = (SwipeRefreshLayout) rootView.findViewById(R.id.swipe_articles);
		mListViewArticles = (ListView) rootView.findViewById(R.id.listview_articles);

		SlideViewPager viewPagerSpecial = (SlideViewPager) rootView.findViewById(R.id.viewPager_special);
		CirclePageIndicator pageIndicatorSpecial = (CirclePageIndicator) rootView.findViewById(R.id.viewPagerIndicator_special);

		// 设置 幻灯片
		Slider slider = new Slider(getActivity(), viewPagerSpecial, pageIndicatorSpecial);
		slider.load(getLoaderManager(), new CursorLoader(getActivity(), Constant.CONTENT_URI_ARTICLE_PROVIDER, null, null, null, null),
				new PaperEntryConverter() {

					@Override
					public PagerEntry convert(Cursor cursor) {
						PagerEntry entry = new PagerEntry();
						entry.title = cursor.getString(cursor.getColumnIndex(ArticleColumns.TITLE));
						entry.pic = cursor.getString(cursor.getColumnIndex(ArticleColumns.THUMBNAIL));
						entry.intent = createIntent(cursor);
						return entry;
					}

					private Intent createIntent(Cursor cursor) {
						Intent intent = new Intent(getActivity(), ArticleActivity.class);
						intent.putExtra(ArticleActivity.KEY_TITLE, cursor.getString(cursor.getColumnIndex(ArticleColumns.TITLE)));
						intent.putExtra(ArticleActivity.KEY_TITLE, cursor.getString(cursor.getColumnIndex(ArticleColumns.CONTENT)));
						return intent;
					}
				});

		// 设置下拉更新绑定
		mSwipeArticles.setOnRefreshListener(mArticlesOnRefreshListenner);

		// mSwipeLayout.setColorScheme(android.R.color.holo_blue_bright,
		// android.R.color.holo_green_light,
		// android.R.color.holo_orange_light,
		// android.R.color.holo_red_light);

		mAdapter = new ArticleAdapter(getActivity());

		mListViewArticles.setAdapter(mAdapter);

		// 加载数据库中的文章
		getLoaderManager().initLoader(0, null, mArticleLoaderListener);

		// 启动访问队列
		mVolleyRequesttQueue = AppContext.getInstance().getRequestQueue();

		return rootView;
	}

	private static final int REFRESH_COMPLETE = 0;
	private static final int REFRESH_ERROR = 1;
	private ArticleAdapter mAdapter;

	private class ArticleAdapter extends CursorAdapter {

		ImageLoader mImageLoader;

		public ArticleAdapter(Context context) {
			super(context, null, true);
			RequestQueue queue = AppContext.getInstance().getRequestQueue();
			mImageLoader = new ImageLoader(queue, BitmapCache.getInstance());
		}

		@Override
		public void bindView(View view, Context context, Cursor cursor) {
			Article entry = getEntry(cursor);
			view.setTag(entry);
			((TextView) view.findViewById(R.id.text_title)).setText(entry.getTitle());
			((TextView) view.findViewById(R.id.text_description)).setText(entry.getDescription());
			LoadImageView loadImageView = (LoadImageView) view.findViewById(R.id.image_thumbnail);
			loadImageView.setImageUrl(entry.getThumbnail(), mImageLoader);
		}

		@Override
		public View newView(Context context, Cursor cursor, ViewGroup parent) {
			return ((LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE))
					.inflate(R.layout.item_articlelistview, null);
		}

		private Article getEntry(Cursor cursor) {
			String id = cursor.getString(cursor.getColumnIndex(ArticleColumns._ID));
			String title = cursor.getString(cursor.getColumnIndex(ArticleColumns.TITLE));
			String description = cursor.getString(cursor.getColumnIndex(ArticleColumns.DESCRIPTION));
			String thumbnail = cursor.getString(cursor.getColumnIndex(ArticleColumns.THUMBNAIL));
			String content = cursor.getString(cursor.getColumnIndex(ArticleColumns.CONTENT));
			String submitDate = cursor.getString(cursor.getColumnIndex(ArticleColumns.SUBMIT_DATE));
			String type = cursor.getString(cursor.getColumnIndex(ArticleColumns.TYPE));
			Article article = new Article();
			article.setId(id);
			article.setTitle(title);
			article.setDescription(description);
			article.setThumbnail(thumbnail);
			article.setContent(content);
			article.setSubmitDate(submitDate);
			article.setType(type);
			return article;
		}

	}

	private LoaderCallbacks<Cursor> mArticleLoaderListener = new LoaderCallbacks<Cursor>() {

		@Override
		public Loader<Cursor> onCreateLoader(int arg0, Bundle arg1) {
			Context context = getActivity();
			int limit = 20;
			return new CursorLoader(context, Constant.CONTENT_URI_ARTICLE_PROVIDER, null, null, null, ArticleProvider.ArticleColumns._ID