【问题标题】:How do you call a service method from a class?你如何从一个类中调用一个服务方法?
【发布时间】:2014-06-05 19:31:40
【问题描述】:

我有一个服务,在这个服务中我创建了一个实现 Runnable 的类 Client。我使用

在我的服务的 onCreate 中调用此客户端
clientThread = new Thread(new Client());
clientThread.start();

在客户端类中,我有一个长时间运行的操作,并且有一些我想打印到我的活动的数据。在我的服务中,我有一个向 Activity 发送数据的方法(sendToUI),而 Activity 使用处理程序来接收数据。

现在我的问题是,我的 Client 类如何使用我的服务中的方法 (sendToUI) 将其数据提供给我的 Activity?

提前感谢您的帮助。

更新:我做了一些阅读,发现了一种简单的方法(在我看来)可以解决我的问题。这是我使用的过程。

我在我的 Client 类中添加了一个全局变量,我在 run() 方法中不断更新它。然后我在我的 Client 类中添加了一个方法 (getValue),它返回了全局变量。

我把代码改成了

Client clientthread = new Client();
new Thread(clientthread).start();

为了启动线程。然后我用了

int value = clientthread.getValue();

为了在我的客户端类中检索全局变量的当前值。然后我调用了我的 sendToUi 方法,并将值作为其参数。

【问题讨论】:

    标签: android multithreading service android-service


    【解决方案1】:

    您可以使用返回服务实例的活页夹从您的活动中绑定到该服务。那么您可以简单地使用该服务实例调用您想要的任何方法。

    这种方法的唯一问题是绑定是异步完成的,对于很多用例来说,这会很痛苦!不幸的是,我不知道有什么更好的方法。

    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 了解更多信息。

    【讨论】:

      【解决方案2】:

      您需要调用 UI 线程,使用方法 runOnUiThread,如下所示:

          runOnUiThread(new Runnable() {
              public void run() {
                  // ... Excecute the code for the Activity here
              }
          });
      

      将此代码放入您的课程中。

      希望对你有用。

      【讨论】:

        【解决方案3】:

        您应该通知您的 Activity 类必须在 UI 上更新一些数据。您不应该从该类更新 UI。你可能会制造比解决更多的问题。 您可以使用 Broascast 接收器,或者更简单的解决方案,使用 EventBus framework,它可以让您轻松地通知数据并将数据从一个线程发送到另一个线程。

        使用 EventBus 只需四个简单的步骤:

        在订阅者中实现任意数量的事件处理方法:

        public void onEvent(AnyEventType event) {}
        

        注册订阅者:

        eventBus.register(this);
        

        将事件发布到总线:

        eventBus.post(event);
        

        取消注册订阅者:

        eventBus.unregister(this);
        

        【讨论】:

          猜你喜欢
          • 2014-03-15
          • 1970-01-01
          • 2021-07-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-07-08
          相关资源
          最近更新 更多