package de.tum.in.tumcampusapp.activities.generic;
import android.os.AsyncTask;
import android.support.v4.widget.SwipeRefreshLayout;
import com.google.common.base.Optional;
import de.tum.in.tumcampusapp.auxiliary.NetUtils;
/**
* Generic class which can handle a long running search in background.
* Class parameter should be the class that holds the results of the background task.
*/
public abstract class ActivityForSearchingInBackground<T> extends ActivityForSearching {
protected AsyncTask<String, Void, Optional<T>> asyncTask;
/**
* Initializes an activity for searching in background.
* The xml layout must include an error_layout and a progress_layout.
* A {@link SwipeRefreshLayout}
* called ptr_layout is required if the activity should support PullToRefresh method
*
* @param layoutId Resource id of the xml layout that should be used to inflate the activity
* @param auth Authority for search suggestions declared in manifest file
* @param minLen Minimum text length that has to be entered by the user before a search quest can be submitted
*/
public ActivityForSearchingInBackground(int layoutId, String auth, int minLen) {
super(layoutId, auth, minLen);
}
/**
* Gets called if search has been canceled.
* This method is always called from a thread that is not the UI thread, so long running
* operations can be invoked directly in this method.
* To bring the loaded results to the UI return the results and apply it in
* {@link de.tum.in.tumcampusapp.activities.generic.ActivityForSearchingInBackground#onSearchFinished(Object)}
*/
protected abstract Optional<T> onSearchInBackground();
/**
* Gets called if a search query has been entered.
* This method is always called from a thread that is not the UI thread, so long running
* operations can be invoked directly in this method.
* To bring the loaded results to the UI return the results and apply it in
* {@link de.tum.in.tumcampusapp.activities.generic.ActivityForSearchingInBackground#onSearchFinished(Object)}
*
* @param query Query to search for
* @return Loaded results
*/
protected abstract Optional<T> onSearchInBackground(String query);
/**
* Gets called after background task has finished. The
* background task's return value is passed to this method, but
* this method is called from the UI thread so you can access UI elements from here.
*
* @param result Result from background task
*/
protected abstract void onSearchFinished(Optional<T> result);
@Override
public final void onStartSearch() {
if (asyncTask != null) {
asyncTask.cancel(true);
}
asyncTask = new BackgroundSearch();
asyncTask.execute();
}
@Override
public final void onStartSearch(final String query) {
if (asyncTask != null) {
asyncTask.cancel(true);
}
asyncTask = new BackgroundSearch();
asyncTask.execute(query);
}
void onCancelLoading() {
if (asyncTask != null) {
asyncTask.cancel(true);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
onCancelLoading();
}
/**
* Shows error layout and toasts the given message.
* Hides any progress indicator.
*
* @param errorReason Resource id of the error text
*/
@Override
protected void showError(int errorReason) {
showError(getString(errorReason));
}
/**
* Shows error layout and toasts the given message.
* Hides any progress indicator.
*
* @param errorReason Error text
*/
@Override
protected void showError(final String errorReason) {
runOnUiThread(new Runnable() {
@Override
public void run() {
ActivityForSearchingInBackground.super.showError(errorReason);
}
});
}
/**
* Shows error layout.
* Hides any progress indicator.
*/
@Override
protected void showErrorLayout() {
runOnUiThread(new Runnable() {
@Override
public void run() {
ActivityForSearchingInBackground.super.showErrorLayout();
}
});
}
/**
* Shows failed layout
*
* @param error Error Text to be toasted
*/
@Override
protected void showFailedTokenLayout(final String error) {
runOnUiThread(new Runnable() {
@Override
public void run() {
ActivityForSearchingInBackground.super.showFailedTokenLayout(error);
}
});
}
/**
* Shows failed layout
*/
@Override
protected void showNoTokenLayout() {
runOnUiThread(new Runnable() {
@Override
public void run() {
ActivityForSearchingInBackground.super.showNoTokenLayout();
}
});
}
/**
* Shows failed layout
*/
@Override
protected void showNoInternetLayout() {
runOnUiThread(new Runnable() {
@Override
public void run() {
ActivityForSearchingInBackground.super.showNoInternetLayout();
}
});
}
private class BackgroundSearch extends AsyncTask<String, Void, Optional<T>> {
@Override
protected void onPreExecute() {
super.onPreExecute();
if (!NetUtils.isConnected(ActivityForSearchingInBackground.this)) {
showNoInternetLayout();
return;
}
showLoadingStart();
}
@Override
protected Optional<T> doInBackground(String... arg) {
if (arg.length == 0) {
return onSearchInBackground();
}
return onSearchInBackground(arg[0]);
}
@Override
protected void onPostExecute(Optional<T> result) {
onSearchFinished(result);
asyncTask = null;
}
}
}