7、Service
7.1 Service初探
- A Service is an application component that can perform long-running operations in the background and does not provide a user interface.
服务是一个应用程序组件,它可以在后台执行长时间运行的操作,而不提供用户界面。
- A Service is not a separate process.
- A Service is not a thread.
- Two Forms
- Started
- Bound
7.2 Service的生命周期点我查看
Start :
Android的应用程序组件,如活动,通过startService()启动了服务,则服务是Started状态。一旦启动,服务可以在后台无限期运行,即使启动它的组件已经被销毁。
7.3 使用Service做一个播放音乐的实例
-
7.3.1 新建一个TestService——Module
-
7.3.2 新建一个MusicService类
-
在 res下新建一个 raw文件夹,选取一个 mp3文件存放在 res/raw文件夹中
.mp3 文件名称必须是小写!小写!小写!
public class MusicService extends Service { private static final String TAG = MusicService.class.getSimpleName(); private MediaPlayer mediaPlayer; // 创建 MediaPlayer对象 @Override public void onCreate() { super.onCreate(); Log.i(TAG, "onCreate"); // 初始化 MediaPlayer mediaPlayer = MediaPlayer.create(this,R.raw.tianhou); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.i(TAG, "onStartCommand"); mediaPlayer.start(); return START_NOT_STICKY; } @Override public void onDestroy() { Log.i(TAG, "onDestroy"); mediaPlayer.stop(); super.onDestroy(); } @Nullable @Override public IBinder onBind(Intent intent) { return null; } }
**START_NOT_STICKY 😗*这种模式对于那些想通过启动来完成一些工作的事情来说是有意义的,但是在内存压力下可以停止,并且以后会显式地重新启动自己来完成更多的工作。
-
-
7.3.3 新建一个activity_music.xml布局文件,并创建MusicButtonActivity类
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <Button android:id="@+id/startBtn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAllCaps="false" android:text="Start"/> <Button android:id="@+id/stopBtn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAllCaps="false" android:text="Stop"/> </LinearLayout>
public class MusicButtonActivity extends AppCompatActivity implements View.OnClickListener { private Button mStartButton; private Button mStopButton; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_music); mStartButton = findViewById(R.id.startBtn); mStopButton = findViewById(R.id.stopBtn); mStartButton.setOnClickListener(this); mStopButton.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.startBtn: // 启动服务 startService(new Intent(MusicButtonActivity.this, MusicService.class)); break; case R.id.stopBtn: // 关闭服务 stopService(new Intent(MusicButtonActivity.this, MusicService.class)); break; } } }
-
7.3.4 在activity_main.xml布局文件中添加一个Button按钮并设置点击事件
<Button android:id="@+id/musicBtn_service" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="music_service"/>
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button button = findViewById(R.id.musicBtn_service); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(MainActivity.this, MusicButtonActivity.class); startActivity(intent); } }); } }
-
7.3.5 在AndroidManifest.xml文件中添加 MusicButtonActivity和 MusicService
<activity android:name=".MusicButtonActivity"></activity> <service android:name=".MusicService"></service>
-
7.3.6 效果预览 [动态图片听不见音乐]
Bind :
当Android的应用程序组件通过bindService()绑定了服务,则服务是Bound状态。Bound状态的服务提供了一个客户服务器接口来允许组件与服务进行交互,如发送请求,获取结果,甚至通过IPC来进行跨进程通信。
-
7.3.3 创建ServiceConnection并实现接口中的方法
public class MusicButtonActivity extends AppCompatActivity implements View.OnClickListener { private Button mStartButton; private Button mStopButton; private MusicService musicService; // 实现 ServiceConnection private ServiceConnection mServiceConnection = new ServiceConnection() { /** * onServiceConnected(ComponentName name, IBinder service): IBinder是从 MusicService中的 onBind传递过来的, * 而 MusicService中的 onBind则是内部类 LocalBinder中创建的。LocalBinder中的方法用于获取当前的 Service。 * 所以这个 LocalBinder是一个桥梁,是沟通 Service 以及这个 Activity的桥梁,在这里可以存储一些数据,所以这时候 * 就可以把 MusicService得到。 * * @param name * @param service */ @Override public void onServiceConnected(ComponentName name, IBinder service) { MusicService.LocalBinder localBinder = (MusicService.LocalBinder) service; musicService = localBinder.getService(); } @Override public void onServiceDisconnected(ComponentName name) { } }; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_music); mStartButton = findViewById(R.id.startBtn); mStopButton = findViewById(R.id.stopBtn); mStartButton.setOnClickListener(this); mStopButton.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.startBtn: // 绑定服务 bindService(new Intent(MusicButtonActivity.this, MusicService.class), mServiceConnection, BIND_AUTO_CREATE); break; case R.id.stopBtn: // 解绑服务 unbindService(mServiceConnection); break; } } }
-
7.3.2 通过 LocalBinder获取 MusicService
public class MusicService extends Service { private static final String TAG = MusicService.class.getSimpleName(); private MediaPlayer mediaPlayer; // 创建 MediaPlayer对象 private IBinder mBinder = new LocalBinder(); @Override public void onCreate() { super.onCreate(); Log.i(TAG, "onCreate"); // 初始化 MediaPlayer mediaPlayer = MediaPlayer.create(this,R.raw.tianhou); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.i(TAG, "onStartCommand"); mediaPlayer.start(); return START_NOT_STICKY; } @Override public void onDestroy() { Log.i(TAG, "onDestroy"); mediaPlayer.stop(); super.onDestroy(); } @Nullable @Override public IBinder onBind(Intent intent) { return mBinder; } public class LocalBinder extends Binder { MusicService getService() { return MusicService.this; } } // 模拟数据 public int getMusicPlayProgress() { return 18; } }
First, go to bindService and pass in the connection, which will be passed to the service in LocalBinder.getService(), and then the service will pass back the mBinder of onBind(), that is to say, the connection just passed in will be passed in The IBinder in onServiceConnected() can receive the LocalBinder, and a getService() method is constructed in LocalBinder to return the current service. Through this method, we can get the service. Some public methods can be created in MusicService, the data can be obtained through the methods in MusicService object. At this time, MusicButtonActivity and MusicService can communicate.
什么场景下使用IntentService和Service
- 当你需要把你的任务按队列来分配时就用IntentService;只需要后台服务的用service