你如何从班级调用服务方法?

时间:2014-06-05 19:31:40

标签: android multithreading service android-service

我有一个服务,在这个服务中我创建了一个实现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方法,并将值作为参数。

3 个答案:

答案 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了解详情。