Servicio
No es un proceso separado, ni un hilo
Dos tipos: iniciar y enlazar
Declarado en AndroidManifest.xml:
<service android:name=".MusicService" />
servicio con inicio:
package com.jsc4.aboutactivity;
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.IBinder;
import android.util.Log;
import androidx.annotation.Nullable;
public class MusicService extends Service {
private static final String TAG = MusicService.class.getSimpleName();
private MediaPlayer mMediaPlayer;
@Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "onCreate");
mMediaPlayer = MediaPlayer.create(this, R.raw.lovelove);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "onStartCommand");
mMediaPlayer.start();
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
Log.i(TAG, "onDestroy");
mMediaPlayer.stop();
super.onDestroy();
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
Log.i(TAG, "onBind");
return null;
}
}
Ciclo de vida del servicio
servicio con enlace:
MusicButtonActivity.java
package com.jsc4.aboutactivity;
import androidx.appcompat.app.AppCompatActivity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.view.View;
import android.widget.Button;
public class MusicButtonActivity extends AppCompatActivity implements View.OnClickListener {
private Button mStartButton;
private Button mStopButton;
private MusicService mMusicService;
private ServiceConnection mServiceConnection = new ServiceConnection(){
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
MusicService.LocalBinder localBinder = (MusicService.LocalBinder) service;
mMusicService = localBinder.getService();
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_music_button);
mStartButton = findViewById(R.id.start_music_button);
mStopButton = findViewById(R.id.stop_music_button);
mStartButton.setOnClickListener(this);
mStopButton.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch(v.getId()){
case R.id.start_music_button:
startService(new Intent(MusicButtonActivity.this, MusicService.class));
bindService(new Intent(MusicButtonActivity.this, MusicService.class), mServiceConnection, BIND_AUTO_CREATE);
break;
case R.id.stop_music_button:
unbindService(mServiceConnection);
stopService(new Intent(MusicButtonActivity.this, MusicService.class));
break;
case R.id.get_music_progress_button:
if(mMusicService != null){
int progress = mMusicService.getMusicPlayProgress();
}
break;
}
}
}
MusicService.java
package com.jsc4.aboutactivity;
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
import androidx.annotation.Nullable;
public class MusicService extends Service {
private static final String TAG = MusicService.class.getSimpleName();
private MediaPlayer mMediaPlayer;
private IBinder mIBinder = new LocalBinder();
@Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "onCreate");
mMediaPlayer = MediaPlayer.create(this, R.raw.lovelove);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "onStartCommand");
mMediaPlayer.start();
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
Log.i(TAG, "onDestroy");
mMediaPlayer.stop();
super.onDestroy();
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
Log.i(TAG, "onBind");
return mIBinder;
}
public class LocalBinder extends Binder {
MusicService getService(){
return MusicService.this;
}
}
public int getMusicPlayProgress(){
return 18;
}
}
Flujo de trabajo:
la oración ( bindService(new Intent(MusicButtonActivity.this, MusicService.class), mServiceConnection, BIND_AUTO_CREATE);
) en la actividad pasará la conexión al servicio, y la oración ( return mIBinder;
) en el servicio pasará el miBinder de nuevo a la conexión que acaba de pasar, y puede recibirlo en la actividad:
private ServiceConnection mServiceConnection = new ServiceConnection(){
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
MusicService.LocalBinder localBinder = (MusicService.LocalBinder) service;
mMusicService = localBinder.getService();
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
El objeto IBinder recibido por Activity contiene información clave, porque el método getService está definido en el objeto IBinder en el servicio, así que eso es todo 在Activity中拿到Service
.
Algunos están definidos en el servicio 公共方法
Por ejemplo public int getMusicPlayProgress();
, en Actividad, estos métodos públicos se pueden obtener a través del objeto de servicio.
IntentService
activity中:
Intent intent = new Intent(MusicButtonActivity.this, MusicService.class);
intent.putExtra("msg", "携带的信息");
startService(intent);
IntentService中:
@Override
protected void onHandleIntent(@Nullable Intent intent) {
// intent队列 排队,像MessageQueue 同步操作:排队领书,处理Intent数据
// stopSelf(); // 停止本身,此处不必使用
if(intent != null){
}
}
Todo el IntentService:
package com.jsc4.aboutactivity;
import android.app.IntentService;
import android.content.Intent;
import androidx.annotation.Nullable;
public class TestIntentService extends IntentService {
/**
* Creates an IntentService. Invoked by your subclass's constructor.
*
* @param name Used to name the worker thread, important only for debugging.
*/
public TestIntentService(String name) {
super(name);
}
@Override
public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
// do more work is wrong UI线程 > 10s时,ANR(应用程序无响应)
// 把耗时操作放到子线程中
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
}
});
thread.start();
return super.onStartCommand(intent, flags, startId);
}
@Override
protected void onHandleIntent(@Nullable Intent intent) {
// intent队列 排队,像MessageQueue 同步操作:排队领书,处理Intent数据
// stopSelf(); // 停止本身,此处不必使用
if(intent != null){
}
}
}
Nota
El servicio no es adecuado para operaciones que requieren mucho tiempo. Pertenece al subproceso de la interfaz de usuario, por lo que se debe crear un subproceso secundario para realizar operaciones que requieren mucho tiempo.