Android学习之Activity与Service进行通信的三种方式

原文地址为: Android学习之Activity与Service进行通信的三种方式

ActivityService进行通信的三种方式

第一种 简单通信

直接通过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类中的两个方法onServiceConnectedonServiceDisconnected,这两个方法分别是在绑定成功和服务所在进程崩溃的时候被调用,如果绑定成功了,那么onServiceConnected(ComponentName componentName, IBinder iBinder) 就会被执行,然后第二个参数IBinder正是MyServiceonBind()方法的返回值,因此我们可以通过这个返回值来想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对象来实现MyServiceCallback的接口,在Android中有一个安全机制,辅助线程是不能直接修改主线程中的数据的,因此我们需要再定义一个Hander对象。

//①
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"));
}
};
}


在以上的代码中,按钮等控件可以自行添加





转载请注明本文地址: Android学习之Activity与Service进行通信的三种方式
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值