2

我有一个启动服务的活动,例如我的状态MyService是:

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从我的活动传递到此服务的参数。请注意,我的活动与我的服务不同。如何才能做到这一点?请使用一些代码显示具体示例。

4

5 回答 5

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)即可设置参数。

于 2013-02-05T15:36:32.303 回答
1

而不是调用 start service 使用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;
    }
}
于 2013-02-05T15:23:29.333 回答
1

简单使用

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

并在使用中检索它

 a = intent.getStringExtra("key");// or Int, ArrayList whatever
于 2013-02-05T15:40:09.807 回答
1

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

如建议的那样,您可以使用传递参数startService。另一种解决方案,是使用LocalBroadcast,这里是一个例子

关于您的线程,您可能需要在服务中将其定义为单独的类而不是匿名类,例如:

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

}
于 2013-02-05T16:12:58.350 回答
0

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

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

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

在服务中,在 onStartCommand() 中:

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

param 将保存您的参数。

于 2013-02-05T15:40:48.213 回答