Android Service的两种启动方式

时间:2022-07-18 16:44:18

Android中有一个经常使用到的组件,叫Service,它有这么几个特点:

  1. 它无法与用户直接进行交互;
  2. 它必须由用户或者其他程序显式的启动;
  3. 它的优先级比较高,它比处于前台的应用优先级低,但是比后台的其他应用优先级高,这就决定了当系统因为缺少内存而销毁某些没被利用的资源时,它被销毁的概率很小。

那么接下来,我们就写一个比较简单的跟activity界面绑定的service,用于音乐播放,activity销毁时,服务service也销毁,音乐就停止播放。

看TestService.java:

/** * @author xpd3581 * @date 2017-3-27 * @version 1.0 */
package com.xingpd.test;

import java.io.IOException;

import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.IBinder;
import android.util.Log;

/** * TestService 2017-3-27 */
public class TestService extends Service {

    @Override
    public IBinder onBind(Intent intent) {
        Log.e("onBind:", "服务启动!");
        new Thread() {
            public void run() {
                for (int i = 0; i < 100; i++) {
                    Log.e("i:", "====>" + i);
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();

        return null;
    }

    private MediaPlayer mp;

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.e("TestService:", "onStartCommand()!");
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onStart(Intent intent, int startId) {
        Log.e("TestService:", "onStart()!");
        // 开始播放音乐
        mp.start();
        // 音乐播放完毕的事件处理
        mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {

            public void onCompletion(MediaPlayer mp) {
                // 循环播放
                try {
                    mp.start();
                } catch (IllegalStateException e) {
                    e.printStackTrace();
                }
            }
        });
        // 播放音乐时发生错误的事件处理
        mp.setOnErrorListener(new MediaPlayer.OnErrorListener() {

            public boolean onError(MediaPlayer mp, int what, int extra) {
                // 释放资源
                try {
                    mp.release();
                } catch (Exception e) {
                    e.printStackTrace();
                }

                return false;
            }
        });

        super.onStart(intent, startId);
    }

    @Override
    public void onCreate() {
        Log.e("TestService:", "onCreate()!");
        // 初始化音乐资源
        try {
            // 创建MediaPlayer对象
            mp = new MediaPlayer();
            // 将音乐保存在res/raw/era_themass.mp3,R.java中自动生成{public static final int
            // era_themass=0x7f040000;}
            mp = MediaPlayer.create(this, R.raw.era_themass);
            // 在MediaPlayer取得播放资源与stop()之后要准备PlayBack的状态前一定要使用MediaPlayer.prepeare()
            mp.prepare();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        super.onCreate();
    }

    @Override
    public void onDestroy() {
        Log.e("TestService:", "onDestroy()!");
        // 服务停止时停止播放音乐并释放资源
        mp.stop();
        mp.release();

        super.onDestroy();
    }

    @Override
    public boolean onUnbind(Intent intent) {
        Log.e("TestService:", "onUnbind()!");
        return super.onUnbind(intent);
    }

}

相关的资源配置:

Android Service的两种启动方式

服务写完以后,需要在AndroidManifest.xml文件里边注册:

<service  android:name=".TestService">
</service>

然后启动服务和停止服务需要activity来实现:

MainActivity.java:

package com.xingpd.test;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MainActivity extends Activity implements OnClickListener {

    Button startService, stopService;
    ServiceConnection sc = new ServiceConnection() {

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.e("ServiceConnection:", "onServiceDisconnected!");
        }

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.e("ServiceConnection:", "onServiceConnected!");
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        startService = (Button) this.findViewById(R.id.startService);
        stopService = (Button) this.findViewById(R.id.stopService);
        startService.setOnClickListener(this);
        stopService.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
        case R.id.startService:
            Intent startIntent = new Intent(this, TestService.class);

            startService(startIntent);
            break;
        case R.id.stopService:
            Intent stopIntent = new Intent(this, TestService.class);
            stopService(stopIntent);

            break;

        default:
            break;
        }
    }

    @Override
    protected void onStop() {
        // TODO Auto-generated method stub
        Intent intent = new Intent(this, TestService.class);
        stopService(intent);
        super.onStop();
    }

}

其中用的是startService方法,如果换成bindService方法就得需要下面的代码:

ServiceConnection sc = new ServiceConnection() {

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.e("ServiceConnection:", "onServiceDisconnected!");
        }

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.e("ServiceConnection:", "onServiceConnected!");
        }
    };

而调用的话就是这样:

Intent startIntent = new Intent(this, TestService.class);

bindService(startIntent, sc, BIND_AUTO_CREATE);

同理,unbindService也是如此:

unbindService(sc);

项目运行以后,就可以点击相应按钮进行播放音乐了。

下载源码可以去这里:

更多资源下载地址