我只想从我的活动中调用本地服务的方法。我该怎么做?
这里有一个可能会有所帮助的示例
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;
}
};
}
在“本地服务示例”下的Service文档中有相关代码:
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操作系统创建、销毁和管理的系统组件。
要创建service对象,需要IBinder。
以下是从IBinder获取Service对象的方法。
一旦获得了serviceObject,它就像任何普通的Java对象一样工作。
上面解释的内容被称为绑定服务(Binding a Service)。
绑定使得Activity可以观察后台服务。通过绑定,我们可以进行双向通信,即Activity<--->Service。
Prateek Yadav已经提供了一个很好的代码片段。您可以使用它。
startService(intent)
和bindService(mIntent, mConnection, BIND_AUTO_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)
}
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()
}
}}
Binder
子系统执行IPC。我在发布的链接中提供了一组非常好的说明。建议您从那里开始,如果有问题再来这里发帖问。尽管IPC是一个相当复杂的主题,但Android和Binder
确实做得非常好(至少在入门方面,如果您想要的话,肯定可以把它搞得更复杂;-))。
编辑:正如评论中指出的那样,如果Service
和客户端在同一个进程中运行,则此操作是不必要的。除非另有规定,否则这是默认设置。然而,即使如此,它仍然能够工作,只是增加了一些复杂性。我不知道你的问题出在哪里,请贴上一些代码。 使用Binder,Activity可以访问服务对象。请参阅API中有关创建活动和服务之间连接的示例。
在您的活动中拥有服务对象后,您只需调用:
mService.yourMethod();
如果您能确切地描述您的问题并像我说的那样发布一些代码片段,我们可以更好地帮助您。