【Android】Service用法

Service

不是一个独立的进程,也不是线程

种类:Local,Remote
类型:前台,后台
启动方式:start ,Bind

在AndroidManifest.xml中声明:

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

service with start :

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;
    }
}

Service声明周期

在这里插入图片描述

service with bind:

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;
    }
}

工作流程:
Activity中的这句话(bindService(new Intent(MusicButtonActivity.this, MusicService.class), mServiceConnection, BIND_AUTO_CREATE);)会把connection传给service,service中的这句话(return mIBinder;)会把mIBinder传回去,传给刚才传进来的connection里,在Activity中就可以收到了:

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) {

        }
    };

Activity收到的IBinder对象含有关键信息,因为在service中这个IBinder对象中定义了getService方法,这样就可以在Activity中拿到Service了。

在service中定义了一些公共方法,如public int getMusicPlayProgress();,这样,在Activity中,通过service对象,就可以获取到这些公共方法了。

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){

    }
}

整个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){

        }
    }
}

注意

Service中不适合做耗时操作,它属于UI线程,所以要创建一个子线程去做耗时操作。

模板

MainActivity:

public class MainActivity extends AppCompatActivity {
    private MyService mMyService;
    private ServiceConnection mServiceConnection = new ServiceConnection(){
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            MyService.LocalBinder localBinder = (MyService.LocalBinder) service;
            mMyService = localBinder.getService();
        }
        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };

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


   public void startService(View view){
        startService(new Intent(MainActivity.this, MyService.class));
        bindService(new Intent(MainActivity.this, MyService.class), mServiceConnection, BIND_AUTO_CREATE);
    }

   public void stopService(View view){
        unbindService(mServiceConnection);
        stopService(new Intent(MainActivity.this, MyService.class));
    }

   public void updataProgress(View view){
        if(mMyService != null){
            int progress = mMyService.getProgress();
        }
    }
}

xml:

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/startService"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="start"
        android:onClick="startService"
        app:layout_constraintBottom_toTopOf="@+id/guideline2"
        app:layout_constraintEnd_toStartOf="@+id/guideline"
        app:layout_constraintStart_toStartOf="@+id/guideline"
        app:layout_constraintTop_toTopOf="@+id/guideline2" />

    <Button
        android:id="@+id/stopService"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Stop"
        android:onClick="stopService"
        app:layout_constraintBottom_toTopOf="@+id/guideline3"
        app:layout_constraintEnd_toStartOf="@+id/guideline"
        app:layout_constraintStart_toStartOf="@+id/guideline"
        app:layout_constraintTop_toTopOf="@+id/guideline3" />

    <Button
        android:id="@+id/updataProgress"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Update"
        android:onClick="updataProgress"
        app:layout_constraintBottom_toTopOf="@+id/guideline4"
        app:layout_constraintEnd_toStartOf="@+id/guideline"
        app:layout_constraintStart_toStartOf="@+id/guideline"
        app:layout_constraintTop_toTopOf="@+id/guideline4" />

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_percent="0.5" />

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent="0.2" />

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent="0.4" />

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent="0.6" />

</androidx.constraintlayout.widget.ConstraintLayout>

Service:

public class MyService extends Service {
    private static final String TAG = MyService.class.getSimpleName();
    private IBinder mIBinder = new MyService.LocalBinder();

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.i(TAG, "onStartCommand");
        // 开始工作
        // ...
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        Log.i(TAG, "onDestroy");
        // 停止工作
        // ...
        super.onDestroy();
    }
    
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Log.i(TAG, "onBind");
        return mIBinder;
    }

    public class LocalBinder extends Binder {
        MyService getService(){
            return MyService.this;
        }
    }

    public int getProgress(){
        return 18; // 可以自行定义逻辑
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值