每次在Service中更改数据后如何更新Activity [英] How to update Activity every time the data had been changed in Service

查看:555
本文介绍了每次在Service中更改数据后如何更新Activity的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写我的第一个Android应用,它应该计算步数(通过加速计,来自

I'm writing my first Android app and it's supposed to count steps (via accelerometer, source code from http://www.gadgetsaint.com/android/create-pedometer-step-counter-android/)

那我现在有什么?

  1. 具有三个TextView字段(步长,奖金,速度)的MainActivity.
  2. 我检测步骤并计算距离,奖金和 速度.
  1. MainActivity with three TextView fields (steps, bonuses, speed).
  2. Service where I detect steps and calculate distanse, bonus and speed.

此服务是绑定服务,它包含三个类:MyService,MyServiceBinder和MyServiceConnection.我已经按照Xamarin.Android文档和示例中的说明进行了操作: https://github.com/xamarin/monodroid-samples/tree/master/ApplicationFundamentals/ServiceSamples/BoundServiceDemo .

This service is a Bound Service and it consist of three classes: MyService, MyServiceBinder and MyServiceConnection. I've done it as explained in Xamarin.Android documentation and example: https://github.com/xamarin/monodroid-samples/tree/master/ApplicationFundamentals/ServiceSamples/BoundServiceDemo.

关键是我每走一步,就想在MainActivity上实时显示(更新那些textviews).而且我不知道如何以适当的方式做到这一点.活动?广播接收者?我对绑定/连接一无所知,这对我来说是新事物. 请帮助我使它正常工作!任何示例(Java都可以)将非常有帮助.

The point is every time I have a step, I want to show this on MainActivity (update those textviews) in real time. And I don't understand how to do this in a proper way. Events? Broadcast reciever? I get messed with binding/connection, it's a new thing to me. Please help me to get it work! Any examples (Java is ok) would be very helpful.

这是源代码(我已经从多余的代码中清除了它).

Here is the source code (I've cleaned it up from extra code).

MainActivity.cs

public class MainActivity : Activity
{
    //BOUND SERVICE: STEPSERVICE 
    MyServiceConnection myServiceConnection;

    //UI
    internal TextView textBonus, textSteps, textSpeed;

    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
        SetContentView(Resource.Layout.Main);

        textBonus = FindViewById<TextView>(Resource.Id.textViewBonus);
        textStep = FindViewById<TextView>(Resource.Id.textViewDistance);
        textSpeed = FindViewById<TextView>(Resource.Id.textViewSpeed);
    }

    protected override void OnStart()
    {
        base.OnStart();
        if (myServiceConnection == null)
        {
            myServiceConnection = new MyServiceConnection(this);
        }
        DoBindMyService();
    }

    private void DoBindMyService()
    {
        Intent serviceIntent = new Intent(this, typeof(MyService));
        BindService(serviceIntent, myServiceConnection, Bind.AutoCreate);
    }


    protected override void OnDestroy()
    {
        //stop services!
        base.OnDestroy();
    }

    private void UpdateUI()
    {
        RunOnUiThread(() =>
        {
            textBonus.Text = myServiceConnection.Binder.Service.Bonus;              
            textSteps.Text = myServiceConnection.Binder.Service.Steps;
            textSpeed.Text = myServiceConnection.Binder.Service.Speed;
        });
    }
}

MyService.cs

[Service]
public class MyService : Service, IStepListener, ISensorEventListener
{
    //counters
    private int bonus;
    public int Bonus
    {
        get { return bonus; }
        set { bonus = value; }
    }

    private int steps = 0;
    public int StepsT
    {
        get { return steps; }
        set
        {
            steps = value;
        }
    }

    private float speed = 0.0F;
    public float Speed
    {
        get { return speed; }
        set
        {
            speed = value;
        }
    }

    public IBinder Binder { get; private set; }

    public override IBinder OnBind(Intent intent)
    {
        this.Binder = new MyServiceBinder(this);
        return this.Binder;
    }

    public override void OnCreate()
    {
        base.OnCreate();
    }

    public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
    {
        return StartCommandResult.Sticky;
    }

    public void Step(long timeNs)
    {
        Steps++;
        Bonus++;
        Speed++;
    }

    public void OnAccuracyChanged(Sensor sensor, SensorStatus accuracy)
    {
        // We don't want to do anything here.
    }

    public void OnSensorChanged(SensorEvent e)
    {
        simpleStepDetector.UpdateAccel(e.Timestamp, e.Values[0], e.Values[1], e.Values[2]);
    }
}

MyServiceConnection.cs

public class MyServiceConnection : Java.Lang.Object, IServiceConnection
{
    MainActivity mainActivity;

    public MyServiceConnection(MainActivity activity)
    {
        IsConnected = false;
        Binder = null;
        mainActivity = activity;
    }

    public bool IsConnected { get; private set; }
    public MyServiceBinder Binder { get; private set; }

    public void OnServiceConnected(ComponentName name, IBinder service)
    {
        Binder = service as MyServiceBinder;
        IsConnected = this.Binder != null;

        string message = "onSecondServiceConnected - ";

        if (IsConnected)
        {
            message = message + " bound to service " + name.ClassName;
        }
        else
        {
            message = message + " not bound to service " + name.ClassName;
        }

        mainActivity.textSpeed.Text = message;
    }

    public void OnServiceDisconnected(ComponentName name)
    {
        IsConnected = false;
        Binder = null;
    }
}

MyServiceBinder.cs

public class MyServiceBinder : Binder
{
    public MyServiceBinder(MyService service)
    {
        this.Service = service;
    }

    public MyService Service { get; private set; }
}

PS.这是我的第一个问题.如果我做错了事,请原谅.

PS. This is my first question here. Excuse me if I've made something wrong.

推荐答案

有三种方法可以完成它.

There are three ways to complete it.

  • 广播
  • 接口
  • BindService
  • 在您的MyServiceConnection中添加以下内容:

public MyService myService;

,然后在您的OnServiceConnected方法中,将其添加到Binder = service as MyServiceBinder;下:

and in your OnServiceConnected method add this under Binder = service as MyServiceBinder;:

myService=Binder.Service;
myService.SetActivity(mainActivity);

  • 在您的MyService类中添加此内容(以便您可以在服务中获取MainActivity实例):

  • In your MyService class add this (so you can get MainActivity instance in your service):

    MainActivity mainActivity;
    public void SetActivity(MainActivity activity) {
    this.mainActivity = activity;
    }
    

    ,然后在Step(long timeNs)方法中添加mainActivity.UpdateUI();,以便您可以更新UI.

    and add mainActivity.UpdateUI(); in your Step(long timeNs) method, so you can update your UI.

    在您的MainActivity中,将private void UpdateUI()替换为public void UpdateUI().

    • 添加IUpdate界面

    public interface IUpdate
    {
        void Update();
    }
    

  • 在您的MyService中添加以下内容:

  • In your MyService add this:

    IUpdate update;
    public void SetIUpdate(IUpdate update) {
        this.update = update;
    }
    

    ,然后在Step(long timeNs)方法中添加this.update.Update();.

    在您的MyServiceConnection类中实现IUpdate接口,所以它将像这样:

    Implement the IUpdate interface in your MyServiceConnection class, so it will like this:

    public class MyServiceConnection : Java.Lang.Object, IServiceConnection,IUpdate
    {
         MainActivity mainAtivity;
    
        public MyServiceConnection(MainActivity activity)
    {
        IsConnected = false;
        Binder = null;
        mainActivity = activity;
    }
    
    public bool IsConnected { get; private set; }
    public MyServiceBinder Binder { get; private set; }
    public MyService myService;
    
    public void OnServiceConnected(ComponentName name, IBinder service)
    {
        Binder = service as MyServiceBinder;
        myService=Binder.Service;
        myService.SetIUpdate(this);
        //myService.SetActivity(mainActivity);
        IsConnected = this.Binder != null;
    
        string message = "onSecondServiceConnected - ";
    
        if (IsConnected)
        {
            message = message + " bound to service " + name.ClassName;
        }
        else
        {
            message = message + " not bound to service " + name.ClassName;
        }
    
        mainActivity.textSpeed.Text = message;
    }
    
    public void OnServiceDisconnected(ComponentName name)
    {
        IsConnected = false;
        Binder = null;
    }
    
    public void Update()
    {
        mainActivity.UpdateUI();
    }
    }
    

  • 这是您已经知道的.

    这篇关于每次在Service中更改数据后如何更新Activity的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆