【发布时间】:2011-06-18 05:05:51
【问题描述】:
我只是想从我的活动中调用本地服务的方法。我该怎么做?
【问题讨论】:
标签: android service android-activity
我只是想从我的活动中调用本地服务的方法。我该怎么做?
【问题讨论】:
标签: android service android-activity
这是一个可能有帮助的示例
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;
}
};
}
【讨论】:
在“本地服务示例”下的服务文档中有此权限的示例代码:
http://developer.android.com/reference/android/app/Service.html#LocalServiceSample
同样对于那些建议使用aidl 的人——如果您的服务和客户端都是您自己的.apk 的一部分并且在同一个进程中运行(默认行为),则不需要aidl;它只是额外的复杂性,并没有给你任何东西。
【讨论】:
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。你可以使用它。
startService(intent) 和bindService(mIntent, mConnection, BIND_AUTO_CREATE)。绑定和启动服务是两个独立的东西。【讨论】:
实现此目的的一种方法是使用Android's AIDL 定义一个接口,并利用Binder 子系统执行IPC。我发布的链接中有一组很棒的说明。如果您有问题,我会从那里开始,然后在这里发布。尽管是一个相当复杂的主题 (IPC) Android 和 Binder 在使它变得非常简单方面做得非常好(至少在开始时,我相信如果你愿意,你可以让它变得复杂;-))
编辑 正如 cmets 中所指出的,如果 Service 和客户端在同一进程中运行,则这是不必要的。除非您另外指定,否则这是默认设置。但是,无论如何它仍然有效,只是增加了一点复杂性。
【讨论】:
我不知道你的问题出在哪里,请发布一些代码。 使用 Binder,Activity 可以访问服务对象。请参阅 API 中的示例以创建活动和服务之间的连接。
在您的活动中拥有服务对象,您可以简单地调用:
mService.yourMethod();
如果您能准确描述您的问题,我们可以为您提供更好的帮助,正如我所说,发布一些 sn-ps。
【讨论】:
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()
}
}}
【讨论】: