如何从活动中调用服务的方法?

Shi*_*hiz 29 service android android-activity

我只想从我的活动中调用本地服务的方法.我怎样才能做到这一点 ?

小智 62

这是一个可能有助于Server.java的示例
:

package com.example.bindservice.binder;

import java.text.SimpleDateFormat;
import java.util.Date;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;

public class Server extends Service {

    IBinder mBinder = new LocalBinder();

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

    public class LocalBinder extends Binder {
        public Server getServerInstance() {
            return Server.this;
        }
    }

    public String getTime() {
        SimpleDateFormat mDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return mDateFormat.format(new Date());
    }
}
Run Code Online (Sandbox Code Playgroud)

Client.java

package com.example.bindservice.binder;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.example.bindservice.binder.Server.LocalBinder;

public class Client extends Activity {

    boolean mBounded;
    Server mServer;
    TextView text;
    Button button;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        text = (TextView)findViewById(R.id.text);
        button = (Button) findViewById(R.id.button);
        button.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                text.setText(mServer.getTime());
            }
        });
    }

    @Override
    protected void onStart() {
        super.onStart();

        Intent mIntent = new Intent(this, Server.class);
        bindService(mIntent, mConnection, BIND_AUTO_CREATE);
    };

    ServiceConnection mConnection = new ServiceConnection() {
        @Override
        public void onServiceDisconnected(ComponentName name) {
            Toast.makeText(Client.this, "Service is disconnected", 1000).show();
            mBounded = false;
            mServer = null;
        }

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Toast.makeText(Client.this, "Service is connected", 1000).show();
            mBounded = true;
            LocalBinder mLocalBinder = (LocalBinder)service;
            mServer = mLocalBinder.getServerInstance();
        }
    };

    @Override
    protected void onStop() {
        super.onStop();
        if(mBounded) {
            unbindService(mConnection);
            mBounded = false;
        }
    };
}
Run Code Online (Sandbox Code Playgroud)

  • 为什么称这个简单的功能真是太难了 (30认同)

hac*_*bod 28

在"本地服务示例"下的服务文档中有此权限的示例代码:

http://developer.android.com/reference/android/app/Service.html#LocalServiceSample

对于那些建议使用aidl的人 - 如果您的服务和客户端都是您自己的.apk的一部分并且在相同的进程中运行(默认行为),则不需要aidl; 它只是额外的复杂性,不会给你任何东西.


Roh*_*ngh 12

你如何调用一个普通的 Java 方法?

A obj = new A();
obj.method();
Run Code Online (Sandbox Code Playgroud)

服务是一个 Java 类。那么如何调用服务方法呢?

serviceObj.method();
Run Code Online (Sandbox Code Playgroud)

现在真正的问题是如何创建 Service 对象?

Service serviceObj = new Service();

当然不。

在 Android 中,Service 是由 Android 操作系统创建、销毁和管理的系统组件。
要创建服务对象,您需要IBinder

这就是您如何从IBinder获取 Service 对象的方法

在此处输入图片说明

一旦你拥有了 serviceObject。它会像任何普通的 Java 对象一样工作。
上面图中解释的东西叫做Binding a Service

绑定使得从 Activity 观察后台服务成为可能。通过绑定,我们可以通过两种方式进行通信,即Activity<--->Service
Prateek Yadav 已经提供了一个很好的代码片段。你可以用那个。

要记住的几件事

  • 永远不要忘记解除绑定服务,否则您将导致 ResourceLeak。
  • 你可以调用startService(intent)bindService(mIntent, mConnection, BIND_AUTO_CREATE)按任何顺序。绑定和启动服务是两个独立的事情。


Chr*_*son 2

实现此目的的一种方法是使用Android 的 AIDL定义接口并利用Binder子系统执行 IPC。我发布的链接中有一组很棒的说明。如果您有疑问,我会从这里开始,然后在这里发帖。尽管 Android 是一个相当复杂的主题(IPC),并且做得Binder非常好,使它变得非常简单(至少在开始时,我相信如果你愿意的话,你可以让它变得复杂;-))

编辑正如评论中所指出的,如果Service和客户端在同一进程中运行,则这是不必要的。除非您另外指定,否则这是默认值。然而,无论如何它仍然有效,只是增加了一点复杂性。

  • 仅当服务和活动位于不同的应用程序中时才需要 AIDL。如果您的服务和活动是您的应用程序本地的(这是常见情况),请参阅 @hackbod 的回复 (4认同)