您的位置:首页 > 移动开发 > Android开发

Android服务Service详解(作用,生命周期,AIDL)系列文章--服务绑定和开启混合使用

2017-06-18 14:43 1066 查看
前面我们知道 了服务的开始方式有两种,一种是直接通过startService来开启,另外一种是通过bindService来开启服务。
这两种方式,各有种的优缺点。

比如说:startService的话,优点,可以长期运行着服务;缺点,没办跟服务进行通讯。
而bindService的话则是生命周期跟随绑定者一起结束,优点
是可以跟服务进行通讯。

那么我们需要达到既可以长期运行,又可以进行通讯怎么办呢?很简单,两种开启方式混合使用即可!

其实,这才是服务真正的生命周期呢!

假如我们的开启方式是:startService()----->stopService()

那么它的生命周期是这样子的:onCreate()----->onStartCommand----->onDestroy()

假如我们的开启方式是:bindService()------>unbindService()

那么它的生命周期是这样子的:onCreate()-----> onBind()----->onUnbind()---->onDestroy

我们先上代码,这次的话,我们只是添加多了一个按钮,调用服务内部方法的按钮而已。代码修改如下:布局文件代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">

<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="start"
android:text="开启服务"/>

<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="stop"
android:text="停止服务"/>

<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="bind"
android:text="绑定服务"/>

<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="unbind"
android:text="解绑服务"/>

<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="call"
android:text="调用服务内部的方法"/>

</LinearLayout>
MainActivity的代码:

package com.sunofbeaches.servicetestdemo;

import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;

public class MainActivity extends AppCompatActivity {

private static final String TAG = "MainActivity";
private IProxyInterface mRemoteServiceBinder;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.on
4000
Create(savedInstanceState);
setContentView(R.layout.activity_main);

}

/**
* 开始服务
*
* @param view
*/
public void start(View view) {
Intent intent = new Intent(this, SOBTestService.class);
startService(intent);
}

/**
* 停止服务
*
* @param view
*/
public void stop(View view) {
Intent intent = new Intent(this, SOBTestService.class);
stopService(intent);
}

/**
* 绑定服务
*
* @param view
*/
public void bind(View view) {
Log.d(TAG, "点击绑定服务按钮..");

Intent intent = new Intent(this, SOBTestService.class);

/**
* 这里面需要三个参数,第一个是意图对象,第二个是回调,第三个是创建模式。
*/
bindService(intent, mConnection, BIND_AUTO_CREATE);
}

private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//这里呢,则是绑定上了,那到我们输出它的名字,然后调用它的方法即可。
Log.d(TAG, "services name == " + name);

if (service instanceof IProxyInterface) {
//调用内部方法
mRemoteServiceBinder = (IProxyInterface) service;
} else {
throw new RuntimeException("服务的内部代理方法没有实现IProxyInterface借口");
}

}

@Override
public void onServiceDisconnected(ComponentName name) {
Log.d(TAG, "服务断开连接....");
}
};

/**
* 解除服务绑定...
*/
public void unbind(View view) {
Log.d(TAG, "点击了解绑服务按钮..");
unbindService(mConnection);
}

public void call(View view) {
Log.d(TAG, "调用服务内部的方法..");
mRemoteServiceBinder.callInnerMethod();
}

}
接口的代码:

package com.sunofbeaches.servicetestdemo;

/**
* Created by TrillGates on 17/4/16.
* God bless my code!
*/
public interface IProxyInterface {
void callInnerMethod();
}
服务的代码:
package com.sunofbeaches.servicetestdemo;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.util.Log;

/**
* Created by TrillGates on 17/4/15.
* God bless my code!
*/
public class SOBTestService extends Service {

private static final String TAG = "SOBTestService";

//继承自Binder,其实Binder就是IBinder的一个子类嘛。
private class CommunicationBinder extends Binder  implements IProxyInterface{

//这个方法供外部调用,用于调用内部的方法。
@Override
public void callInnerMethod() {
//调用内部的方法
innerMethod();
}

}

@Nullable
@Override
public IBinder onBind(Intent intent) {
//绑定以后,反回CommunicationBinder
return new CommunicationBinder();
}

@Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "服务被创建了....");
}

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

@Override
public boolean onUnbind(Intent intent) {
Log.d(TAG, "执行了onBind方法...");
return super.onUnbind(intent);
}

@Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG, "服务被销毁了....");
}

private void innerMethod() {
Log.d(TAG, "我是服务内部的方法被调用啦...");
}
}
接着,我们把程序跑起来,就是这个样子的啦:



于是,我们开心地执行以下操作:

点击开启服务

点击开启服务

点击绑定服务

点击停止服务



我们发现,第一次点击开启服务,则执行了onCreate方法和startCommand方法
第二次点击开启服务,则执行了startCommand方法
点击绑定服务,执行了onBind方法
点击停止服务,则没有反应

结论:如果服务被绑定了,并且没有解绑的话,服务是无活停止的。

接着,我们做以下操作:

开启服务

绑定服务

解绑服务



点击了开启服务,则执行了onCreate方法以及onStartCommand方法
点击了绑定服务,执行了onBind方法
点击了解绑服务,执行了unBind

结论:如果使用startService来开启服务,那么对应的unBind方法则不会停止服务。除非你stopService,这样子服务才会停止。

根据服务中的需求,既要长期运行,又要可以和服务进行通讯,那么推荐的做法如下:

startService()----->bindService()------->communication--------->unBinderService()------->stopService()

按这个套路的话,就可以达到我们目的啦!是不是很简单呢!

网易云视频:





社区网站:



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐