我有一个服务,在这个服务中我创建了一个实现Runnable的类Client。我使用
在我的服务的onCreate中调用此客户端clientThread = new Thread(new Client());
clientThread.start();
在客户端类中,我有一个长时间运行的操作,并且有一些我想要打印到Activity的数据。在我的服务中,我有一个方法(sendToUI)将数据发送到Activity,而Activity使用处理程序来接收数据。
现在我的问题是,我的Client类如何使用我服务中的方法(sendToUI)将其数据提供给我的Activity?
提前感谢您的帮助。
更新:我做了一些阅读,并找到了解决我问题的简单方法(在我看来)。这是我使用的过程。
我在我的Client类中添加了一个全局变量,我在run()方法中不断更新。然后我向我的Client类添加了一个方法(getValue),它返回了全局变量。
我将代码更改为
Client clientthread = new Client();
new Thread(clientthread).start();
为了启动线程。然后我用
int value = clientthread.getValue();
以便在我的Client类中检索全局变量的当前值。然后我调用了sendToUi方法,并将值作为参数。
答案 0 :(得分:0)
您需要使用 runOnUiThread 方法调用 UI线程,如下所示:
runOnUiThread(new Runnable() {
public void run() {
// ... Excecute the code for the Activity here
}
});
将此代码放入您的班级。
我希望它对你有用。
答案 1 :(得分:0)
您应该通知您的Activity类,必须在UI上更新一些数据。您不应该从该类更新UI。你可能会创造出比解决更多的问题。 您可以使用Broascast Receiver或更简单的解决方案,使用EventBus framework轻松地允许您通知并将数据从一个线程发送到另一个线程。
使用EventBus需要四个简单的步骤:
在订户中实施任意数量的事件处理方法:
public void onEvent(AnyEventType event) {}
注册订阅者:
eventBus.register(this);
将活动发布到公交车:
eventBus.post(event);
取消注册订阅者:
eventBus.unregister(this);
答案 2 :(得分:0)
您可以使用返回服务实例的活页夹从活动绑定到该服务。那么你可以简单地用该服务实例调用你想要的任何方法。
这种方法的唯一问题是绑定是异步完成的,对于很多用例来说会很痛苦!不幸的是,我不知道有任何更好的方法。
public class LocalService extends Service {
// Binder given to clients
private final IBinder mBinder = new LocalBinder();
// Random number generator
private final Random mGenerator = new Random();
/**
* Class used for the client Binder. Because we know this service always
* runs in the same process as its clients, we don't need to deal with IPC.
*/
public class LocalBinder extends Binder {
LocalService getService() {
// Return this instance of LocalService so clients can call public methods
return LocalService.this;
}
}
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
/** method for clients */
public int getRandomNumber() {
return mGenerator.nextInt(100);
}
}
public class BindingActivity extends Activity {
LocalService mService;
boolean mBound = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
@Override
protected void onStart() {
super.onStart();
// Bind to LocalService
Intent intent = new Intent(this, LocalService.class);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
@Override
protected void onStop() {
super.onStop();
// Unbind from the service
if (mBound) {
unbindService(mConnection);
mBound = false;
}
}
/** Called when a button is clicked (the button in the layout file attaches to
* this method with the android:onClick attribute) */
public void onButtonClick(View v) {
if (mBound) {
// Call a method from the LocalService.
// However, if this call were something that might hang, then this request should
// occur in a separate thread to avoid slowing down the activity performance.
int num = mService.getRandomNumber();
Toast.makeText(this, "number: " + num, Toast.LENGTH_SHORT).show();
}
}
/** Defines callbacks for service binding, passed to bindService() */
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName className,
IBinder service) {
// We've bound to LocalService, cast the IBinder and get LocalService instance
LocalBinder binder = (LocalBinder) service;
mService = binder.getService();
mBound = true;
}
@Override
public void onServiceDisconnected(ComponentName arg0) {
mBound = false;
}
};
}
请参阅this了解详情。