Android四大组件之Service

本文详细介绍了Android中的Service组件,包括startService和bindService两种启动方式的区别及生命周期。并通过实际案例展示了如何利用Service进行音乐播放,以及如何通过bindService实现与Service的绑定交互。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Service:是一个可以在后台执行长时间运行操作而不使用用户界面的Android应用组件。启动Service有两种方式:startServie和bindService。通过startService开启的服务.一旦服务开启, 这个服务和开启他的调用者之间就没有任何的关系了.
调用者不可以访问 service里面的方法. 调用者如果被系统回收了或者调用了ondestroy方法, service还会继续存在 。通过bindService开启的服务,服务开启之后,调用者和服务之间 还存在着联系 ,
一旦调用者挂掉了.service也会跟着挂掉 (若该service仅与该调用者绑定,那么该调用者被销毁,那么该service也被销毁;若该service与多个调用者绑定,那么当所有调用者与该service解除绑定,该service被销毁)。
一、startService的方式启动Service,其生命周期为:onCreate–>onStartCommand(android2.0以前,为onStart)–>onDestroy.
下面为利用Service播放音乐的demo
MainActivity的xml文件,里面有播放音乐、停止播放和停止服务三个按钮

<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" >

    <Button
        android:id="@+id/play_musi"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:text="开始播放" />

    <Button
        android:id="@+id/stop_music"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:text="停止播放播放" />

    <Button
        android:id="@+id/stop_service"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:text="停止服务" />

</LinearLayout>

MainActivity Java文件,当多次调用startService,Service的onCreate方法只会被调用一次,onStartCommand方法被多次调用,所以在onStartCommand实现播发和停止播放音乐的逻辑

package com.example.servicetest;

import android.R.integer;
import android.net.Uri;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MainActivity extends Activity implements OnClickListener {
    private Intent intent;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button play_music = (Button) findViewById(R.id.play_musi);
        Button stop_music = (Button) findViewById(R.id.stop_music);
        Button stop_service = (Button) findViewById(R.id.stop_service);
        intent = new Intent();
        intent.setClass(this, MusicService.class);

        play_music.setOnClickListener(this);
        stop_music.setOnClickListener(this);
        stop_service.setOnClickListener(this);

    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.play_musi:
            LogUtil.d("播放音乐");
            intent.putExtra("msg", 0);
            intent.putExtra("musicName", "music.mp3");
            startService(intent);

            break;
        case R.id.stop_music:
            LogUtil.d("停止播放音乐");
            intent.putExtra("msg", 1);
            startService(intent);

            break;
        case R.id.stop_service:
            LogUtil.d("停止服务");
            stopService(intent);
            break;

        default:
            break;
        }
    }

}



用于播放音乐的Service

package com.example.servicetest;

import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;

import android.app.Service;
import android.content.Intent;
import android.content.res.AssetFileDescriptor;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.IBinder;

public class MusicService extends Service {
    private MediaPlayer mediaPlayer; // 媒体播放器对象

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

    @Override
    public void onCreate() {
        super.onCreate();
        mediaPlayer = new MediaPlayer();
        LogUtil.d("onCreate");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        int msg = intent.getIntExtra("msg", -1);
        String musicName = intent.getStringExtra("musicName");
        LogUtil.d("onStartCommand" + "msg: " + msg + " musicName: " + musicName);
        if (msg == 0) {
            play(musicName);

        }
        if (msg == 1) {
            stop();

        }
        return super.onStartCommand(intent, flags, startId);
    }

    private void play(String musicName) {
        try {
            LogUtil.d("play");

            mediaPlayer.reset();// 把各项参数恢复到初始状态
            AssetFileDescriptor fileDescriptor = getAssets()
                    .openFd(musicName);
            mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
            mediaPlayer.setDataSource(fileDescriptor.getFileDescriptor(),

            fileDescriptor.getStartOffset(),

            fileDescriptor.getLength());

            mediaPlayer.prepare();
            mediaPlayer.start();

        } catch (Exception e) {
            LogUtil.d("播放失败:" + e.getMessage());
            e.printStackTrace();
        }

    }

    private void stop() {
        if (mediaPlayer != null && mediaPlayer.isPlaying()) {
            mediaPlayer.pause();
            LogUtil.d("stop");

        }

    }

    @Override
    public void onDestroy() {
        LogUtil.d("onDestroy");
        stop();
        mediaPlayer = null;


        super.onDestroy();
    }}

二、bindService的方式启动Service,其生命周期为:onCreate–>onBind–>Service运行–>调用者unbindService或调用者被销毁–>–>onUnbind–>onDestroy.Service中还有一个onRebind方法,那么它何时被调用呢?如果调用者同时startService和bindService,当调用者和service解除绑定后,并且onUnbind返回为true(默认情况下,onUnbind方法返回return super.onUnbind(intent);而super.onUnbind(intent)为false,所以要手动返回为true),当调用者再次绑定Service时,onRebind会被调用。
以下bindService的demo中,MyService继承于Service,有个继承于Binder的内部类,并定义了MyServiBce方法,目的是通过MyBinder返回MyService的实例。

package com.example.bindservice;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;

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

    @Override
    public void onCreate() {
        super.onCreate();
        LogUtil.d("onCreate");
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        LogUtil.d("onStartCommand");
        return super.onStartCommand(intent, flags, startId);
    }
    @Override
    public boolean onUnbind(Intent intent) {
        LogUtil.d("onUnbind");
        boolean re = super.onUnbind(intent);
        LogUtil.d("onUnbind默认返回: " + re);
        //return super.onUnbind(intent);
        return true;
    }
    @Override
    public void onRebind(Intent intent) {
        LogUtil.d("onRebind");
        super.onRebind(intent);
    }


    @Override
    public IBinder onBind(Intent arg0) {
        LogUtil.d("onBind");
        return mBinder;
    }

    public class MyBinder extends Binder{
        public MyService getService(){
            //返回serive实例
            return MyService.this;

        }

    }

    public int sum(int a,int b){
        return a + b;

    }
    @Override
    public void onDestroy() {
        LogUtil.d("onDestroy");
        super.onDestroy();
    }

}

MainActivity的java文件,其通过ServiceConnection和Service通信,如调用Service中的sum方法

package com.example.bindservice;

import android.os.Bundle;
import android.os.IBinder;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.util.Log;
import android.view.Menu;
import android.view.View;

public class MainActivity extends Activity {

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

    }



    public void bindMyService(View v) {

        LogUtil.d("绑定服务");
        Intent intent = new Intent();
        intent.setClass(this, MyService.class);
        //startService(intent);
        bindService(intent, conn, Context.BIND_AUTO_CREATE);

    }

    public void unbindMyService(View v) {

        LogUtil.d("解除绑定服务");
        unbindService(conn);

    }

    private ServiceConnection conn = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName arg0, IBinder binder) {
            MyService myService = ((MyService.MyBinder) binder).getService();
            int sum = myService.sum(1, 2);
            LogUtil.d("和: " + sum);

        }

        @Override
        public void onServiceDisconnected(ComponentName arg0) {
        }

    };

}

startService完整demo
bindService的完整demo

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值