Android 在onPostExecute中关闭光标不会显示任何内容
我使用AsyncTask从SQLite数据库加载数据,然后使用交错布局管理器和CustomListAdapter将数据提供给回收器视图 如果我在onPostExecuteMethod中不关闭doInBackground方法的游标,那么从上一个活动的转换是滞后的,android logcat说“跳过了52帧” 如果在Post Execute方法的末尾关闭游标,则不会出现延迟,但在活动内部不会呈现任何内容。(回收器视图不渲染任何内容。) 多因背景法 BaseAdapter类Android 在onPostExecute中关闭光标不会显示任何内容,android,sqlite,android-layout,android-recyclerview,Android,Sqlite,Android Layout,Android Recyclerview,我使用AsyncTask从SQLite数据库加载数据,然后使用交错布局管理器和CustomListAdapter将数据提供给回收器视图 如果我在onPostExecuteMethod中不关闭doInBackground方法的游标,那么从上一个活动的转换是滞后的,android logcat说“跳过了52帧” 如果在Post Execute方法的末尾关闭游标,则不会出现延迟,但在活动内部不会呈现任何内容。(回收器视图不渲染任何内容。) 多因背景法 BaseAdapter类 导入android.co
导入android.content.Context;
导入android.database.Cursor;
导入android.database.DataSetObserver;
导入android.support.v7.widget.RecyclerView;
公共抽象类CursorRecyclServiceAdapter扩展了RecyclerView.Adapter{
私有上下文;
私有游标mCursor;
私有布尔mDataValid;
私有int-mRowIdColumn;
私有DataSetObserver mDataSetObserver;
公共游标RecyclServiceAdapter(上下文上下文,游标游标){
mContext=上下文;
mCursor=光标;
mDataValid=cursor!=null;
mRowIdColumn=mDataValid?mCursor.getColumnIndex(“\u id”):-1;
mDataSetObserver=new NotifyingDataSetObserver();
if(mCursor!=null){
mCursor.registerDataSetObserver(mDataSetObserver);
}
}
公共游标getCursor(){
返回mCursor;
}
@凌驾
public int getItemCount(){
if(mDataValid&&mCursor!=null){
返回mCursor.getCount();
}
返回0;
}
@凌驾
公共长getItemId(int位置){
if(mDataValid&&mCursor!=null&&mCursor.moveToPosition(位置)){
返回mCursor.getLong(mRowIdColumn);
}
返回0;
}
@凌驾
公共void setHassTableId(布尔HassTableId){
super.sethasstableId(true);
}
BindViewHolder上的公共摘要无效(VH viewHolder,光标);
@凌驾
公共无效onBindViewHolder(VH viewHolder,内部位置){
如果(!mDataValid){
抛出新的IllegalStateException(“仅当光标有效时才应调用它”);
}
如果(!mCursor.moveToPosition(位置)){
抛出新的IllegalStateException(“无法将光标移动到位置”+位置);
}
onBindViewHolder(viewHolder,mCursor);
}
/**
*将基础游标更改为新游标。如果存在现有游标,则它将
*关闭。
*/
公共void changeCursor(游标){
游标old=swapCursor(游标);
如果(旧!=null){
old.close();
}
}
/**
*交换新光标,返回旧光标。与
*{@link#changeCursor(Cursor)},返回的旧游标不是
*关闭。
*/
公共游标交换游标(游标新建游标){
if(newCursor==mCursor){
返回null;
}
最终光标oldCursor=mCursor;
if(oldCursor!=null&&mDataSetObserver!=null){
注销DataSetoObserver(mDataSetObserver);
}
mCursor=newCursor;
if(mCursor!=null){
if(mDataSetObserver!=null){
mCursor.registerDataSetObserver(mDataSetObserver);
}
mRowIdColumn=newCursor.getColumnIndexOrThrow(“\u id”);
mDataValid=true;
notifyDataSetChanged();
}否则{
mRowIdColumn=-1;
mDataValid=false;
notifyDataSetChanged();
//RecyclerView.Adapter中没有NotifyDataSetionValidated()方法
}
返回光标;
}
私有类NotifyingDataSetObserver扩展DataSetObserver{
@凌驾
更改后的公共无效(){
super.onChanged();
mDataValid=true;
notifyDataSetChanged();
}
@凌驾
未验证的公共无效(){
super.onInvalidated();
mDataValid=false;
notifyDataSetChanged();
//RecyclerView.Adapter中没有NotifyDataSetionValidated()方法
}
}
}
扩展适配器类
导入android.content.Context;
导入android.content.Intent;
导入android.content.res.Resources;
导入android.database.Cursor;
导入android.graphics.Bitmap;
导入android.graphics.BitmapFactory;
导入android.graphics.Typeface;
导入android.os.AsyncTask;
导入android.support.v7.widget.CardView;
导入android.support.v7.widget.RecyclerView;
导入android.util.DisplayMetrics;
导入android.util.Log;
导入android.view.Display;
导入android.view.LayoutInflater;
导入android.view.view;
导入android.view.ViewGroup;
导入android.view.WindowManager;
导入android.widget.Button;
导入android.widget.LinearLayout;
导入android.widget.TextView;
公共类MyListCursorAdapter扩展了CursorRecyclServiceAdapter{
私有静态最终字符串TAG=“MyListCursorAdapter”;
公共MyListCursorAdapter(上下文,光标){
超级(上下文、游标);
}
@凌驾
public ViewHolder onCreateViewHolder(视图组父级,int-viewType){
View itemView=LayoutInflater.from(parent.getContext())
.充气(R.layout.productList,父项,false);
ViewHolder vh=新的ViewHolder(项目视图);
返回vh;
}
@凌驾
公共无效onBindViewHolder(最终视图持有人、最终光标){
Book myListItem=Book.fromCursor(光标);
viewHolder.titleTextView.setText(myListItem.getTitle());
viewHolder.shippingTextView.setText(myListItem.getAShipping());
d(标记“onBindViewHolder:+viewHolder.isRecyclable());
}
公共静态类ViewHolder扩展了RecyclerView.ViewHolder{
公共文本视图shippingTextView;
公共文本视图
@Override
protected void onPostExecute(Void Void) {
c.close();
swipeRefreshLayout.setRefreshing(false);
swipeRefreshLayout.setOnRefreshListener(
new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
new MyTask().execute();
}
});
swipeRefreshLayout.setColorSchemeColors(getResources().getIntArray(R.array.swipeRefreshColors));
}
try {
myDb = new SavedData(getApplicationContext());
writeableDatabase = myDb.getReadableDatabase();
final String[] projection = {SavedData.COLUMN_NAME_ENTRY_ID,
SavedData.COLUMN_NAME_PRICE,
SavedData.COLUMN_NAME_SHIPPING,
SavedData.COLUMN_NAME_WEIGHT,
SavedData.COLUMN_NAME_PRODUCT};
sortOrder = BookSave.COLUMN_NAME_ENTRY_ID + " DESC";
c = writeableDatabase.query(
SavedData.TABLE_NAME,
projection,
null,
null,
null,
null,
sortOrder
);
m = new MyListCursorAdapter(getApplicationContext(), c);
gaggeredGridLayoutManager = new StaggeredGridLayoutManager(NUM, 1);
} catch (Exception e) {
e.printStackTrace();
} finally {
}
import android.content.Context;
import android.database.Cursor;
import android.database.DataSetObserver;
import android.support.v7.widget.RecyclerView;
public abstract class CursorRecyclerViewAdapter<VH extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<VH> {
private Context mContext;
private Cursor mCursor;
private boolean mDataValid;
private int mRowIdColumn;
private DataSetObserver mDataSetObserver;
public CursorRecyclerViewAdapter(Context context, Cursor cursor) {
mContext = context;
mCursor = cursor;
mDataValid = cursor != null;
mRowIdColumn = mDataValid ? mCursor.getColumnIndex("_id") : -1;
mDataSetObserver = new NotifyingDataSetObserver();
if (mCursor != null) {
mCursor.registerDataSetObserver(mDataSetObserver);
}
}
public Cursor getCursor() {
return mCursor;
}
@Override
public int getItemCount() {
if (mDataValid && mCursor != null) {
return mCursor.getCount();
}
return 0;
}
@Override
public long getItemId(int position) {
if (mDataValid && mCursor != null && mCursor.moveToPosition(position)) {
return mCursor.getLong(mRowIdColumn);
}
return 0;
}
@Override
public void setHasStableIds(boolean hasStableIds) {
super.setHasStableIds(true);
}
public abstract void onBindViewHolder(VH viewHolder, Cursor cursor);
@Override
public void onBindViewHolder(VH viewHolder, int position) {
if (!mDataValid) {
throw new IllegalStateException("this should only be called when the cursor is valid");
}
if (!mCursor.moveToPosition(position)) {
throw new IllegalStateException("couldn't move cursor to position " + position);
}
onBindViewHolder(viewHolder, mCursor);
}
/**
* Change the underlying cursor to a new cursor. If there is an existing cursor it will be
* closed.
*/
public void changeCursor(Cursor cursor) {
Cursor old = swapCursor(cursor);
if (old != null) {
old.close();
}
}
/**
* Swap in a new Cursor, returning the old Cursor. Unlike
* {@link #changeCursor(Cursor)}, the returned old Cursor is <em>not</em>
* closed.
*/
public Cursor swapCursor(Cursor newCursor) {
if (newCursor == mCursor) {
return null;
}
final Cursor oldCursor = mCursor;
if (oldCursor != null && mDataSetObserver != null) {
oldCursor.unregisterDataSetObserver(mDataSetObserver);
}
mCursor = newCursor;
if (mCursor != null) {
if (mDataSetObserver != null) {
mCursor.registerDataSetObserver(mDataSetObserver);
}
mRowIdColumn = newCursor.getColumnIndexOrThrow("_id");
mDataValid = true;
notifyDataSetChanged();
} else {
mRowIdColumn = -1;
mDataValid = false;
notifyDataSetChanged();
//There is no notifyDataSetInvalidated() method in RecyclerView.Adapter
}
return oldCursor;
}
private class NotifyingDataSetObserver extends DataSetObserver {
@Override
public void onChanged() {
super.onChanged();
mDataValid = true;
notifyDataSetChanged();
}
@Override
public void onInvalidated() {
super.onInvalidated();
mDataValid = false;
notifyDataSetChanged();
//There is no notifyDataSetInvalidated() method in RecyclerView.Adapter
}
}
}
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Typeface;
import android.os.AsyncTask;
import android.support.v7.widget.CardView;
import android.support.v7.widget.RecyclerView;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
public class MyListCursorAdapter extends CursorRecyclerViewAdapter<MyListCursorAdapter.ViewHolder> {
private static final String TAG = "MyListCursorAdapter";
public MyListCursorAdapter(Context context, Cursor cursor) {
super(context, cursor);
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.productList, parent, false);
ViewHolder vh = new ViewHolder(itemView);
return vh;
}
@Override
public void onBindViewHolder(final ViewHolder viewHolder, final Cursor cursor) {
Book myListItem = Book.fromCursor(cursor);
viewHolder.titleTextView.setText(myListItem.getTitle());
viewHolder.shippingTextView.setText(myListItem.getAShipping());
Log.d(TAG, "onBindViewHolder: "+viewHolder.isRecyclable());
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView shippingTextView;
public TextView titleTextView;
public LinearLayout insideCard;
public Button payButton;
public View seperator;
public CardView cv;
public View view;
public ViewHolder(final View view) {
super(view);
WindowManager wm = (WindowManager) view.getContext().getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
DisplayMetrics DM = new DisplayMetrics();
display.getMetrics(DM);
payButton = (Button) view.findViewById(R.id.readButton);
seperator = view.findViewById(R.id.separator);
titleTextView = (TextView) view.findViewById(R.id.titleTextView);
insideCard = (LinearLayout) view.findViewById(R.id.insideCard);
insideCard.getLayoutParams().width = (DM.widthPixels / 2) - 24;
shippingTextView = (TextView) view.findViewById(R.id.shippingTextView);
//typeface
Typeface light = Typeface.createFromAsset(titleTextView.getResources().getAssets(), "fonts/light.ttf");
titleTextView.setTypeface(light);
Typeface regular = Typeface.createFromAsset(authorTextView.getResources().getAssets(), "fonts/thinItalic.ttf");
shippingTextView.setTypeface(regular);
payButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent goToCheckout = new Intent(view.getContext(), ShowReader.class);
goToCheckout.putExtra("PRODUCT_NAME", titleTextView.getText());
view.getContext().startActivity(goToCheckout);
}
});
setWidth((DM.widthPixels / 2) - 24);
}
public void setWidth(int a) {
a = a - 8 * 4;
payButton.getLayoutParams().width = a;
seperator.getLayoutParams().width = a;
}
}
}
//typeface
Typeface light = Typeface.createFromAsset(titleTextView.getResources().getAssets(), "fonts/light.ttf");
titleTextView.setTypeface(light);
Typeface regular = Typeface.createFromAsset(authorTextView.getResources().getAssets(), "fonts/thinItalic.ttf");
shippingTextView.setTypeface(regular);
public class MyFontProvider {
private static final String TAG = MyFontProvider.class.getSimpleName();
private Map<String, Typeface> mCache;
private static volatile MyFontProvider sInstance;
public static MyFontProvider getInstance() {
if (sInstance == null) {
synchronized (MyFontProvider.class) {
if (sInstance == null) {
sInstance = new MyFontProvider();
}
}
}
return sInstance;
}
private MyFontProvider() {
mCache = new Hashtable<>();
}
public synchronized Typeface getFont(String assetPath, Context context) {
if (!mCache.containsKey(assetPath)) {
try {
Typeface t = Typeface.createFromAsset(context.getAssets(), assetPath);
mCache.put(assetPath, t);
} catch (Exception e) {
Log.e(TAG, "Error getting typeface (" + assetPath + " ) " + e.getMessage());
return null;
}
}
return mCache.get(assetPath);
}
}
//typeface
Typeface light = Typeface.createFromAsset(titleTextView.getResources().getAssets(), "fonts/light.ttf");
titleTextView.setTypeface(light);
Typeface regular = Typeface.createFromAsset(authorTextView.getResources().getAssets(), "fonts/thinItalic.ttf");
shippingTextView.setTypeface(regular);
//typeface
titleTextView.setTypeface(MyFontProvider.getInstance().getFont("fonts/light.ttf",this));
shippingTextView.setTypeface(MyFontProvider.getInstance().getFont("fonts/thinItalic.ttf",this));