经过 3 年的阅读,这是我在这里的第一篇文章。从来没有必要写一个。这是一个非常好的网站。
我有了扩展本机类以支持从、和AsyncTask
调用的回调的想法。所以我不需要为每一个任务实现一个新的后代。RunInBackground()
OnProgressUpdate()
OnPreExecute()
OnPostExecute()
AsyncTask
(我不得不提到 inJava
是一个被调用的方法DoInBackground()
,它也存在于 Xamarin 端口中。但是文档说要覆盖RunInBackground()
。)
目标是实例化AsyncTask
后代,设置所需的回调并执行AsyncTask
.
现在的问题是,我需要PublishProgress()
从活动的回调内部调用以对不断变化的进度状态做出反应。所以我必须将此方法的单独回调传递给RunInBackground()
. 但是当我这样做时,会抛出一个异常。
System.Reflection.TargetInvocationException: 调用的目标已引发异常。 ---> 系统异常: 你调用的对象是空的
但我无法处理这个,因为我不知道应该需要哪个参考。调试清楚地表明回调是正确传递的。
活动:Main.cs
using AsyncSpecial = AsyncTaskEnhanced< System.String, System.Int32, System.Int32 >;
[ Activity( Label = "FooBar", MainLauncher = true ) ]
public class Main : Activity
{
protected Int32 RunInBackground( AsyncSpecial.PublishProgressDelegate publishProgressCallback, params String[] arguments )
{
for ( Int32 n = 0; n < arguments.Length; n++ )
{
Console.WriteLine( "Item :: " + arguments[ n ] );
// Won't invoke.
PublishProgressDelegate( n );
// Won't invoke.
DelegateHelper.Invoke( publishProgressCallback, n );
}
return arguments.Length;
}
protected void OnProgressUpdate( Int32 progress )
{
Console.WriteLine( "Progress :: " + progress );
}
protected void OnPreExecute( )
{
Console.WriteLine( "Pre" );
}
protected void OnPostExecute( Int32 result )
{
Console.WriteLine( "Result :: " + result );
}
protected override void OnCreate( Bundle bundle )
{
base.OnCreate( bundle );
this.SetContentView( Resource.Layout.Main );
Button button = this.FindViewById< Button >( Resource.Id.btnOne );
button.Click += ( Object sender, EventArgs eventArgs ) =>
{
AsyncSpecial asyncTask = new AsyncSpecial( );
asyncTask.RunInBackgroundCallback = this.RunInBackground;
asyncTask.OnProgressUpdateCallback = this.OnProgressUpdate;
asyncTask.OnPreExecuteCallback = this.OnPreExecute;
asyncTask.OnPostExecuteCallback = this.OnPostExecute;
asyncTask.Execute( "ItemOne", "ItemTwo" );
};
}
}
类:AsyncTaskEnhanced.cs
public class AsyncTaskEnhanced< TArgument, TProgress, TResult > : AsyncTask< TArgument, TProgress, TResult >
{
public delegate void PublishProgressDelegate( params TProgress[ ] progresses );
public delegate TResult RunInBackgroundDelegate( PublishProgressDelegate publishProgressCallback, params TArgument[ ] arguments );
public delegate void OnProgressUpdateDelegate( TProgress progress );
public delegate void OnPreExecuteDelegate( );
public delegate void OnPostExecuteDelegate( TResult result );
private PublishProgressDelegate publishProgressCallback = null;
public PublishProgressDelegate PublishProgressCallback
{
get
{
return this.publishProgressCallback;
}
set
{
this.publishProgressCallback = value;
}
}
private RunInBackgroundDelegate runInBackgroundCallback = null;
public RunInBackgroundDelegate RunInBackgroundCallback
{
get
{
return this.runInBackgroundCallback;
}
set
{
this.runInBackgroundCallback = value;
}
}
private OnProgressUpdateDelegate onProgressUpdateCallback = null;
public OnProgressUpdateDelegate OnProgressUpdateCallback
{
get
{
return this.onProgressUpdateCallback;
}
set
{
this.onProgressUpdateCallback = value;
}
}
private OnPreExecuteDelegate onPreExecuteCallback = null;
public OnPreExecuteDelegate OnPreExecuteCallback
{
get
{
return this.onPreExecuteCallback;
}
set
{
this.onPreExecuteCallback = value;
}
}
private OnPostExecuteDelegate onPostExecuteCallback = null;
public OnPostExecuteDelegate OnPostExecuteCallback
{
get
{
return this.onPostExecuteCallback;
}
set
{
this.onPostExecuteCallback = value;
}
}
public AsyncTaskEnhanced( IntPtr doNotUse, JniHandleOwnership transfer ) : base( doNotUse, transfer )
{
this.PublishProgressCallback = this.PublishProgress;
}
public AsyncTaskEnhanced( ) : base( )
{
}
protected override TResult RunInBackground( params TArgument[ ] arguments )
{
TResult result = DelegateHelper.Invoke< TResult >( this.RunInBackgroundCallback, this.PublishProgressCallback, arguments );
return result;
}
protected void OnProgressUpdate( TProgress progress )
{
DelegateHelper.Invoke( this.OnProgressUpdateCallback, progress );
}
protected override void OnPreExecute( )
{
DelegateHelper.Invoke( this.OnPreExecuteCallback );
}
protected override void OnPostExecute( TResult result )
{
DelegateHelper.Invoke( this.OnPostExecuteCallback, result );
}
}
类:DelegateHelper.cs
static public class DelegateHelper
{
static public void Invoke( Delegate callback, params Object[ ] arguments )
{
if ( null != callback )
{
callback.DynamicInvoke( arguments );
}
}
static public TResult Invoke< TResult >( Delegate callback, params Object[ ] arguments )
{
TResult result = default( TResult );
if ( null != callback )
{
result = ( TResult ) callback.DynamicInvoke( arguments );
}
return result;
}
}
顺便说一句:如果我PublishProgress()
从内部调用,AsyncTaskEnhanced::RunInBackground()
则AsyncTaskEnhanced::OnProgressUpdate()
不会被调用。这让我很困惑。
我希望我让自己和我的需求足够清楚。
非常感谢。基督教