keepass2android/src/keepass2android/Utils/LoadingDialog.cs

216 lines
4.4 KiB
C#

using System;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Java.Lang;
using Exception = System.Exception;
using Object = Java.Lang.Object;
namespace keepass2android.Utils
{
public class LoadingDialog<TParams, TProgress, TResult> : AsyncTask<TParams, TProgress, TResult>
{
private readonly Context _context;
private readonly string _message;
private readonly bool _cancelable;
private readonly Func<Object[], Object> _doInBackground;
private readonly Action<Object> _onPostExecute;
private ProgressDialog mDialog;
/**
* Default is {@code 500}ms
*/
private int mDelayTime = 500;
/**
* Flag to use along with {@link #mDelayTime}
*/
private bool mFinished = false;
private Exception mLastException;
public LoadingDialog(IntPtr javaReference, JniHandleOwnership transfer)
: base(javaReference, transfer)
{
}
public LoadingDialog(Context context, string message, bool cancelable, Func<Object[], Object> doInBackground,
Action<Object> onPostExecute)
{
_context = context;
_message = message;
_cancelable = cancelable;
_doInBackground = doInBackground;
_onPostExecute = onPostExecute;
Initialize();
}
private void Initialize()
{
mDialog = new ProgressDialog(_context);
mDialog.SetMessage(_message);
mDialog.Indeterminate = true;
mDialog.SetCancelable(_cancelable);
if (_cancelable)
{
mDialog.SetCanceledOnTouchOutside(true);
mDialog.CancelEvent += (sender, args) => mDialog.Cancel();
}
}
public LoadingDialog(Context context, bool cancelable, Func<Object[], Object> doInBackground,
Action<Object> onPostExecute)
{
_message = context.GetString(Resource.String.loading);
_context = context;
_cancelable = cancelable;
_doInBackground = doInBackground;
_onPostExecute = onPostExecute;
Initialize();
}
protected override void OnPreExecute()
{
new Handler().PostDelayed(() =>
{
if (!mFinished)
{
try
{
/*
* sometime the activity has been finished before we
* show this dialog, it will raise error
*/
mDialog.Show();
}
catch (Exception t)
{
Kp2aLog.LogUnexpectedError(t);
}
}
}
, mDelayTime);
}
/**
* If you override this method, you must call {@code super.onCancelled()} at
* beginning of the method.
*/
protected override void OnCancelled()
{
DoFinish();
base.OnCancelled();
}
// onCancelled()
private void DoFinish()
{
mFinished = true;
try
{
/*
* Sometime the activity has been finished before we dismiss this
* dialog, it will raise error.
*/
mDialog.Dismiss();
}
catch (Exception e)
{
Kp2aLog.LogUnexpectedError(e);
}
}
// doFinish()
/**
* Sets last exception. This method is useful in case an exception raises
* inside {@link #doInBackground(Void...)}
*
* @param t
* {@link Throwable}
*/
protected void SetLastException(Exception e)
{
mLastException = e;
}
// setLastException()
/**
* Gets last exception.
*
* @return {@link Throwable}
*/
protected Exception GetLastException()
{
return mLastException;
}
// getLastException()
protected override Object DoInBackground(params Object[] @params)
{
return _doInBackground(@params);
}
protected override TResult RunInBackground(params TParams[] @params)
{
throw new NotImplementedException();
}
protected override void OnPostExecute(Object result)
{
DoFinish();
if (_onPostExecute != null)
_onPostExecute(result);
}
}
public class SimpleLoadingDialog : LoadingDialog<object, object, object>
{
private class BackgroundResult : Object
{
private readonly Action _onPostExec;
public BackgroundResult(Action onPostExec)
{
_onPostExec = onPostExec;
}
public Action OnPostExec
{
get { return _onPostExec; }
}
}
public SimpleLoadingDialog(IntPtr javaReference, JniHandleOwnership transfer)
: base(javaReference, transfer)
{
}
public SimpleLoadingDialog(Context ctx, string message, bool cancelable, Func<Action> doInBackgroundReturnOnPostExec)
: base(ctx, message, cancelable, input =>
{ return new BackgroundResult(doInBackgroundReturnOnPostExec()); }
, res => { ((BackgroundResult) res).OnPostExec(); })
{
}
}
}