package org.softeg.slartus.forpdaplus.listfragments; import android.database.sqlite.SQLiteDatabase; import android.os.AsyncTask; import android.os.Bundle; import android.widget.Filterable; import android.widget.Toast; import org.softeg.slartus.forpdaapi.IListItem; import org.softeg.slartus.forpdaplus.App; import org.softeg.slartus.forpdaplus.Client; import org.softeg.slartus.forpdaplus.R; import org.softeg.slartus.forpdaplus.common.AppLog; import org.softeg.slartus.forpdaplus.db.CacheDbHelper; import org.softeg.slartus.forpdaplus.prefs.Preferences; import org.softeg.sqliteannotations.BaseDao; import java.io.IOException; import java.util.ArrayList; /** * Created by slartus on 19.02.14. */ public abstract class BaseTaskListFragment extends BaseListFragment { protected ArrayList<? extends IListItem> mLoadResultList; protected ArrayList<IListItem> mCacheList = new ArrayList<>(); public BaseTaskListFragment() { super(); } public void filter(CharSequence text) { if (getAdapter() instanceof Filterable) { ((Filterable) getAdapter()).getFilter().filter(text); } } public void loadCache() throws IOException, IllegalAccessException, NoSuchFieldException, java.lang.InstantiationException { } public void saveCache() throws Exception { } protected <T> void updateItemCache(final T item, final Class<T> tClass, Boolean newThread) { if (newThread) { new Thread(new Runnable() { @Override public void run() { updateItemCache(item, tClass); } }).start(); } else { updateItemCache(item, tClass); } } private <T> void updateItemCache(T item, Class<T> tClass) { try { CacheDbHelper cacheDbHelper = new CacheDbHelper(App.getContext()); SQLiteDatabase db = null; try { db = cacheDbHelper.getWritableDatabase(); BaseDao<T> baseDao = new BaseDao<>(App.getContext(), db, getListName(), tClass); baseDao.update(item, ((IListItem) item).getId().toString()); } finally { if (db != null) db.close(); } } catch (Throwable ex) { // Log.e(getContext(), ex); } } public void trySaveCache() { try { saveCache(); } catch (Throwable e) { AppLog.toastE(getContext(), e); } } /* Поддерживает ли загрузку состояния */ protected Boolean isSavedInstanceStateEnabled() { return false; } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); // если не поддерживает загрузку состояния, то грузим по новой if (!isSavedInstanceStateEnabled() || savedInstanceState == null) { mCacheTask = new LoadCacheTask(); mCacheTask.execute(); } } @Override public void onDestroy() { super.onDestroy(); if (mCacheTask != null) mCacheTask.cancel(false); if (mTask != null) mTask.cancel(null); } private Task mTask = null; private LoadCacheTask mCacheTask = null; public void startLoad() { if (mTask != null) return; loadData(true); } protected Task createTask(Boolean isRefresh) { return new Task(isRefresh); } public void loadData(final boolean isRefresh) { saveListViewScrollPosition(); Runnable runnable = new Runnable() { @Override public void run() { if (needLogin()) { Client.getInstance().checkLoginByCookies(); if (!Client.getInstance().getLogined()) Client.getInstance().showLoginForm(getContext(), new Client.OnUserChangedListener() { public void onUserChanged(String user, Boolean success) { loadData(isRefresh); } }); } mTask = createTask(isRefresh); mTask.execute(); } }; if (mTask != null && mTask.getStatus() != AsyncTask.Status.FINISHED) mTask.cancel(runnable); else { runnable.run(); } } protected abstract boolean inBackground(boolean isRefresh) throws Throwable; protected abstract void deliveryResult(boolean isRefresh); private void beforeDeliveryResult() { saveListViewScrollPosition(); } protected void afterDeliveryResult() { setCount(); setListShown(true); mAdapter.notifyDataSetChanged(); setEmptyText(App.getContext().getString(R.string.no_data)); new Thread(new Runnable() { @Override public void run() { trySaveCache(); } }).start(); restoreListViewScrollPosition(); } protected void onFailureResult() { } protected Boolean isCancelled() { return mTask.isCancelled(); } public class Task extends AsyncTask<Boolean, Void, Boolean> { protected Boolean mRefresh; private Runnable onCancelAction; protected Throwable mEx; public Task(Boolean refresh) { mRefresh = refresh; } @Override protected void onPreExecute() { super.onPreExecute(); setLoading(true); } public void cancel(Runnable runnable) { onCancelAction = runnable; cancel(false); } @Override protected Boolean doInBackground(Boolean[] p1) { try { return inBackground(mRefresh); } catch (Throwable e) { mEx = e; } return false; } @Override protected void onPostExecute(Boolean result) { super.onPostExecute(result); if (result && !isCancelled()) { beforeDeliveryResult(); deliveryResult(mRefresh); afterDeliveryResult(); } if (!isCancelled()) setLoading(false); if (mEx != null) AppLog.e(getActivity(), mEx, new Runnable() { @Override public void run() { loadData(mRefresh); } }); else if (!result) { onFailureResult(); } } @Override protected void onCancelled(Boolean result) { if (onCancelAction != null) onCancelAction.run(); } @Override protected void onCancelled() { if (onCancelAction != null) onCancelAction.run(); } } public class LoadCacheTask extends AsyncTask<Boolean, Void, Boolean> { private Throwable mEx; @Override protected void onPreExecute() { super.onPreExecute(); setLoading(true); } public void cancel() { cancel(false); } @Override protected Boolean doInBackground(Boolean[] p1) { try { loadCache(); return true; } catch (Throwable e) { mEx = e; } return false; } @Override protected void onPostExecute(Boolean result) { super.onPostExecute(result); if (mEx != null) Toast.makeText(getContext(), AppLog.getLocalizedMessage(mEx, App.getContext().getString(R.string.cache_load_error)), Toast.LENGTH_SHORT).show(); if (!isCancelled()) { deliveryCache(); restoreListViewScrollPosition(); if (mData.size() == 0 || Preferences.Lists.isRefresh()) startLoad(); else { setLoading(false); } } } @Override protected void onCancelled(Boolean result) { setLoading(false); } @Override protected void onCancelled() { setLoading(false); } } protected void deliveryCache() { mData.clear(); if (mCacheList != null) { mData.addAll(mCacheList); mCacheList.clear(); } setCount(); mAdapter.notifyDataSetChanged(); } }