大作业---Android本地音乐播放器开发知识点19145120

article/2025/10/24 1:55:36

步骤

  • 系列文章
  • 前言
      • 1. 简述程序、进程、线程的区别和联系。(10分)
      • 2. 什么是UI线程??什么是工作线程?(10分)
      • 3. 如何定义1个结构良好可控的工作线程(源代码说明)?(10分)
      • 4. 工作线程什么时间需要与UI线程进行通信?又如何与UI线程进行通信(源代码说明)?(10分)
      • 5. 手机中MediaPlayer类生成对象的2种方法分别是什么(举例说明)?有什么不同??(10分)
      • 6. MediaPlayer类的OnPreparedListener、OnCompletionListener监听器有什么作用??(10分)
      • 7. 使用MediaPlayer类如何才能自动播放音乐(源代码说明)?如何修改界面外观(源代码说明)?(10分)
      • 8. 请简单解释SeekBar类的3个监听方法。(10分)
      • 9. Service类该如何派生出(源代码说明,并解释每个方法的作用)?
    • 10. 10. Service后台程序如何与前台Acvtity进行相互(双向)通信(源代码说明)?(10分)
      • 10.1绑定服务的方式,实现ServiceConnection接口
      • 10.2利用广播方式
  • 总结

系列文章

提示:转到安卓学习专栏,观看更多内容!
点我直达–>安卓学习专栏


前言

大作业—Android本地音乐播放器开发知识点,稍后源代码放出。(MZH-学号19145120)
Android本地音乐播放器源码 https://blog.csdn.net/u011027547/article/details/122376235


1. 简述程序、进程、线程的区别和联系。(10分)

简述程序、进程、线程:
多线程:是指一个应用程序同时执行多个任务,一般来说一个任务就是一个线程 ,而一个应用程序有一个以上的线程我们称之为多线程。

进程:进程是一个正在执行的程序 ,比如QQ,迅雷等 一个进程的运行会向CPU申请在内存中开辟一个内存块。
进程是向CPU申请资源的,进程之间数据相互独立,一个进程至少有一个线程。

线程:线程是进程中的单一的顺序控制流程也可以叫做最小控制单元,线程是进程中执行单元,开启一个线程比开启一个进程更加节省资源。

程序、进程、线程的区别:
笼统的说区别:
1)程序只是一组指令的有序集合,它本身没有任何运行的含义,它只是一个静态的实体。
2)进程是动态的一个独立实体。
3)线程是进程的更小的组成单元,是一个动态的基本单元。一个程序至少有一个进程,一个进程至少有一个线程.。

进程和线程的区别:
一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程。线程是操作系统可识别的最小执行和调度单位。
资源分配给进程,同一进程的所有线程共享该进程的所有资源。 同一进程中的多个线程共享代码段(代码和常量),数据段(全局变量和静态变量),扩展段(堆存储)。但是每个线程拥有自己的栈段,栈段又叫运行时段,用来存放所有局部变量和临时变量。
处理机分给线程,即真正在处理机上运行的是线程。
线程在执行过程中,需要协作同步。不同进程的线程间要利用消息通信的办法实现同步。

地址空间:同一进程的线程共享本进程的地址空间,而进程之间则是独立的地址空间。
资源拥有:同一进程内的线程共享本进程的资源如内存、I/O、cpu等,但是进程之间的资源是独立的。


2. 什么是UI线程??什么是工作线程?(10分)

UI线程
当一个程序第一次启动时,Android会同时启动一个对应的主线程(Main Thread),主线程主要负责处理与UI相关的事件,如:用户的按键事件,用户接触屏幕的事件以及屏幕绘图事件,并把相关的事件分发到对应的组件进行处理。所以主线程通常又被叫做UI线程。

工作线程
没有界面的称之为工作者线程。工作者线程默认是没有消息队列的,比如UI中一个按钮触发一个很耗时间的复杂计算,这个计算过程就可以通过一个工作者线程来实现。


3. 如何定义1个结构良好可控的工作线程(源代码说明)?(10分)

在这里插入图片描述

public Handler handler=new Handler(){@Overridepublic void handleMessage(@NonNull Message msg) {switch (msg.what){case -100:moveTaskToBack(true);}}
};private class Work extends Thread{@Overridepublic void run() {try {sleep(5000);Message mm=Message.obtain();mm.what=-100;handler.sendMessage(mm);}catch (InterruptedException e){e.printStackTrace();}}
}

4. 工作线程什么时间需要与UI线程进行通信?又如何与UI线程进行通信(源代码说明)?(10分)

什么时间需要与UI线程进行通信:

Android多线程的Handler—实现工作线程通知Main线程修改界面。Handler是一套 Android 消息传递机制。在多线程的应用场景中,将工作线程中需更新UI的操作信息传递到UI主线程,从而实现工作线程对UI的更新处理,最终实现异步消息的处理。

只要需要GDI的调用,需要产生UI的变化的时候需要进行通信。工作者线程原本是没有消息队列,但是你可以强制加一个,一般只要你的线程中出现了GDI的调用就会出现一个消息队列,线程中如果调用了GetMessage(),就可以强制加入了一个消息循环,系统就会给该线程加一个消息队列,同样用PeekMessage()也可以强制系统加入一个消息队列.工作者线程的消息传递是通过PostThreadMessage函数发送的。即:工作线程函数里面如果调用了有关消息的函数,操作系统自动为工作线成创建消息队列。

与UI线程进行通信的源代码:

public void run() {try {sleep(5000);Message mm=Message.obtain();mm.what=-100;handler.sendMessage(mm);}catch (InterruptedException e){e.printStackTrace();}
}

5. 手机中MediaPlayer类生成对象的2种方法分别是什么(举例说明)?有什么不同??(10分)

生成1个MediaPlayer类的对象
创建MediaPlaer对象有两种方式:
a、直接new出来

MediaPlayer  mp = new   MediaPlayer( );

b、使用create方式

MediaPlayer  mp = MediaPlayer. create( this, R.raw.test );

区别在于第二种方法中R.raw.test:资源中的音乐文件,这时就不用调用setDataSource了


6. MediaPlayer类的OnPreparedListener、OnCompletionListener监听器有什么作用??(10分)

OnPreparedListener:
只有在准备结束后才能调用getDuration()方法,如果在之前调用getDuration()会出现IllegalStateException异常。

player.prepareAsync(); // 当player已准备结束的时候player.setOnPreparedListener(new OnPreparedListener() {public void onPrepared(MediaPlayer mp) {seekbar.setMax(player.getDuration());player.start();}});

OnCompletionListener:

    处理播放结束后的操作。由于player占有的系统资源比较大,因此在播放结束后,就应该调用该方法,把player占有的资源给释放掉。示例:
player.setOnCompletionListener(new OnCompletionListener() {public void onCompletion(MediaPlayer mp) {player.release();//播放结束后,就自动释放player的资源。seekbar.setProgress(0);//将seekbar还原。}});

7. 使用MediaPlayer类如何才能自动播放音乐(源代码说明)?如何修改界面外观(源代码说明)?(10分)

使用MediaPlayer类自动播放音乐:

@Override
public int onStartCommand(Intent intent, int flags, int startId) {action=intent.getStringExtra("action");index=intent.getIntExtra("index",0);progress=intent.getIntExtra("progress",0);Ok=intent.getBooleanExtra("ok",true);switch (action){case "play"://-------启动int tt=0;if (mp.isPlaying()==false){mp.start();work.ok=true;tt=1;}else {mp.pause();work.ok=false;tt=-1;}Message mm=Message.obtain();mm.what=200;mm.arg1=tt;MainActivity.hh.sendMessage(mm);break;case "click":Goto();break;case "prev":Goto();break;case "next":Goto();break;case "change":mp.seekTo(progress);work.ok=Ok;break;}return super.onStartCommand(intent, flags, startId);
}

修改界面外观:

public static Handler hh=new Handler(){@Overridepublic void handleMessage(@NonNull Message msg) {switch (msg.what){case 100:SendData sendData=(SendData) msg.obj;progress=sendData.progress;max=sendData.max;index=sendData.index;sb.setMax(max);sb.setProgress(progress);tv_time.setText(MP3Utils.timeParse(progress)+"/"+MP3Utils.timeParse(max));tv_title.setText(list.get(index).getTitle());break;case 200:int tt=msg.arg1;//设置按钮图片if (tt==1){img_play.setImageResource(R.drawable.stop);//点击后设置为stop图片,此时音乐不播放}if (tt==-1){img_play.setImageResource(R.drawable.play);}break;case 300:max=0;progress=0;img_play.setImageResource(R.drawable.stop);//点击后设置为stop图片,此时音乐不播放sb.setProgress(0);tv_time.setText("00:00/00:00");//设置时间清零tv_title.setText("等待加载歌曲信息");//设置歌曲标题清零break;}}
};public Handler handler=new Handler(){@Overridepublic void handleMessage(@NonNull Message msg) {switch (msg.what){case -100:moveTaskToBack(true);}}
};

8. 请简单解释SeekBar类的3个监听方法。(10分)

3个监听方法:

onProgressChanged:进度发生改变时会触发
onStartTrackingTouch:按住SeekBar时会触发
onStopTrackingTouch:放开SeekBar时触发

示例代码:

public class MainActivity extends AppCompatActivity {private SeekBar sb_normal;private TextView txt_cur;private Context mContext;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mContext = MainActivity.this;bindViews();}private void bindViews() {sb_normal = (SeekBar) findViewById(R.id.sb_normal);txt_cur = (TextView) findViewById(R.id.txt_cur);sb_normal.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {@Overridepublic void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {txt_cur.setText("当前进度值:" + progress + "  / 100 ");}@Overridepublic void onStartTrackingTouch(SeekBar seekBar) {Toast.makeText(mContext, "触碰SeekBar", Toast.LENGTH_SHORT).show();}@Overridepublic void onStopTrackingTouch(SeekBar seekBar) {Toast.makeText(mContext, "放开SeekBar", Toast.LENGTH_SHORT).show();}});}
}

9. Service类该如何派生出(源代码说明,并解释每个方法的作用)?

Service启动方式:调用Context.startService()
Service停止方式:调用Context.stopService()Service.stopSefl()

• 服务管理(startService()启动Service )

public class MyService extends Service{@Overridepublic IBinder onBind(Intent intent) {	return null;	}@Overridepublic void onCreate() {	super.onCreate();  		}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {return super.onStartCommand(intent, flags, startId);}@Overridepublic void onDestroy() { 	super.onDestroy();		}
}

• 服务管理(注册服务 )
在这里插入图片描述
在这里插入图片描述

• 服务管理(startService()启动和停止 )

在这里插入图片描述


10. 10. Service后台程序如何与前台Acvtity进行相互(双向)通信(源代码说明)?(10分)

10.1绑定服务的方式,实现ServiceConnection接口

bindService() - unbindService()

10.1.1进行数据传递
Service中声明一个Binder类,类中声明用来传递数据的方法。比如向Activity返回Service实例/接受或返回数据。
Activity实现ServiceConnection接口,Activity绑定Service调用bindService()方法。此时onServiceConnected()方法就会被调用。此方法中利用获取的Binder实例,可以调用Service中各个用来传递数据的方法。
这就实现了Activity向Service传递数据,Service接收数据进行数据操作后,再返回给Activity。

10.1.2.Activity监听Service数据变化

Service自定义Callback接口,声明监听数据的抽象函数onDataChange(String data),参数data用来向外部暴露data数据,并设置callback实例的setter方法。再onCreat()方法中,Service利用接收来的data数据,进行耗时操作后(例如开启线程进行data的循环递增),用callback.onDataChange(data + “”)暴露data数据。
Activity在onServiceConnected()方法中,利用获取的Service实例调用setCallback()方法,同时实例化Callback接口,进行接口回调实现onDataChange()函数,此时就监听到了Service中data数据的状态,并利用Handler进行更新UI操作。

@Override
public void onCreate() {super.onCreate();try {mp=new MediaPlayer();String ss= MainActivity.list.get(index).getUrl();Uri uri=Uri.parse(ss);mp.setDataSource(this,uri);mp.setOnPreparedListener(this);mp.setOnCompletionListener(this);mp.setOnErrorListener(this);mp.prepareAsync();work=new Work();work.start();}catch (IOException e){e.printStackTrace();}
}//--------------------------------------------
private void Goto(){work.ok=false;mp.stop();mp.reset();if (index>=MainActivity.list.size()){index=0;}if (index<0){index=MainActivity.list.size()-1;}try {String ss=MainActivity.list.get(index).getUrl();Uri uri=Uri.parse(ss);mp.setDataSource(this,uri);mp.setOnPreparedListener(this);mp.prepareAsync();mp.start();work.ok=true;}catch (IOException e){e.printStackTrace();}
}

10.2利用广播方式

startService() - stopService()

Activity:动态注册广播 。将data存储到intent中,调用startService(intent)开启服务。
Service:重写onStartCommand()方法,利用intent.getXXExtra()获取Activity传来的数据。对数据进行操作后,将data存到intent中并发送广播。
Activity:接收广播,重写onReceive()函数,开启主线程并从intent中取出data数据,进行更新UI操作。
利用广播和intent实现了数据通信和监听服务数据状态。

MyService.java

public class MyService3 extends Service {private boolean connecting = false;public static final String COUNTER = "data";public static final String ACTION_NAME = "com.example.myinterview.service3.COUNTER_ACTION";private int data;@Overridepublic IBinder onBind(Intent intent) {return null;}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {//从Activity获取datadata = intent.getIntExtra(COUNTER, 0);final Intent mIntent = new Intent();mIntent.setAction(ACTION_NAME);connecting = true;//开启一个线程,对数据进行处理new Thread(new Runnable() {@Overridepublic void run() {try {while (connecting) {//耗时操作:数据处理并保存,向Activity发送广播mIntent.putExtra(COUNTER, data);sendBroadcast(mIntent);data++;Thread.sleep(300);}} catch (InterruptedException e) {e.printStackTrace();}}}).start();return START_STICKY;}@Overridepublic void onDestroy() {super.onDestroy();connecting = false;}
}

ServiceActivity3.java

public class ServiceActivity3 extends AppCompatActivity implements View.OnClickListener {private int TransforData;private TextView textView;private Intent mIntent;private MyReceiver myReceiver;private boolean bind = false;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_service3);TransforData = 0;textView = (TextView) findViewById(R.id.textView);Button startBtn = (Button) findViewById(R.id.mstart);Button pauseBtn = (Button) findViewById(R.id.pause);Button clearBt = (Button) findViewById(R.id.clear);startBtn.setOnClickListener(this);pauseBtn.setOnClickListener(this);clearBt.setOnClickListener(this);mIntent = new Intent(this, MyService3.class);myReceiver = new MyReceiver();IntentFilter intentFilter = new IntentFilter();intentFilter.addAction(MyService3.ACTION_NAME);//注册广播registerReceiver(myReceiver, intentFilter);}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.mstart:if (!bind) {bind = true;//向Service传递datamIntent.putExtra(MyService3.COUNTER, TransforData);startService(mIntent);Toast.makeText(this, "Start!", Toast.LENGTH_SHORT).show();}break;case R.id.pause://停止服务stopService(mIntent);bind = false;break;case R.id.clear:if (!bind) {TransforData = 0;textView.setText("0");Toast.makeText(this, "Pause!", Toast.LENGTH_SHORT).show();}break;default:break;}}class MyReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, final Intent intent) {runOnUiThread(new Runnable() {@Overridepublic void run() {//获取从Service中传来的dataTransforData = intent.getIntExtra(MyService3.COUNTER, 0);//更新UItextView.setText(String.valueOf(TransforData));}});}}@Overrideprotected void onDestroy() {stopService(mIntent);unregisterReceiver(myReceiver);super.onDestroy();}
}

总结

大家喜欢的话,给个👍,点个关注!继续跟大家分享敲代码过程中遇到的问题!



http://chatgpt.dhexx.cn/article/7o72LBDD.shtml

相关文章

Android入门之本地音乐播放器

功能简介 读取模拟器中音乐文件&#xff1b;列表展示&#xff0c;获取歌曲详细信息&#xff1a;歌名、歌手名、专辑名、专辑封面、播放时间等&#xff1b;基本功能&#xff1a;上下切歌&#xff0c;播放暂停、进度条显示与点击跳转。成品效果图&#xff1a; Mediaplayer基本…

大学生安卓期末设计之本地音乐播放器

作为一个热爱设计交互性产品的男大学生&#xff0c;我真的不太爱听课&#xff0c;所以很多时候&#xff0c;需要一个人学会阅读搜索资料并不停尝试&#xff0c;我希望大家也多多热爱这样持之以恒的尝试。 先看产品的一个模拟机测试效果&#xff08;b站南阳洛信也有视频) 安卓A…

Android本地音乐播放器

UI界面模仿QQ音乐 实现一个简单的本地播放器&#xff0c;功能包括&#xff1a;播放&#xff0c;暂停&#xff0c;上一曲&#xff0c;下一曲&#xff0c;进度条。 功能实现 读取本地音乐 1.创建一个Song类 public class Song {public String song;//歌曲名public String sing…

毕业设计- 基于Android的本地音乐播放器

—— 木叶飞舞之处&#xff0c;火亦生生不息。 项目介绍 本系统支持扫瞄本地音乐播放、暂停、上一首、下一首&#xff0c;点击播放栏跳转到播放页面&#xff0c;可查看当前播放列表&#xff0c;设置播放模式如顺序播放、随机播放&#xff0c;标记为我的喜欢&#xff0c;可以创…

Selenium自动化测试设计模式-PO模式

前言&#xff1a; 在python自动化过程中&#xff0c;Selenium自动化测试中有一个名字常常被提及PageObject&#xff08;思想与面向对象的特性相同&#xff09;&#xff0c;通过PO模式可以大大提高测试用例的维护效率。 不了解po设计模式的可自行百度 面向对象的特性&#xf…

电商项目测试实战(十一)后台业务场景测试设计

后台订单处理业务场景测试设计 流程步骤&#xff1a; 设计测试用例&#xff1a; 第一步&#xff1a;绘制流程图 1、确认业务中的操作 2、分析执行的顺序 3、按照业务方向进行连线 收到前台订单&#xff08;商城->订单->订单列表&#xff09;订单确认发货&#xff0…

电商项目测试实战(十)前台下单业务场景测试设计

前台下单业务场景测试设计 流程步骤&#xff1a; 设计测试用例&#xff1a; 第一步&#xff1a;需求分析 第二步&#xff1a;绘制流程图 1、确定业务中的操作 2、分析执行的顺序 3、按照业务方向进行连线 登录->选购商品->加入购物车->支付->确认订单->等待…

空调测试用例设计

** 空调测试用例设计 ** 界面测试 功能测试 可靠性测试 易用性测试 可维护性测试 兼容性测试 竞品测试 负载压力测试 稳定性测试 文档测试 界面测试&#xff1a; 空调外观的美观性空调外观尺寸是否和设计尺寸一致遥控按钮是否清晰和易懂显示温度及模式的显示屏是否显示设备…

测试场景设计-登录设计

来一波广告&#xff1a;欢迎关注测者说&#xff0c;测试理论知识尽在此处 面试中经常被问到有一个登录页面&#xff0c;你怎么设计测试场景&#xff0c;原来可以做到这么细致。 具体需求&#xff1a; 有一个登陆页面&#xff0c;&#xff08;假如上面有2个textbox,一个提交按钮…

基于微信小程序的大学生心理健康测试设计与实现 .docx

目录 1 绪论 3 1.1 项目开发背景 3 1.2 项目开发意义 3 1.3 项目主要的内容 4 2 相关技术介绍及系统环境开发条件 5 2.1相关技术介绍 5 2.2系统环境开发条件 6 3 系统的需求分析与设计 6 3.1可行性分析 7 3.2需求分析 7 3.2.1系统总体概述 8 3.2.2功能性需求 8 3.2.3非功能性需…

测试设计技术

本文是根据测试架构师修炼之道&#xff08;第二部分 突破&#xff1a;向软件测试架构师的目标迈进&#xff09;整理的&#xff0c;主要分为5个小部分&#xff1a;测试设计四步走、测试设计软技能、设计技术之控制用例粒度、设计技术之自动化测试、设计技术之探索式测试。学习的…

数字系统的测试与可测试设计(DFT)

数字系统的测试与可测试设计&#xff08;DFT&#xff09; 背景介绍1 Defects1.1 名词解释1.2 缺陷种类1.2.1 Physical Defects物理缺陷1.2.2 Shorting Defects1.2.2.1 Gate-Oxide-Shorts1.2.2.2 Bridge1.2.2.1 Open1.2.2.1 Post-fabrication failures 2 Fault Modelling&#x…

2. 测试分析与测试设计

1. 为什么要做好测试分析和测试设计 以业务驱动测试&#xff1a;当下的测试圈子内&#xff0c;大家一直在强调自动化技术、DevOps等&#xff0c;这些是提高效率和质量的利器&#xff0c;但是所有有效的测试行为&#xff0c;都是建立在对业务需求有正确的理解和分析的基础上的。…

软件测试之---测试设计方法

二、测试设计方法&#xff08;黑盒测试设计方法&#xff1b;白盒测试设计方法&#xff09; 1、等价类划分法 1.1等价类划分法概念 将输入&#xff08;输出&#xff09;域划分成若干个子集合&#xff0c;从划分的子集合中选取代表数据&#xff0c;如果选取的数据测试没有问题&…

测试用例:四步测试设计法

读者提问&#xff1a; 阿常&#xff0c;上节我们讲到测试点不等同于测试用例&#xff0c;想请教你一下&#xff0c;如何把测试点加工成测试用例呢&#xff1f; 目前团队中测试人员针对同样的测试点&#xff0c;编写出来的测试用例各不相同&#xff0c;一千个人就有一千个哈姆雷…

常用测试设计方法

目录 1、按照开发阶段划分&#xff08;1&#xff09;单元测试(模块测试)&#xff08;2&#xff09;集成测试(组装测试)&#xff08;3&#xff09;确认测试(有效性测试)&#xff08;4&#xff09;系统测试&#xff08;5&#xff09;验收测试 2、按照代码运行划分&#xff08;1&a…

大数据基础概述

大数据基础概述 1.前言2.大数据技术发展的三个阶段3.大数据技术面临的问题4.大数据技术数据的特点5.大数据对各方面的影响6.大数据技术的应用领域7.大数据技术的相关概念8.大数据技术的相关产业9.云计算和物联网 1.前言 三次信息浪潮 信息化浪潮发生时间标志解决问题代表企业第…

大数据概论

大数据big data指无法在一定时间范围内用常规软件工具进行捕捉、管理和处理的数据集合&#xff0c;是需要新 处理模式才能具有更强的决策力、洞察发现力和流程优化能力的海量、高增长率和多样化的信息资产。大量数据资源为解决以前不可能解决的问题带来了可能性。1大数据不一定…

大数据技术概论

大数据技术概论 大数据技术的产生 大数据的基本概念 ●大数据简介: 大数据是规模非常巨大和复杂的数据集,传统数据库管理工具处理起来面临很多问题,比如说获取、存储、检索、共享、分析和可视化,数据量达到PB、EB或ZB的级别。 大数据有三个V: 一是数据量(Volume),数据量是持续…

2【源码】数据可视化:基于 Echarts + Java SpringBoot 实现的动态实时大屏范例-物流大数据

数据可视化大屏的出现&#xff0c;掀起一番又一番的浪潮&#xff0c;众多企业纷纷想要打造属于自己的“酷炫吊炸天”的霸道总裁大屏驾驶舱。 之前小伙伴们建议我出一些视频课程来学习Echarts&#xff0c;这样可以更快上手&#xff0c;所以我就追星赶月的录制了《Echarts - 0基…