Android:将参数从Activity传递给Service
Posted
技术标签:
【中文标题】Android:将参数从Activity传递给Service【英文标题】:Android: pass parameter to Service from Activity 【发布时间】:2012-04-14 20:11:26 【问题描述】:我通过这种方式绑定到服务:
活动类:
ListenLocationService mService;
@Override
public void onCreate(Bundle savedInstanceState)
...
Intent intent = new Intent(this, ListenLocationService.class);
intent.putExtra("From", "Main");
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
...
private ServiceConnection mConnection = new ServiceConnection()
public void onServiceConnected(ComponentName className,
IBinder service)
LocalBinder binder = (LocalBinder) service;
mService = binder.getService();
public void onServiceDisconnected(ComponentName arg0)
;
这是我的服务的onBind
方法:
@Override
public IBinder onBind(Intent intent)
Bundle extras = intent.getExtras();
if(extras == null)
Log.d("Service","null");
else
Log.d("Service","not null");
String from = (String) extras.get("From");
if(from.equalsIgnoreCase("Main"))
StartListenLocation();
return mBinder;
所以我在 LogCat
中有“null” - 尽管我在 bindService
之前创建了 intent.putExtra
,但 bundle 为 null
一般服务工作正常。但是,我只需要从应用程序的主要活动中调用StartListenLocation();
(我决定通过发送标志来执行此操作)。
我怎样才能将数据发送到服务?或者也许还有另一种方法来检查onBind
启动了什么活动?
【问题讨论】:
【参考方案1】:1 创建一个接口,声明要从 Activity 调用的所有方法签名:
public interface ILocationService
public void StartListenLocation(Location location);
2 让你的 binder 实现 ILocaionService 并定义实际的方法体:
public class MyBinder extends Binder implements ILocationService
... ...
public void StartListenLocation(Location location)
// implement your method properly
... ...
3 在绑定到服务的活动中,通过接口引用您的活页夹:
... ...
ILocationService mService; // communication is handled via Binder not the actual service class.
private ServiceConnection mConnection = new ServiceConnection()
public void onServiceConnected(ComponentName className, IBinder service)
mService = (ILocationService) service;
... ...
;
... ...
// At some point if you need call service method with parameter:
Location location = new Location();
mService.StartListenLocation(location);
所有通信(即对您的服务的方法调用)都应该通过绑定类初始化和在 ServiceConnection.onServiceConnected() 中的返回来处理和执行,而不是实际的服务类(binder.getService() 是不必要的)。这就是设计为在 API 中工作的绑定服务通信的方式。
请注意,bindService() 是一个异步调用。在调用 bindService() 之后,在 ServiceConnection.onServiceConnected() 回调被系统参与之前会有一个延迟。所以在ServiceConnection.onServiceConnected()方法中初始化mService之后立即执行service方法的最佳位置。
希望这会有所帮助。
【讨论】:
感谢您的回答。我后来又遇到了一个问题,也许你知道怎么解决:***.com/questions/9956601/… @yorkw “这就是绑定服务通信设计为在 API 中工作的方式” - 并不是我怀疑你是正确的,但你是否有一些官方 android 文档的链接,我可以在其中阅读更多关于这个? @DuneCat,我同意这个说法不太准确,它实际上引用了谷歌建议实现绑定服务的推荐方式之一,更多详细信息请参见here。【参考方案2】:根据本次会议 http://www.google.com/events/io/2010/sessions/developing-RESTful-android-apps.html
向服务发送数据的一种方法是使用包含 pid(process id)、data、status 列的数据库,其中状态可以是 READ 、 READY 、 BINDING 等,当服务加载时,它会读取由调用活动填充的表,完成后可以删除,另一种表示方式为AIDL,如上一个答案所示,根据您的应用选择。
【讨论】:
【参考方案3】:你可以通过这种简单的方式传递参数:-
Intent serviceIntent = new Intent(this,ListenLocationService.class);
serviceIntent.putExtra("From", "Main");
startService(serviceIntent);
并在服务类的 onStart 方法中获取参数
@Override
public void onStart(Intent intent, int startId)
super.onStart(intent, startId);
Bundle extras = intent.getExtras();
if (extras == null)
Log.d("Service","null");
else
Log.d("Service","not null");
String from = (String) extras.get("From");
if(from.equalsIgnoreCase("Main"))
StartListenLocation();
享受:)
【讨论】:
这是根据要求将参数传递给 onBind 方法的方式。 @yorkw 有一个很好的通用解决方案,可以从服务中调用 Activity。以上是关于Android:将参数从Activity传递给Service的主要内容,如果未能解决你的问题,请参考以下文章
如何将值从基本适配器传递到 Android 中的 Activity