如何从活动中调用服务的方法?
Posted
技术标签:
【中文标题】如何从活动中调用服务的方法?【英文标题】:How to call methods of a Service from activity? 【发布时间】:2011-06-18 05:05:51 【问题描述】:我只是想从我的活动中调用本地服务的方法。我该怎么做?
【问题讨论】:
【参考方案1】:这是一个可能有帮助的示例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());
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;
;
【讨论】:
如果服务被强制停止,我会接到 onServiceDisconnected 的电话吗? 为什么调用一个简单的函数这么难 @Mr.Z 也许你没有将服务绑定到Android中的活动***.com/questions/1916253/… 这应该是正确的答案。谢谢。你节省了我的时间。【参考方案2】:在“本地服务示例”下的服务文档中有此权限的示例代码:
http://developer.android.com/reference/android/app/Service.html#LocalServiceSample
同样对于那些建议使用aidl 的人——如果您的服务和客户端都是您自己的.apk 的一部分并且在同一个进程中运行(默认行为),则不需要aidl;它只是额外的复杂性,并没有给你任何东西。
【讨论】:
【参考方案3】:如何调用普通的 Java 方法?
A obj = new A();
obj.method();
Service 是一个 Java 类。那么如何调用服务方法呢?
serviceObj.method();
现在真正的问题是如何创建服务对象?
Service serviceObj = new Service();
绝对不是。
在 Android 中,Service 是由 Android 操作系统创建、销毁和管理的系统组件。 要创建服务对象,您需要 IBinder。
这是您从IBinder 获取服务对象的方法。
一旦你拥有了 serviceObject.它将像任何普通的 Java 对象一样工作。 上面图中解释的东西叫做Binding a Service。
绑定使得从 Activity 观察后台服务成为可能。通过绑定,我们可以通过两种方式进行通信,即ActivityService。 Prateek Yadav 已经提供了出色的代码 sn-p。你可以使用它。
注意事项
永远不要忘记取消绑定服务,否则会导致 ResourceLeak。 您可以按任意顺序拨打startService(intent)
和bindService(mIntent, mConnection, BIND_AUTO_CREATE)
。绑定和启动服务是两个独立的东西。
【讨论】:
【参考方案4】:实现此目的的一种方法是使用Android's AIDL 定义一个接口,并利用Binder
子系统执行IPC。我发布的链接中有一组很棒的说明。如果您有问题,我会从那里开始,然后在这里发布。尽管是一个相当复杂的主题 (IPC) Android 和 Binder
在使它变得非常简单方面做得非常好(至少在开始时,我相信如果你愿意,你可以让它变得复杂;-))
编辑 正如 cmets 中所指出的,如果 Service
和客户端在同一进程中运行,则这是不必要的。除非您另外指定,否则这是默认设置。但是,无论如何它仍然有效,只是增加了一点复杂性。
【讨论】:
AIDL 仅在服务和活动位于不同应用程序中时才需要。如果您的服务和活动对您的应用程序来说是本地的(这是常见的情况),请参阅@hackbod 的回复 @odedfos 你说对了一部分。使用 AIDL 的必要性取决于调用者和被调用者是否在不同的进程中,不一定是不同的应用程序。大多数情况下,应用程序只有一个进程,因此这不是问题,但您可以指定服务在与 UI 不同的进程中运行,即使在同一个应用程序中也是如此。 本地服务定义不使用IPC,问题是关于本地服务,所以这个答案是错误的。 @Ixx 默认情况下不会,但您可以指定它们在单独的进程中运行。此外,如果您在与客户端相同的进程中运行服务,这确实工作 ergo 它并没有错,它只是更复杂并且需要更多的开销。【参考方案5】:我不知道你的问题出在哪里,请发布一些代码。 使用 Binder,Activity 可以访问服务对象。请参阅 API 中的示例以创建活动和服务之间的连接。
在您的活动中拥有服务对象,您可以简单地调用: mService.yourMethod(); 如果您能准确描述您的问题,我们可以为您提供更好的帮助,正如我所说,发布一些 sn-ps。
【讨论】:
为什么不放一些有用资源的链接?发布一些关于如何绑定服务并随后调用其方法的骨架 sn-ps? :) @Juri ***.com/questions/1916253/… 突然链接了【参考方案6】:Kotlin 的等效代码
MainActivity.kt
private var mBounded = false
private var foregroundService: ForegroundService? = null
override fun onPostCreate(savedInstanceState: Bundle?)
super.onPostCreate(savedInstanceState)
btn_start_service.setOnClickListener startMyService();
btn_stop_service.setOnClickListener stopMyService();
mConnection = object : ServiceConnection
override fun onServiceDisconnected(name: ComponentName)
Toast.makeText(this@MainActivity, "Service is disconnected", Toast.LENGTH_SHORT)
.show()
mBounded = false
foregroundService = null
override fun onServiceConnected(name: ComponentName, service: IBinder)
Toast.makeText(this@MainActivity, "Service is connected", Toast.LENGTH_SHORT).show()
mBounded = true
val mLocalBinder = service as LocalBinder
foregroundService = mLocalBinder.getServerInstance()
val startIntent = Intent(this, ForegroundService::class.java)
bindService(startIntent, mConnection as ServiceConnection, Context.BIND_AUTO_CREATE);
private fun startMyService()
foregroundService!!.startService(this, "sdds")
private fun stopMyService()
if (mBounded)
mConnection?.let unbindService(it) ;
mBounded = false;
val stopIntent = Intent(this, ForegroundService::class.java)
stopService(stopIntent)
ForegroundService.kt
class ForegroundService : Service()
private val CHANNEL_ID = "ForegroundService Kotlin"
var mBinder: IBinder = LocalBinder()
fun startService(context: Context, message: String)
val startIntent = Intent(context, ForegroundService::class.java)
startIntent.putExtra("inputExtra", message)
ContextCompat.startForegroundService(context, startIntent)
fun stopService(context: Context)
val stopIntent = Intent(context, ForegroundService::class.java)
context.stopService(stopIntent)
override fun onBind(intent: Intent?): IBinder?
return mBinder
class LocalBinder : Binder()
fun getServerInstance(): ForegroundService?
return ForegroundService()
【讨论】:
以上是关于如何从活动中调用服务的方法?的主要内容,如果未能解决你的问题,请参考以下文章