如何在服务中每次更改数据时更新 Activity
How to update Activity every time the data had been changed in Service
我正在编写我的第一个 Android 应用程序,它应该计算步数(通过加速度计,来自 http://www.gadgetsaint.com/android/create-pedometer-step-counter-android/ 的源代码)
那么我现在有什么:
- 具有三个 TextView 字段(步数、奖金、速度)的 MainActivity。
- 我检测步数并计算距离、奖励和
速度。
此服务是一个绑定服务,它由三个 类 组成:MyService、MyServiceBinder 和 MyServiceConnection。我已经按照 Xamarin.Android 文档和示例中的说明进行了操作:https://github.com/xamarin/monodroid-samples/tree/master/ApplicationFundamentals/ServiceSamples/BoundServiceDemo.
关键是每次我有一个步骤时,我都想在 MainActivity 上实时显示(更新那些文本视图)。而且我不明白如何以正确的方式做到这一点。事件?广播接收器?我被 binding/connection 弄得一团糟,这对我来说是一件新鲜事。
请帮助我让它工作!任何示例(Java 都可以)将非常有帮助。
这是源代码(我已经清除了多余的代码)。
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。这是我的第一个问题。如有错误请见谅
可以通过三种方式完成。
- 广播
- 界面
- 绑定服务
绑定服务
在您的 MyServiceConnection
中添加:
public MyService myService;
并在您的 OnServiceConnected
方法中将其添加到 Binder = service as MyServiceBinder;
下:
myService=Binder.Service;
myService.SetActivity(mainActivity);
在你的 MyService
class 添加这个(这样你就可以在你的服务中获得 MainActivity
实例):
MainActivity mainActivity;
public void SetActivity(MainActivity activity) {
this.mainActivity = activity;
}
并在您的 Step(long timeNs)
方法中添加 mainActivity.UpdateUI();
,这样您就可以更新您的 UI。
在您的 MainActivity
中将 private void UpdateUI()
替换为 public void UpdateUI()
。
界面
添加IUpdate
接口
public interface IUpdate
{
void Update();
}
在您的 MyService
中添加:
IUpdate update;
public void SetIUpdate(IUpdate update) {
this.update = update;
}
并在您的 Step(long timeNs)
方法中添加 this.update.Update();
。
在你的MyServiceConnection
class中实现IUpdate
接口,所以它会像这样:
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();
}
}
广播
这是你已经知道的。
我正在编写我的第一个 Android 应用程序,它应该计算步数(通过加速度计,来自 http://www.gadgetsaint.com/android/create-pedometer-step-counter-android/ 的源代码)
那么我现在有什么:
- 具有三个 TextView 字段(步数、奖金、速度)的 MainActivity。
- 我检测步数并计算距离、奖励和 速度。
此服务是一个绑定服务,它由三个 类 组成:MyService、MyServiceBinder 和 MyServiceConnection。我已经按照 Xamarin.Android 文档和示例中的说明进行了操作:https://github.com/xamarin/monodroid-samples/tree/master/ApplicationFundamentals/ServiceSamples/BoundServiceDemo.
关键是每次我有一个步骤时,我都想在 MainActivity 上实时显示(更新那些文本视图)。而且我不明白如何以正确的方式做到这一点。事件?广播接收器?我被 binding/connection 弄得一团糟,这对我来说是一件新鲜事。 请帮助我让它工作!任何示例(Java 都可以)将非常有帮助。
这是源代码(我已经清除了多余的代码)。
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。这是我的第一个问题。如有错误请见谅
可以通过三种方式完成。
- 广播
- 界面
- 绑定服务
绑定服务
在您的
MyServiceConnection
中添加:public MyService myService;
并在您的
OnServiceConnected
方法中将其添加到Binder = service as MyServiceBinder;
下:myService=Binder.Service; myService.SetActivity(mainActivity);
在你的
MyService
class 添加这个(这样你就可以在你的服务中获得MainActivity
实例):MainActivity mainActivity; public void SetActivity(MainActivity activity) { this.mainActivity = activity; }
并在您的
Step(long timeNs)
方法中添加mainActivity.UpdateUI();
,这样您就可以更新您的 UI。在您的
MainActivity
中将private void UpdateUI()
替换为public void UpdateUI()
。
界面
添加
IUpdate
接口public interface IUpdate { void Update(); }
在您的
MyService
中添加:IUpdate update; public void SetIUpdate(IUpdate update) { this.update = update; }
并在您的
Step(long timeNs)
方法中添加this.update.Update();
。在你的
MyServiceConnection
class中实现IUpdate
接口,所以它会像这样: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(); } }
广播
这是你已经知道的。