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的主要内容,如果未能解决你的问题,请参考以下文章

如何将位图从 Activity 传递给服务

如何将值从基本适配器传递到 Android 中的 Activity

android ListView 将隐藏值从一个 Activity 传递到另一个

android入门:activity之间跳转,并且回传参数

将列表传递给 Android 中的另一个 Activity

Android Activity 到 WebView 和 WebView 到 Activity 参数传递