将参数从活动传递到服务中的线程

时间:2013-02-05 15:15:56

标签: android service android-activity parameter-passing

我有一项活动,我开始提供服务,例如我将MyService作为:{/ p>

Intent intent1 = new Intent(this, MyService.class);
startService(intent1);

在我的服务中,我创建了一个线程并运行它。这是我的代码的一部分:

public class MyService extends Service {
...
@Override
public void onStart(Intent intent, int startid) {
    Thread mythread= new Thread() {
        @Override
        public void run() {
            while(true)
            {
              ...
            }
        }
    };
    mythread.start();
}

}

现在我要使用while(true)代替while(a),其中a是从我的活动传递到此服务的参数。请注意,我的活动与我的服务不同。如何才能做到这一点?请用一些代码显示具体示例。

5 个答案:

答案 0 :(得分:2)

您可以通过绑定来访问您的服务。编辑服务类,使其返回IBinder onBind()

public class MyService extends Service {

    private static final String TAG = MyService.class.getSimpleName();
    private final IBinder binder = new ServiceBinder();
    private boolean a;

    @Override
    public IBinder onBind( Intent intent ) {

        return binder;
    }

    @Override
    public int onStartCommand( Intent intent, int flags, int startId ) {

        return super.onStartCommand( intent, flags, startId );
    }

    @Override
    public void onCreate() {

        super.onCreate();
    }

    public class ServiceBinder extends Binder {

        public MyService getService() {

            return MyService.this;
        }
    }

    public void setA(boolean a) {

        this.a = a;
    }
}

现在,在您的活动中,您需要处理绑定和解除绑定到您的服务。在这个例子中,服务坚持你是否受约束。如果这不是您想要的功能,则不能致电startService(...)

public class MyActivity extends Activity {

    //...
    private MyService myService;
    private boolean bound;

    @Override    
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        Intent intent = new Intent( this, MyService.class );
        startService( intent );
        doBindService();
    }

    private final ServiceConnection serviceConnection = new ServiceConnection() {

        public void onServiceConnected( ComponentName className, IBinder service ) {

            myService = ( (MyService.ServiceBinder) service ).getService();
            bound = true;
        }

        public void onServiceDisconnected( ComponentName className ) {

            myService = null;
            bound = false;
        }
    };

    void doBindService() {

        boolean bound = bindService( new Intent( this, MyService.class ), serviceConnection, Context.BIND_AUTO_CREATE );
        if ( bound ) {

            Log.d( TAG, "Successfully bound to service" );
        }
        else {

            Log.d( TAG, "Failed to bind service" );
        }
    }

    void doUnbindService() {

        unbindService( serviceConnection );
    }
}

现在您在活动中引用了绑定服务,只需拨打myService.setA(true)即可设置参数。

答案 1 :(得分:1)

使用 bindService 代替调用启动服务,它允许您访问服务对象。

以下是有关Android Doc

的详细主题

一旦您的活动绑定到您的服务,您就可以通过您的活动从您的服务中调用任何方法。 你可以这样做:

.... Activity Code
          mService.stopThread();


..... Service Code
         public void stopThread(){
             a = false;
         }

以下是我的工作方式

在您尝试连接服务时的活动中:

    Intent serviceIntent = new Intent(this, MyService.class);
    bindService(serviceIntent, serviceConnection, BIND_AUTO_CREATE);

private ServiceConnection serviceConnection  = new ServiceConnection(){

    @Override
    public void onServiceConnected(ComponentName arg0, IBinder arg1) {
        mService = (MyService) ((MyService.LocalBinder) arg1)
                .getService();


    }

    @Override
    public void onServiceDisconnected(ComponentName arg0) {
        // TODO Auto-generated method stub
    }

};

在我的服务中: 我添加这个成员

private LocalBinder mBinder;


    protected void onCreate(Bundle bundle) {
               super.onCreate(bundle);
               mBinde = new LocalBinder();
         }

和这堂课:

public class LocalBinder extends Binder {
    public MyService getService() {
        // Return this instance of LocalService so clients can call public
        // methods
        return MyService.this;
    }
}

答案 2 :(得分:1)

简单使用

Intent intent1 = new Intent(this, MyService.class);
intent1.putExtra("key",value);
startService(intent1);

并使用

在服务中检索它
 a = intent.getStringExtra("key");// or Int, ArrayList whatever

答案 3 :(得分:1)

我认为服务绑定对您的案例来说太过分了,因为您在活动和服务之间进行了简单的互动。

根据建议,您可以使用startService传递参数。另一种解决方案是使用LocalBroadcast,here is an example

关于您的主题,您可能需要在服务而非匿名类中将其定义为单独的类,例如:

class MyThread extends Thread{
   private boolean a = true;
   public void setA(boolean a){
      this.a = a;
   }
   public void run() {
        while(a)
        {
          ...
        }
    }

}

答案 4 :(得分:0)

如果我正确理解了这个问题,那就是你需要的:

在活动类中,在调用startService()之前,添加以下行:

intent1.putExtra("keyName","keyValue");

在服务中,在onStartCommand()中:

Bundle extras = intent.getExtras();
String param = extras.getString("keyName");

param将保留您的参数。