Android 如何从活动中调用服务的方法?
我只想从我的活动中调用本地服务的方法。我该怎么做呢?我不知道你的问题出在哪里,请发一些代码。 使用活页夹,活动可以访问服务对象。有关在活动和服务之间创建连接的信息,请参见API中的示例 在活动中包含服务对象后,您只需调用:Android 如何从活动中调用服务的方法?,android,service,android-activity,Android,Service,Android Activity,我只想从我的活动中调用本地服务的方法。我该怎么做呢?我不知道你的问题出在哪里,请发一些代码。 使用活页夹,活动可以访问服务对象。有关在活动和服务之间创建连接的信息,请参见API中的示例 在活动中包含服务对象后,您只需调用: mService.yourMethod() 如果您能准确地描述您的问题,并且如我所说,发布一些代码片段,我们可以为您提供更好的帮助 一种方法是定义一个接口,并使用活页夹子系统执行IPC。在我发布的链接上有一系列很好的说明。如果你有问题,我会从那里开始,然后在这里发帖。尽管是一
mService.yourMethod()
如果您能准确地描述您的问题,并且如我所说,发布一些代码片段,我们可以为您提供更好的帮助 一种方法是定义一个接口,并使用
活页夹
子系统执行IPC。在我发布的链接上有一系列很好的说明。如果你有问题,我会从那里开始,然后在这里发帖。尽管是一个相当复杂的主题(IPC),Android和活页夹在让它变得非常简单方面做得非常好(至少从一开始,我相信如果你愿意,你可以让它变得复杂;-)
编辑正如注释中指出的那样,如果服务
和客户端在同一进程中运行,则不需要进行编辑。除非另行指定,否则这是默认设置。但是,不管怎样,它仍然可以工作,只是增加了一点复杂性。服务文档中的“本地服务示例”下有此权限的示例代码:
同样对于那些建议使用aidl的人——如果您的服务和客户端都是您自己的.apk的一部分并且运行在同一个进程中(默认行为),那么就不需要使用aidl;只是额外的复杂性并没有给你带来任何东西。下面是一个可能有帮助的例子
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;
}
};
}
如何调用普通Java方法?
服务是一个Java类。那么,您将如何调用服务方法呢
serviceObj.method();
现在真正的问题是如何创建服务对象?
Service serviceObj=new Service()代码>
绝对不是。
在Android中,服务是由Android操作系统创建、销毁和管理的系统组件。
要创建服务对象,您需要IBinder
这就是如何从中获取服务对象
一旦掌握了serviceObject。它将像任何普通Java对象一样工作。
图中解释的上述内容称为绑定服务
绑定使从活动中观察后台服务成为可能。通过绑定,我们可以通过两种方式进行通信,即活动服务
Prateek Yadav已经提供了一个优秀的代码片段。你可以用这个
没什么要记住的
- 永远不要忘记解除服务绑定,否则将导致资源泄漏
- 您可以按任意顺序调用
startService(intent)
和bindService(minent、mConnection、BIND\u AUTO\u CREATE)
。绑定和启动服务是两件独立的事情
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)
}
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()
}
}}
ForegroundService.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)
}
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()
}
}}
你为什么不放一些有用资源的链接呢?发布一些关于如何绑定服务并随后调用其方法的框架片段:)@Juri不知从哪里冒出来,它是LinkedL,只有当服务和活动在不同的应用程序中时才需要它。如果您的服务和活动是应用程序本地的(这是常见的情况),请参阅response by@hackbod@odedfos你部分是对的。使用AIDL的必要性取决于调用方和被调用方是否处于不同的进程中,而不一定是不同的应用程序。大多数情况下,应用程序只有一个进程,因此这不是问题,但您可以指定服务在与UI不同的进程中运行,即使在同一个应用程序中也是如此。根据定义,本地服务不使用IPC,问题是关于本地服务,因此,这个答案是错误的。@Ixx默认情况下不会,但您可以指定它们在单独的进程中运行。而且,如果您在与客户机相同的进程中运行服务,这也会起作用。如果服务被强制停止,我会被呼叫到onServiceDisconnected吗?为什么呼叫一个简单的fuction@Mr.Z也许您没有将服务绑定到Android中的活动,这应该是正确的答案。谢谢你节省了我的时间。