第一种 简单通信
直接通过Intent进行传值,我们在启动一个Service的时候通过Intent的对象向Service进行传值,这种方式传递值比较不方便,性能不是很高。
(1)在MainActivity中通过启动服务和终止服务的按钮分别调用startService(intent)和stopService(intent)来启动和停止服务
MainActivity
public class MainActivity extends AppCompatActivity implements View.OnClickListener, ServiceConnection {
private Intent intent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
intent = new Intent(MainActivity.this, MyService.class);
findViewById(R.id.btyStartService).setOnClickListener(this);
findViewById(R.id.btyStopService).setOnClickListener(this);
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.btyStartService://启动服务
intent.putExtra("data", editText.getText().toString());
startService(intent);
break;
case R.id.btyStopService://终止服务
stopService(intent);
break;
}
}
}
(2)在Myservice中,我们通过onStartCommand(finalIntent intent, int flags, intstartId)这个函数来接收从Activity传过来的值
Myservice
public class MyService extends Service {
private Boolean myflags = false;
private String data = "服务器正在执行";
private static final String TAG = "ActivityTest";
private Callback callback;
public MyService() {
}
@Override
public IBinder onBind(Intent intent) {
return new Binder();
}
@Override
public void onCreate() {
super.onCreate();
myflags = true;
new Thread(){
@Override
public void run() {
super.run();
while(myflags){
try {
String str = data;
Log.d(TAG, str);
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
Toast.makeText(MyService.this, "出错了", Toast.LENGTH_SHORT).show();
}
}
Log.d(TAG, "服务器已停止");
}
}.start();
}
@Override
public int onStartCommand(final Intent intent, int flags, int startId) {
data = intent.getStringExtra("data");
return super.onStartCommand(intent, flags, startId);
}
}
第二种
我们在绑定服务的时候,首先要做的就是让我们的MainActivity实现ServiceConnection类,实现这个类之后,我们还需要重写ServiceConnection类中的两个方法onServiceConnected和onServiceDisconnected,这两个方法分别是在绑定成功和服务所在进程崩溃的时候被调用,如果绑定成功了,那么onServiceConnected(ComponentName componentName, IBinder iBinder) 就会被执行,然后第二个参数IBinder正是MyService中onBind()方法的返回值,因此我们可以通过这个返回值来想MyService传递数据。
public IBinder onBind(Intent intent) {
Log.d(TAG, "服务器已绑定");
return new Binder();
}
(1)MyService 中我们创建一个Binder类,让其实现android.os.Binder类,并且定义一个方法setData,然后我们通过onBind()方法将其对象返回MainActivity。
public class Binder extends android.os.Binder{
public void setData(String data){
MyService.this.data = data;
}
}
MyService
public class MyService extends Service {
private Boolean myflags = false;
private String data = "服务器正在执行";
private static final String TAG = "ActivityTest";
private Callback callback;
public MyService() {
}
@Override
public IBinder onBind(Intent intent) {
Log.d(TAG, "服务器已绑定");
return new Binder();
}
public class Binder extends android.os.Binder{
public void setData(String data){
MyService.this.data = data;
}
}
@Override
public void onCreate() {
super.onCreate();
myflags = true;
new Thread(){
@Override
public void run() {
super.run();
while(myflags){
//System.out.println("程序正在运行.....");
try {
String str = data;
Log.d(TAG, str);
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
Toast.makeText(MyService.this, "出错了", Toast.LENGTH_SHORT).show();
}
}
Log.d(TAG, "服务器已停止");
}
}.start();
}
@Override
public int onStartCommand(final Intent intent, int flags, int startId) {
data = intent.getStringExtra("data");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
myflags = false;
}
@Override
public boolean onUnbind(Intent intent) {
return super.onUnbind(intent);
}
}
(2)在MainActivity中,首先添加一个Binder对象,然后在ServiceConnection中获取MyService中返回的Binder对象,接着我们通过Binder对象调用它的方法setData向其传递数据
MainActivity
public class MainActivity extends AppCompatActivity implements View.OnClickListener, ServiceConnection {
private Intent intent;
private EditText editText;
private TextView textView;
private MyService.Binder myBinder = null;//①
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
intent = new Intent(MainActivity.this, MyService.class);
editText = (EditText) findViewById(R.id.editText);
textView = (TextView) findViewById(R.id.textView);
findViewById(R.id.btyStartService).setOnClickListener(this);
findViewById(R.id.btyStopService).setOnClickListener(this);
findViewById(R.id.btyBindService).setOnClickListener(this);
findViewById(R.id.btyUnbindService).setOnClickListener(this);
findViewById(R.id.btySend).setOnClickListener(this);
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.btyStartService://启动服务
intent.putExtra("data", editText.getText().toString());
startService(intent);
break;
case R.id.btyStopService://终止服务
stopService(intent);
break;
case R.id.btyBindService://绑定服务
bindService(intent, this, Context.BIND_AUTO_CREATE);
break;
case R.id.btyUnbindService://解除绑定
unbindService(this);
break;
case R.id.btySend://想MyService传递数据
if (myBinder != null) {
myBinder.setData(editText.getText().toString());//③
}
break;
}
}
//一旦绑定成功就会执行该函数
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
myBinder = (MyService.Binder) iBinder;//②
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
}
}
第三种,监听服务中的进程的变化
在MyService中
(1)添加一个公开的接口Callback
public static interface Callback{
void onDataChange(String data);
}
(2)在MyService内部添加一个变量
private Callback callback;
public void setCallback(Callback callback) {
this.callback = callback;
}
public Callback getCallback() {
return callback;
}
(3)向外界派发信息
if (callback != null){
callback.onDataChange(str);
}
(4)在Binder中返回一个当前的MyService对象,然外部可以添加事件的绑定
public MyService getMyService(){
return MyService.this;
}
MyService
public class MyService extends Service {
private Boolean myflags = false;
private String data = "服务器正在执行";
private static final String TAG = "ActivityTest";
private Callback callback;
public MyService() {
}
@Override
public IBinder onBind(Intent intent) {
Log.d(TAG, "服务器已绑定");
return new Binder();
}
public class Binder extends android.os.Binder{
public void setData(String data){
MyService.this.data = data;
}
public MyService getMyService(){
return MyService.this;
}
}
@Override
public void onCreate() {
super.onCreate();
myflags = true;
new Thread(){
@Override
public void run() {
super.run();
int i =1;
while(myflags){
//System.out.println("程序正在运行.....");
try {
String str = i + ":" +data;
Log.d(TAG, str);
if (callback != null){
callback.onDataChange(str);
}
sleep(1000);
i++;
} catch (InterruptedException e) {
e.printStackTrace();
Toast.makeText(MyService.this, "出错了", Toast.LENGTH_SHORT).show();
}
}
Log.d(TAG, "服务器已停止");
}
}.start();
}
@Override
public int onStartCommand(final Intent intent, int flags, int startId) {
data = intent.getStringExtra("data");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
myflags = false;
}
@Override
public boolean onUnbind(Intent intent) {
return super.onUnbind(intent);
}
public void setCallback(Callback callback) {
this.callback = callback;
}
public Callback getCallback() {
return callback;
}
public static interface Callback{
void onDataChange(String data);
}
}
在MainActivity中我们可以通过onServiceConnected方法中的iBinder对象来实现MyService中Callback的接口,由于 onDataChange() 是执行在子线程中的,因此我们需要再定义一个Hander对象,将任务由子线程切换到主线程中,让主线程来进行 UI 操作。
//①
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
myBinder = (MyService.Binder) iBinder;
myBinder.getMyService().setCallback(new MyService.Callback(){
@Override
public void onDataChange(String data) {
Message msg = new Message();
Bundle b = new Bundle();
b.putString("data",data);
msg.setData(b);
hander.sendMessage(msg);
}
});
}
//②
private Handler hander = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
textView.setText(msg.getData().getString("data"));
}
};
MainActivity
public class MainActivity extends AppCompatActivity implements View.OnClickListener, ServiceConnection {
private Intent intent;
private EditText editText;
private TextView textView;
private MyService.Binder myBinder = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
intent = new Intent(MainActivity.this, MyService.class);
editText = (EditText) findViewById(R.id.editText);
textView = (TextView) findViewById(R.id.textView);
findViewById(R.id.btyStartService).setOnClickListener(this);
findViewById(R.id.btyStopService).setOnClickListener(this);
findViewById(R.id.btyBindService).setOnClickListener(this);
findViewById(R.id.btyUnbindService).setOnClickListener(this);
findViewById(R.id.btySend).setOnClickListener(this);
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.btyStartService:
intent.putExtra("data", editText.getText().toString());
startService(intent);
break;
case R.id.btyStopService:
stopService(intent);
break;
case R.id.btyBindService:
bindService(intent, this, Context.BIND_AUTO_CREATE);
break;
case R.id.btyUnbindService:
unbindService(this);
break;
case R.id.btySend:
if (myBinder != null) {
myBinder.setData(editText.getText().toString());
}
break;
}
}
//一旦绑定成功就会执行该函数
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
myBinder = (MyService.Binder) iBinder;
myBinder.getMyService().setCallback(new MyService.Callback(){
@Override
public void onDataChange(String data) {
Message msg = new Message();
Bundle b = new Bundle();
b.putString("data",data);
msg.setData(b);
hander.sendMessage(msg);
}
});
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
}
private Handler hander = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
textView.setText(msg.getData().getString("data"));
}
};
}
在以上的代码中,按钮等控件可以自行添加