前言
前几天身体不适,难以将自己定下的目标进行可持续化,整理一些之前写过的笔记来应对一下自己的懒惰,顺便想办法对自己曾学过的Android进行一次回忆。
嗯,现阶段正在调养(苦笑),而且我需要一段时间对Spring进行思维上的整理
正文
Service是什么
Service是一个后台运行的组件,执行长时间运行且不需要用户交互的任务。即使应用被销毁也依然可以工作。
++Service需要在AndroidManifest.xml中进行注册!++1
2
Service的状态
启动方式启动(Started状态):startService() 启动后,若后台不自动清理,即使启动它的组件被销毁,也会无限期运行下去
绑定方式启动(Bound状态):bindService()绑定了服务,Bound状态的服务提供了一个客户服务器接口来允许组件与服务进行交互,如发送请求,获取结果,甚至通过IPC来进行跨进程通信。
混合方式启动:在一个组件中用两种不同的方式启动了多个服务。
Service生命周期:
1.通过startService():
service启动
->
onCreate(),第一次创建时执行,只执行一次就可以在以后的执行中继续使用,类似于静态创建的带启动项(初始化)
->
onStartCommand(以前是onStart),每开启一个service时执行该方法,该方法内部可以写方法运行时想要执行的业务逻辑,也可以
设置为前台服务,若使用该方法,有责任结束service: 停止本身stopSelf();stopSelf(int id);stopSelfResult(int startid);
->
onDestroy(),当服务不再有用或者被销毁时,系统调用该方法。你的服务需要实现该方法来清理任何资源,如线程,已注册的监听器,接收器等。
->
service结束
2.通过bindService():
service启动
->
onCreate(),第一次创建时执行,只执行一次就可以在以后的执行中继续使用,类似于静态创建的带启动项(初始化)
->
onBind(),绑定时,为了定义Activity(发起方)与service的信息传递返回IBinder,IBinder需要自己定义(是返回的与Activity进行数据交换的通道)
->
onUnbind(),onRebind()(可能执行)
onUnbind():当客户中断所有服务发布的特殊接口时,系统调用该方法(解除绑定)
onRebind():当新的客户端与服务连接,且此前它已经通过onUnbind(Intent)通知断开连接时,系统调用该方法。(再次绑定)
->
onDestroy(),当服务不再有用或者被销毁时,系统调用该方法。你的服务需要实现该方法来清理任何资源,如线程,已注册的监听器,接收器等。
->
service结束
IntentService:
在把耗时线程放到Service中的onStart()方法中时,很容易引起ANR异常(Application Not Responding)
原因:
1.Service不是一个单独的进程,它和它的应用程序在同一个进程中
2.Service不是一个线程,这样就意味着我们应该避免在Service中进行耗时操作
android给出解决上述问题的替代品IntentService。
IntentService 是继承与Service并处理异步请求的一个类,在IntentService中有 一个工作线程来处理耗时操作,请求的Intent记录会加入队列
工作方式:
startService(intent)来启动IntentService
执行完毕会自动停止
可以启动IntentService多次
每个耗时操作会以工作队列的方式在IntentService的 onHandleIntent回调方法中执行
并且每次只会执行一个工作线程(从一到二这样依次执行)
MediaPlayer的基本使用与Service的整合
MediaPlayer是播放多媒体文件(视频,音乐和图片),
提供了两个静态创建的方法:
static MediaPlayer create(Context context,int resid):通过给定的Id来创建一个MediaPlayer实例。
static MediaPlayer create(Context context,Uri uri):通过给定的Uri来创建一个MediaPlayer实例。
还有具体方法可以使用(前几个比较常用):
void pause () 暂停
void start () 开始
void stop () 停止
void prepare() 同步的方式装载流媒体文件。
void prepareAsync() 异步的方式装载流媒体文件。
void reset() 重置MediaPlayer至未初始化状态。
void release () 回收流媒体资源。
void setDataSource(String path) 通过一个具体的路径来设置MediaPlayer的数据源,path可以是本地的一个路径,也可以是一个网络路径
void setDataSource(Context context, Uri uri) 通过给定的Uri来设置MediaPlayer的数据源,这里的Uri可以是网络路径或是一个ContentProvider的Uri。
void setDataSource(MediaDataSource dataSource) 通过提供的MediaDataSource来设置数据源
void setDataSource(FileDescriptor fd) 通过文件描述符FileDescriptor来设置数据源
int getCurrentPosition() 获取当前播放的位置
int getAudioSessionId() 返回音频的
session ID
int getDuration() 得到文件的时间
TrackInfo[] getTrackInfo() 返回一个track信息的数组
boolean isLooping () 是否循环播放
boolean isPlaying() 是否正在播放
void seekTo(int msec) 指定播放的位置(以毫秒为单位的时间)
void setAudioStreamType(int streamtype) 指定流媒体类型
void setLooping(boolean looping) 设置是否单曲循环
void setNextMediaPlayer(MediaPlayer next) 当 当前这个MediaPlayer播放完毕后,MediaPlayer next开始播放
void setWakeMode(Context context, int mode):设置CPU唤醒的状态。
setOnBufferingUpdateListener(MediaPlayer.OnBufferingUpdateListener listener) 网络流媒体的缓冲变化时回调
setOnCompletionListener(MediaPlayer.OnCompletionListener listener) 网络流媒体播放结束时回调
setOnErrorListener(MediaPlayer.OnErrorListener listener) 发生错误时回调
setOnPreparedListener(MediaPlayer.OnPreparedListener listener):当装载流媒体完毕的时候回调。
与service的整合:需要用到前台服务(优先级更高):
startForeground(1, notification);前面介绍过,在onStartCommand(onStart)方法中进行
在此之前(Android8.0 api26之后)需要发送通知:NotificationChannel(notificationManager.createNotificationChannel(notificationChannel1)),
notificationChanne是由系统服务NotificationService创建,创建方式Notification.Binder 内容,标题,小图标(
Notification.Builder builder = new Notification.Builder(this,”channel1”);
builder.setSmallIcon(R.drawable.ic_tubiao);//图标
builder.setContentText(“音乐播放中。。。”);//内容
builder.setContentTitle(“播放音乐”);//标题
)
前台服务可以避免MediaPlayer被系统意外终止.
前台服务:
3.如何创建一个前台服务
新建一个服务
->
构建通知消息(在Service的onStartCommand中添加如下代码构建Notification):
Notification.Builder builder = new Notification.Builder
(this.getApplicationContext()); //获取一个Notification构造器
Intent nfIntent = new Intent(this, MainActivity.class);
builder.setContentIntent(PendingIntent.
getActivity(this, 0, nfIntent, 0)) // 设置PendingIntent
.setLargeIcon(BitmapFactory.decodeResource(this.getResources(),
R.mipmap.ic_large)) // 设置下拉列表中的图标(大图标)
.setContentTitle(“下拉列表中的Title”) // 设置下拉列表里的标题
.setSmallIcon(R.mipmap.ic_launcher) // 设置状态栏内的小图标
.setContentText(“要显示的内容”) // 设置上下文内容
.setWhen(System.currentTimeMillis()); // 设置该通知发生的时间
Notification notification = builder.build(); // 获取构建好的Notification
notification.defaults = Notification.DEFAULT_SOUND; //设置为默认的声音
->
启动前台服务(在完成Notification通知消息的构建后,在Service的onStartCommand中可以使用startForeground方法来让Android服务运行在前台。):
// 参数一:唯一的通知标识;参数二:通知消息。
startForeground(110, notification);// 开始前台服务
->停止前台服务(在Service的onDestory中使用stopForeground方法来停止正在运行的前台服务。):
@Override
public void onDestroy() {
Log.d(TAG, “onDestroy()”);
stopForeground(true);// 停止前台服务–参数:表示是否移除之前的通知
super.onDestroy();
}