diff options
| author | John Reck <jreck@google.com> | 2011-10-10 15:33:48 -0700 |
|---|---|---|
| committer | John Reck <jreck@google.com> | 2012-04-18 14:29:03 -0700 |
| commit | f94abcf44fc1611f76e55461f48220e621fc31b7 (patch) | |
| tree | 678fab453c53611388e27cde68371192e194082f /src/com/android/browser/util/ThreadedCursorAdapter.java | |
| parent | f1286a455eeacd02dfcca1335e6a7a9f87433c1b (diff) | |
Load bookmarks asynchronously
Bug: 5297900
Change-Id: I8b728cfe06799099e21c402d5da7087507209ffa
Diffstat (limited to 'src/com/android/browser/util/ThreadedCursorAdapter.java')
| -rw-r--r-- | src/com/android/browser/util/ThreadedCursorAdapter.java | 193 |
1 files changed, 193 insertions, 0 deletions
diff --git a/src/com/android/browser/util/ThreadedCursorAdapter.java b/src/com/android/browser/util/ThreadedCursorAdapter.java new file mode 100644 index 00000000..fe59ad1c --- /dev/null +++ b/src/com/android/browser/util/ThreadedCursorAdapter.java @@ -0,0 +1,193 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.browser.util; + +import android.content.Context; +import android.database.Cursor; +import android.os.Handler; +import android.os.HandlerThread; +import android.os.Message; +import android.os.Process; +import android.util.Log; +import android.util.SparseArray; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Adapter; +import android.widget.BaseAdapter; +import android.widget.CursorAdapter; + +import com.android.browser.R; + +import java.lang.ref.WeakReference; +import java.util.HashMap; + +public abstract class ThreadedCursorAdapter<T> extends BaseAdapter { + + private static final String LOGTAG = "tca"; + private static final boolean DEBUG = false; + + private Context mContext; + private Object mCursorLock = new Object(); + private CursorAdapter mCursorAdapter; + private T mLoadingObject; + private Handler mLoadHandler; + private Handler mHandler; + private int mSize; + + private class LoadContainer { + WeakReference<View> view; + int position; + T bind_object; + Adapter owner; + boolean loaded; + } + + public ThreadedCursorAdapter(Context context, Cursor c) { + mContext = context; + mCursorAdapter = new CursorAdapter(context, c, 0) { + + @Override + public View newView(Context context, Cursor cursor, ViewGroup parent) { + throw new IllegalStateException("not supported"); + } + + @Override + public void bindView(View view, Context context, Cursor cursor) { + throw new IllegalStateException("not supported"); + } + + @Override + public void notifyDataSetChanged() { + super.notifyDataSetChanged(); + mSize = getCount(); + ThreadedCursorAdapter.this.notifyDataSetChanged(); + } + + @Override + public void notifyDataSetInvalidated() { + super.notifyDataSetInvalidated(); + mSize = getCount(); + ThreadedCursorAdapter.this.notifyDataSetInvalidated(); + } + + }; + mSize = mCursorAdapter.getCount(); + HandlerThread thread = new HandlerThread("threaded_adapter_" + this, + Process.THREAD_PRIORITY_BACKGROUND); + thread.start(); + mLoadHandler = new Handler(thread.getLooper()) { + @SuppressWarnings("unchecked") + @Override + public void handleMessage(Message msg) { + if (DEBUG) { + Log.d(LOGTAG, "loading: " + msg.what); + } + loadRowObject(msg.what, (LoadContainer) msg.obj); + } + }; + mHandler = new Handler() { + @Override + public void handleMessage(Message msg) { + @SuppressWarnings("unchecked") + LoadContainer container = (LoadContainer) msg.obj; + if (container == null) { + return; + } + View view = container.view.get(); + if (view == null + || container.owner != ThreadedCursorAdapter.this + || container.position != msg.what) { + return; + } + container.loaded = true; + bindView(view, container.bind_object); + } + }; + } + + @Override + public int getCount() { + return mSize; + } + + @Override + public Cursor getItem(int position) { + return (Cursor) mCursorAdapter.getItem(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + private void loadRowObject(int position, LoadContainer container) { + if (container == null + || container.position != position + || container.owner != ThreadedCursorAdapter.this + || container.view.get() == null) { + return; + } + synchronized (mCursorLock) { + Cursor c = (Cursor) mCursorAdapter.getItem(position); + container.bind_object = getRowObject(c, container.bind_object); + } + mHandler.obtainMessage(position, container).sendToTarget(); + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + if (convertView == null) { + convertView = newView(mContext, parent); + } + @SuppressWarnings("unchecked") + LoadContainer container = (LoadContainer) convertView.getTag(R.id.load_object); + if (container == null) { + container = new LoadContainer(); + container.view = new WeakReference<View>(convertView); + convertView.setTag(R.id.load_object, container); + } + if (container.position == position + && container.owner == this + && container.loaded) { + bindView(convertView, container.bind_object); + } else { + bindView(convertView, cachedLoadObject()); + container.position = position; + container.loaded = false; + container.owner = this; + mLoadHandler.obtainMessage(position, container).sendToTarget(); + } + return convertView; + } + + private T cachedLoadObject() { + if (mLoadingObject == null) { + mLoadingObject = getLoadingObject(); + } + return mLoadingObject; + } + + public void changeCursor(Cursor cursor) { + synchronized (mCursorLock) { + mCursorAdapter.changeCursor(cursor); + } + } + + public abstract View newView(Context context, ViewGroup parent); + public abstract void bindView(View view, T object); + public abstract T getRowObject(Cursor c, T recycleObject); + public abstract T getLoadingObject(); +}
\ No newline at end of file |
