App应用程序开发实验七 服务

本文介绍了如何在Android中使用后台Service实现音乐播放功能,包括服务的启动、暂停、停止操作,以及如何在主界面通过按钮控制服务。实验步骤详细描述了创建项目、布局文件、服务和主界面的Java代码实现。
摘要由CSDN通过智能技术生成

实验七 服务

一、实验目的

1.掌握Android服务的定义及类的写法。

2. 掌握Android启动服务、停止服务的方法。

3.掌握Android暂停服务的方法。

4.掌握Android音乐播放器的控制方法。

二、实验内容

1.完成使用后台Service进行音乐播放案例,主界面如下,包含4个按钮,播放按钮用来启动服务,播放音乐;暂停按钮暂停音乐播放;停止按钮停止音乐播放;退出按钮退出程序运行。

三、实验仪器、设备

硬件:PC 微型计算机、8G以上内存、500G以上硬盘。

软件:Windows 7/10、Android Studio (Eclipse)、JDK、Android SDK。

四、实验步骤

1.布局:

① 建立android项目。

② 编辑布局文件activity_main.xml。

<?xml version="1.0" encoding="utf-8"?>
<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"
    tools:context=".MainActivity">
    <LinearLayout
        android:id="@+id/linear1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:gravity="center_horizontal"
        android:orientation="horizontal" >
        <Button
            android:id="@+id/play"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="20dp"
            android:layout_weight="1"
            android:text="播放" />
        <Button
            android:id="@+id/pause"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginRight="20dp"
            android:layout_weight="1"
            android:text="暂停" />
    </LinearLayout>
    <LinearLayout
        android:id="@+id/linear2"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:gravity="center_horizontal"
        android:orientation="horizontal" >
        <Button
            android:id="@+id/stop"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="20dp"
            android:layout_weight="1"
            android:text="停止" />
        <Button
            android:id="@+id/exit"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginRight="20dp"
            android:layout_weight="1"
            android:text="退出" />
    </LinearLayout>
</LinearLayout>

③主界面控制的源文件java。

import androidx.appcompat.app.AppCompatActivity ;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity implements OnClickListener {
    private Intent intent;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button playBtn = (Button) findViewById(R.id.play);
        Button stopBtn = (Button) findViewById(R.id.stop);
        Button pauseBtn = (Button) findViewById(R.id.pause);
        Button exitBtn = (Button) findViewById(R.id.exit);
        playBtn.setOnClickListener(this);
        stopBtn.setOnClickListener(this);
        pauseBtn.setOnClickListener(this);
        exitBtn.setOnClickListener(this);
    }

    public void onClick(View v) {
        int num = -1;
        intent = new Intent(this,MusicService.class);
        switch (v.getId()) {
            case R.id.play:
           Toast.makeText(this, "play music...", Toast.LENGTH_SHORT).show();
                num = 1;
                break;
            case R.id.stop:
          Toast.makeText(this, "stop music...", Toast.LENGTH_SHORT).show();
                num = 2;
                break;
            case R.id.pause:
         Toast.makeText(this, "pause music...", Toast.LENGTH_SHORT).show();
                num = 3;
                break;
            case R.id.exit:
                Toast.makeText(this, "exit...", Toast.LENGTH_SHORT);
                num = 4;
                stopService(intent);
                this.finish();
                return;
        }
        Bundle bundle = new Bundle();
        bundle.putInt("music", num);
        intent.putExtras(bundle);
        startService(intent);
    }
    @Override
    public void onDestroy(){
        super.onDestroy();
        if(intent != null){
            stopService(intent);
        }
    }
}

④后台Service服务源代码。

import java.io.IOException;
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;

public class MusicService extends Service {
    private static final String TAG = "MusicService";
    private MediaPlayer mediaPlayer;
    private boolean reset = false;
    public MusicService() {
    }
    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }
    @Override

    public void onCreate() {
        Log.v(TAG, "onCreate");
        if (mediaPlayer==null) {
            mediaPlayer = MediaPlayer.create(this, R.raw.lake);
            mediaPlayer.setLooping(false);
        }
    }

    @Override
    public void onDestroy() {
        Log.v(TAG, "onDestroy");
        if (mediaPlayer != null) {
            mediaPlayer.stop();
            mediaPlayer.release();
        }
    }

    @Override
    public void onStart(Intent intent, int startId) {
        Log.v(TAG, "onStart");
        if (intent != null) {
            Bundle bundle = intent.getExtras();
            if (bundle != null) {
                int num = bundle.getInt("music");
                switch (num) {
                    case 1:
                        play();
                        break;
                    case 2:
                        stop();
                        break;
                    case 3:
                        pause();
                        break;

                }
            }
        }
    }

    public void play() {
        Log.v(TAG, "-----------" + reset + "----------");
        if (mediaPlayer==null)
            return;
        if (reset==true)
            mediaPlayer.seekTo(0);
        if (!mediaPlayer.isPlaying()) {
            mediaPlayer.start();
        }
    }

    public void pause() {
        reset = false;
        if (mediaPlayer != null && mediaPlayer.isPlaying()) {
            mediaPlayer.pause();
        }
    }

    public void stop() {
        reset = true;
        if (mediaPlayer != null) {
            mediaPlayer.stop();
            try {
                mediaPlayer.prepare(); // 在调用stop 后如果需要再次通过 start进行播放,需要之前调用 prepare函数
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }
}

2.在res下创建raw文件夹,拷贝mp3文件lake.mp3到raw下。

3.清单文件AndroidManifest.xml。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.sun.ch7">
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <service
            android:name=".MusicService"
            android:enabled="true"
            android:exported="true"></service>

        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

4.运行,调试。

5.播放器播放方式改为“循环播放” 

① 修改MusicServic.java文件

import java.io.IOException;
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;

public class MusicService extends Service {
    private static final String TAG = "MusicService";
    private MediaPlayer mediaPlayer;
    private boolean reset = false;
    public MusicService() {
    }
    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }
    @Override

    public void onCreate() {
        Log.v(TAG, "onCreate");
        if (mediaPlayer==null) {
            mediaPlayer = MediaPlayer.create(this, R.raw.lake);
            mediaPlayer.setLooping(false);
        }
    }

    @Override
    public void onDestroy() {
        Log.v(TAG, "onDestroy");
        if (mediaPlayer != null) {
            mediaPlayer.stop();
            mediaPlayer.release();
        }
    }

    @Override
    public void onStart(Intent intent, int startId) {
        Log.v(TAG, "onStart");
        if (intent != null) {
            Bundle bundle = intent.getExtras();
            if (bundle != null) {
                int num = bundle.getInt("music");
                switch (num) {
                    case 1:
                        play();
                        break;
                    case 2:
                        stop();
                        break;
                    case 3:
                        pause();
                        break;

                }
            }
        }
    }

    public void play() {
        Log.v(TAG, "-----------" + reset + "----------");
        if (mediaPlayer==null)
            return;
        if (reset==true)
            mediaPlayer.seekTo(0);

        if (!mediaPlayer.isPlaying()) {
            mediaPlayer.start();
            mediaPlayer.setLooping(true);
        }
    }

    public void pause() {
        reset = false;
        if (mediaPlayer != null && mediaPlayer.isPlaying()) {
            mediaPlayer.pause();
        }
    }
    public void stop() {
        reset = true;
        if (mediaPlayer != null) {
            mediaPlayer.stop();
            try {
                mediaPlayer.prepare(); // 在调用stop 后如果需要再次通过 start进行播放,需要之前调用 prepare函数
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }

}

②运行,调试。

五、实验思考题

  1 说明服务Service函数的主要分类以及区别?

答:主要分类:按前后台、按远程服务与本地服务、按是否可以通信。

区别:

1.前后台: 前台服务执行一些用户能注意到的操作。后台服务执行用户不会直接注意到的操作

2.远程服务与本地服务:远程服务运行在独立进程,需要进行 IPC 通讯(AIDL, Messenger),服务后台运行, 不受Activity影响。本地服务跟主体应用同一进程,运行在主线程, 耗时任务需开子线程,主进程被杀死, 服务也会终止,单实例。

3.是否可以通信:startService()不可通信。bindService()通过 ServiceConnection 接收 Service 中 onBind() 函数 返回的 IBinder 对象 进行通讯

2 Service启动方式主要有两种startservice和bindservice,有何不同之处?

答:1.startService启动服务:Service会经历onCreate()------->onStartCommand()。当执行stopService时,直接调用onDestroy方法。调用者如果没有stopService,Service会一直在后台运行,下次调用者再次启动仍然可以stopService。多次调用startService,该Service只能被创建一次,即该Service的onCreate()只会被调用一次。但是每次调用startService,onStartCommand()都会被调用。

2.Service会经历onCreate()----->onBind()。这个时候调用者和Service捆绑在一起。调用者调用unbindService方法或者调用者Context不存在了(如Activity被finish(销毁)了),Service就会调用onUnbind()------>onDestroy()。第一次执行bindService时,onCreate()和onBind()会被调用,但是多次执行bindService时,onCreate()和onBind()方法并不会被多次调用,即并不会多次创建服务和绑定服务。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小孙同学1024

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值