您的位置:首页 > 其它

四大组件之Service 与Activity通信(2)

2016-04-12 21:10 253 查看

绑定通信

还记得上一篇博客中的Binder方法吗,对这个方法进行合理的使用,我们就可以实现活动与服务之间的通信,并通过此活动可以指定服务去执行什么动作。

活动和服务之间进行通信需要将活动和服务绑定在一起才可以

我们先来看自定义的Service中的代码

public class MyService extends Service {
private MyBinder myBinder=new MyBinder();

class MyBinder extends Binder{
public void toStart(){
Log.d("MyBinder","start方法");
}
public void toEnd(){
Log.d("MyBinder","toEnd方法");
}
}

@Override
public IBinder onBind(Intent intent) {
return myBinder;
}

@Override
public void onCreate() {
super.onCreate();
Log.d("MyService","onCreate");
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("MyService","onStartCommand");
return super.onStartCommand(intent, flags, startId);
}

@Override
public void onDestroy() {
super.onDestroy();
Log.d("MyService","onDestroy");
}
}


仔细观察,你会发现,这些代码与上一篇相比,只增加了这些修改

private MyBinder myBinder=new MyBinder();

class MyBinder extends Binder{
public void toStart(){
Log.d("MyBinder","start方法");
}
public void toEnd(){
Log.d("MyBinder","toEnd方法");
}
}

@Override
public IBinder onBind(Intent intent) {
return myBinder;
}


我们增加了一个内部类继承自Binder,同时获取以一个该类的实例,并且在该类中定义了两个我们自定义的方法

同时将onBind()方法的返回值改为我们的实例对象

然后我们再来看活动中的代码

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

private Button button_start, button_stop,button_binder,button_unbinder;
private MyService.MyBinder myBinder;

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
}

private void init() {
button_start = (Button) findViewById(R.id.button_start);
button_start.setOnClickListener(this);
button_stop = (Button) findViewById(R.id.button_stop);
button_stop.setOnClickListener(this);
button_binder= (Button) findViewById(R.id.button_binder);
button_binder.setOnClickListener(this);
button_unbinder= (Button) findViewById(R.id.button_unbinder);
button_unbinder.setOnClickListener(this);
}

private ServiceConnection connection=new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
myBinder= (MyService.MyBinder) service;
myBinder.toStart();
myBinder.toEnd();
}

@Override
public void onServiceDisconnected(ComponentName name) {
}
};

@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button_start:
Intent startIntent = new Intent(this, MyService.class);
startService(startIntent);
break;
case R.id.button_stop:
Intent stopIntent = new Intent(this, MyService.class);
stopService(stopIntent);
break;
case R.id.button_binder:
Intent intent_binder=new Intent(this,MyService.class);
bindService(intent_binder,connection,BIND_AUTO_CREATE);
break;
case R.id.button_unbinder:
unbindService(connection);
break;
}
}
}


同样是在上一篇的代码中修改而来,

首先我们定义了一个服务中我们自定义的Binder的对象,但是未实例化

private MyService.MyBinder myBinder;


然后我们实例化了一个ServiceConnection对象,并且复写了其中的两个抽象方法

private ServiceConnection connection=new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
myBinder= (MyService.MyBinder) service;
myBinder.toStart();
myBinder.toEnd();
}

@Override
public void onServiceDisconnected(ComponentName name) {
}
};


通过方法名我们可以清楚,这两个复写的方法分别在活动和服务绑定和取消绑定的时候调用。

绑定和取消绑定的代码如下:

case R.id.button_binder:
Intent intent_binder=new Intent(this,MyService.class);
//BIND_AUTO_CREATE表示活动与服务绑定后自动创建服务
bindService(intent_binder,connection,BIND_AUTO_CREATE);
break;
case R.id.button_unbinder:
unbindService(connection);
break;


让我们来理一下思路,当我们点击绑定活动和服务的按钮的时候,就会调用onServiceConnected()方法,同时,服务会被创建,服务中的onBinder方法会被调用,同时返回服务中我们实例化的myBinder,并将其赋值给我们在活动中定义但未实例化的myBinder对象,然后再方法中就可以通过myBinder来调用我们在服务中定义的内部类中的方法了,这就实现了活动指挥服务去执行哪些动作了。

-这里就不截图了,因为我只是在绑定服务后,执行服务类中定义的内部类,仅仅输出了两句日志而已。

通过服务进行通信

由于现在在开发中我们很少用绑定服务,所以我们通常最常用的是通过服务来进行通信

我们现在来实现一个点击按钮,在服务中开启新的线程,来实现一个数值的自增,然后通过广播来通知主活动来相应的更新主活动中的进度条的数值,点击结束,就停止更新进度的操作。

这里仅列出主要代码

我们先来看自定义的Service中的代码

public class MyService extends Service {
private int count = 0;
private boolean isRun=true;

@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}

@Override
public void onCreate() {
super.onCreate();
}

@Override
public int onStartCommand(final Intent intent, int flags, int startId) {
new Thread(new Runnable() {
@Override
public void run() {
while (isRun) {

if (count >= 100) {
count = 0;
}
count++;
//这里必须新建一个Intent对象,不能使用参数中的Intent对象
Intent intent1 = new Intent();
intent1.putExtra("count", count);
intent1.setAction("MyService");
sendBroadcast(intent1);
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
return super.onStartCommand(intent, flags, startId);
}

@Override
public void onDestroy() {
super.onDestroy();
isRun=false;
}
}


注意onStartCommand()方法中,必须新建一个Intent对象,不能使用参数中的Intent对象来发送广播

主活动中的代码如下:

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

private Button button_start,button_stop;
private ProgressBar progressBar;
private MyReceiver myReceiver;
private IntentFilter intentFilter;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
intentFilter.addAction("MyService");
registerReceiver(myReceiver,intentFilter);
}

private void init() {
button_start= (Button) findViewById(R.id.button_start);
button_stop= (Button) findViewById(R.id.button_stop);
button_start.setOnClickListener(this);
button_stop.setOnClickListener(this);
progressBar= (ProgressBar) findViewById(R.id.progressBar);
myReceiver=new MyReceiver();
intentFilter=new IntentFilter();
}

@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.button_start:
Intent intent=new Intent(this,MyService.class);
startService(intent);
break;
case R.id.button_stop:
Intent intent1=new Intent(this,MyService.class);
stopService(intent1);
break;
}
}

class MyReceiver extends BroadcastReceiver{

@Override
public void onReceive(Context context, Intent intent) {
progressBar.setProgress(intent.getIntExtra("count",0));
}
}

@Override
public void onBackPressed() {
super.onBackPressed();
unregisterReceiver(myReceiver);
}
}


逻辑代码比较简单,这里就不再解释了。

总结

绑定服务在开发中貌似用的不多

通过广播我们也可以进行服务和活动之间的双向通信,上面的代码我们实现了服务向活动发出广播,传递信息,同时我们也可以反向发送广播,活动通过广播项服务传递信息。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: