Service

1 生命周期

在这里插入图片描述

2 回调方法

回调描述
onStartCommand()其他组件(如活动)通过调用startService()来请求启动服务时,系统调用该方法。如果实现该方法,必须在工作完成时通过stopSelf()或者stopService()方法来停止服务。
onBind当其他组件想要通过bindService()来绑定服务时,系统调用该方法。如果实现该方法,需要返回IBinder对象来提供一个接口,以便客户来与服务通信。必须实现该方法,如果不允许绑定,则直接返回null。
onUnbind()当客户中断所有服务发布的特殊接口时,系统调用该方法。
onRebind()当新的客户端与服务连接,且此前它已经通过onUnbind(Intent)通知断开连接时,系统调用该方法。
onCreate()当服务通过onStartCommand()和onBind()被第一次创建的时候,系统调用该方法。该调用要求执行一次性安装。
onDestroy()当服务不再有用或者被销毁时,系统调用该方法。服务需要实现该方法来清理任何资源,如线程,已注册的监听器,接收器等。

3 实例 - startService

  1. 新建MyService.java
public class MyService extends Service {
    String msg = "Service : ";

    // 标识是否可以使用onRebind
    boolean mAllowRebind;

    // 用于返回Service实例
    public class MyBinder extends Binder {
        public MyService getService(){
            return MyService.this;
        }
    }

    // 绑定的客户端接口
    private MyBinder mBinder = new MyBinder();

    @Override
    public IBinder onBind(Intent arg0) {
        Log.d(msg, "The onBind() event");
        Toast.makeText(this, "服务已经绑定", Toast.LENGTH_LONG).show();

        return mBinder;
    }

    @Override
    public boolean onUnbind(Intent intent) {
        Log.d(msg, "The onUnbind() event");
        Toast.makeText(this, "服务已经解除绑定", Toast.LENGTH_LONG).show();

        return mAllowRebind;
    }

    @Override
    public void onRebind(Intent intent) {
        Log.d(msg, "The onRebind() event");
        Toast.makeText(this, "服务已经重新绑定", Toast.LENGTH_LONG).show();
    }

    @Override
    public void onCreate() {
        Log.d(msg, "The onCreate() event");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Toast.makeText(this, "服务已经启动", Toast.LENGTH_LONG).show();
        Log.d(msg, "The onStartCommand() event");

        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();

        Toast.makeText(this, "服务已经停止", Toast.LENGTH_LONG).show();
        Log.d(msg, "The onDestroy() event");
    }

    // 随便定义一个方法
    public void printMessage() {
        Log.d(msg, "The connection is started.");
    }
}
  1. 修改AndroidManifest.xml,下添加标签
    <application
            android:allowBackup="true"
            android:icon="@drawable/logo"
            android:label="@string/app_name"
            android:roundIcon="@mipmap/ic_launcher_round"
            android:supportsRtl="true"
            android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>

        <service android:name=".MyService" />
    </application>
  1. MainActivity.java定义启动和停止服务方法
public class MainActivity extends AppCompatActivity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    // 启动服务
    public void startService(View view) {
        startService(new Intent(getBaseContext(), MyService.class));
    }

    // 停止服务
    public void stopService(View view) {
        stopService(new Intent(getBaseContext(), MyService.class));
    }
}
  1. activity_main.xml创建2个button,可以在design页拖拽,也可以在text页加标签,分别绑定点击事件startService和stopService
    <Button
            android:text="启动服务"
            <!--其他略-->
            android:onClick="startService"
            />
    <Button
            android:text="停止服务"
             <!--其他略-->
            android:onClick="stopService"
            />

PS: 加了之后,发现Button标红,这是因为定义一个View的位置,必须添加约束
点击 infer constraints 即可
在这里插入图片描述
5. 运行App,先后点击启动和停止按钮,分别显示:
模拟器-开启:
在这里插入图片描述
日志-开启:

08-21 07:06:08.748 10122-10122/app D/Service :: The onCreate() event
08-21 07:06:08.753 10122-10122/app D/Service :: The onStartCommand() event

模拟器-停止:
在这里插入图片描述
日志-停止:

08-21 07:06:41.700 10122-10122/app D/Service :: The onDestroy() event

4 实例 - bindService

使用bindService主要分两种情形:

  1. Service的调用者client与Service在同一个App中;
  2. Service的调用者client是App1中的一个Activity,而Service是App2中的Service,client与service分属两个App,这种情形下主要用于实现跨进程的通信。

实例延续3的代码。

  1. MainActivity.java定义绑定和解除绑定服务方法
public class MainActivity extends AppCompatActivity {
    private MyService service = null;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    // 绑定是异步的,要接收IBinder,客户端必须创建一个ServiceConnection的实例并传给bindService()
    private ServiceConnection conn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder binder) {
            MyService.MyBinder myBinder = (MyService.MyBinder)binder;
            service = myBinder.getService();
            service.printMessage();
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.d("Activity: ", "The service is disconnected.");
        }
    };

    // 绑定服务
    public void bindService(View view) {
        Intent intent = new Intent(this, MyService.class);
        bindService(intent, conn, Context.BIND_AUTO_CREATE);
    }

    // 解绑服务
    public void unbindService(View view) {
        unbindService(conn);
    }
}
  1. 修改activity_main.xml,按钮分别绑定两个新的方法
    <Button
            android:text="绑定服务"
            <!--其他略-->
            android:onClick="bindService"
            />
    <Button
            android:text="解绑服务"
             <!--其他略-->
            android:onClick="unbindService"
            />
  1. 运行App,先后点击绑定和解绑按钮,显示:

模拟器 - 绑定:
在这里插入图片描述
日志 - 绑定:

08-21 08:00:49.323 10576-10576/app D/Service :: The onCreate() event
08-21 08:00:49.324 10576-10576/app D/Service :: The onBind() event
08-21 08:00:49.334 10576-10576/app D/Service :: The connection is started.

模拟器 - 解绑:
在这里插入图片描述
日志 - 解绑:

08-21 08:05:04.409 10808-10808/app D/Service :: The onUnbind() event
08-21 08:05:04.419 10808-10808/app D/Service :: The onDestroy() event

PS: 没有调用onServiceDisconnected

onServiceDisconnected() 在连接正常关闭的情况下是不会被调用的, 该方法只在Service 被破坏了或者被杀死的时候调用。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐