如何制作异步按钮单击使用Xamarin Android动态更新TextView

时间:2016-10-04 07:47:52

标签: android multithreading xamarin

在Xamarin Native Android应用程序中,我调用methodOne()并获取一些细节。在此之后,我想将详细信息更新为文本视图,然后调用methodTwo()。执行MethodTwo后,我必须从文本视图中清除文本详细信息。我试过了  RunOnUiThread(()=> tColorDetail.SetText(“text”,TextView.BufferType.Normal)); 在完成执行MethodOne()后不立即显示的所有方法后,将显示详细信息。 这里缺少什么? .................................................. ...

public class MainActivity : Activity
{
    int count = 1;
    ticket Ticket;
    protected override void OnCreate (Bundle bundle)
    {
        base.OnCreate (bundle);

        // Set our view from the "main" layout resource
        SetContentView (Resource.Layout.Main);

        // Get our button from the layout resource,
        // and attach an event to it
        Button bClick= FindViewById<Button>(Resource.Id.bSub);
        try {
        bClick.Click += delegate {

            Job Job;
            Action act = new Action();
            EditText Address = (EditText)FindViewById(Resource.Id.Address);
            act.Address = Address.Text.ToString();

            if (!ValidateIPv4(act.Address))
            {
                ShowMessage("Invalid IP");
            }
            else
            {//TextView Mode = (TextView)FindViewById(Resource.Id.Mode);
                string httpUrl = act.iPAddress ;
                Ticket = act.ExecuteTicket(httpUrl, "Ticket");
                //RunOnUiThread(() => tColorMode.SetText("text", TextView.BufferType.Normal));
               // this.RunOnUiThread(() => setTicket(true));
                  setStatus(" Ticket : Success", true);
                 setTicket(true);
                //tColorMode.SetText("text",TextView.BufferType.Normal);
                //tColorMode.Invalidate();
                Job = act.executeJob(httpUrl, Ticket);
                setStatus(" Job : Success", true);
                act.File(httpUrl, Ticket, Job);
                setStatus("File Retrieval : Success", true);
                setTicket(false);
                setStatus("File Retrieval : Success", false);
            }
        };
        }
        catch (Exception ex)
        {

            ShowMessage(ex.Message.ToString());
        }
    }
    public bool ValidateIPv4(string ipString)
    {
        if (String.IsNullOrWhiteSpace(ipString))
        {
            return false;
        }

        string[] splitValues = ipString.Split('.');
        if (splitValues.Length != 4)
        {
            return false;
        }
        return true;
     }

    public  void setTicket(bool b)
    {
        //TextView tMode = (TextView)FindViewById(Resource.Id.tMode);
        // tMode.SetText("text",TextView.BufferType.Normal);
        RunOnUiThread(() => { 
        TextView tMode = (TextView)FindViewById(Resource.Id.Mode);
        tColorMode.SetText("text",TextView.BufferType.Normal);// b==true?Ticket.getProcessing():"";
        ((TextView)this.FindViewById(Resource.Id.tRes)).Text =  b == true ? Ticket.getHeight().ToString() : "";
        ((TextView)this.FindViewById(Resource.Id.tFormat)).Text = b == true ? Ticket.getFormat().ToString() : "";
        ((TextView)this.FindViewById(Resource.Id.tOrode)).Text = b == true ? Ticket.getType().ToString() : "";
        ((TextView)this.FindViewById(Resource.Id.tRot)).Text = b == true ? Ticket.getValue().ToString() : "";
        ((TextView)this.FindViewById(Resource.Id.tSource)).Text = b == true ? Ticket.getSource().ToString() : "";
        ((TextView)this.FindViewById(Resource.Id.tSize)).Text = b == true ? Ticket.getAutoDetect().ToString() : "";
        ((TextView)this.FindViewById(Resource.Id.tExpo)).Text = b == true ? Ticket.getAuto().ToString() : "";
        ((TextView)this.FindViewById(Resource.Id.tSharp)).Text = b == true ? Ticket.getSharp().ToString() : "";
        ((TextView)this.FindViewById(Resource.Id.tComp)).Text = b == true ? Ticket.getComp().ToString() : "";
        //tColorMode.Invalidate();
    }); }
    private void ShowMessage(string msg)
    {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        AlertDialog dialog = builder.Create();

        dialog.SetMessage(msg);
        dialog.SetButton("OK", (s, ev) =>
        {
            dialog.Cancel();
        });
        dialog.Show();
    }
    private void setStatus(string status,bool b)
    {
        ((TextView)this.FindViewById(Resource.Id.tStatus)).Text = b == true ? status : " ";
    }
}

1 个答案:

答案 0 :(得分:0)

如果不能访问完整的代码,那么给出答案是很棘手的,但是

Ticket = act.ExecuteTicket(httpUrl, "Ticket");

如果该行执行网络操作并且可能在后台线程中运行而不冻结UI,则该行可能需要一段时间才能完成。

大概是你到了

    // this.RunOnUiThread(() => setTicket(true));setStatus(" Ticket : Success", true);
 setTicket(true);

act.ExecuteTicket调用可能尚未完成

如果在

中发生异步操作
Job = act.executeJob(httpUrl, Ticket);

可能需要一段时间才能完成

考虑到所有这些,你可能会到达

setTicket(false);
setStatus("File Retrieval : Success", false);

在第一次通话完成之前

值得检查

在评论讨论后回答更新:

由于您的问题是您的异步​​调用花费了很长时间并且您遇到了“竞争条件”(您的UI线程正在进行TextView之前的更新),您可以通过以下方式解决问题:更改按钮会点击delegateasync delegate,并在继续操作之前强制执行await长操作“结果。

bClick.Click += async delegate {

               //...
               Job = await act.executeJob(httpUrl, Ticket);
               //...
    }