Android四大组件之Service
来源:互联网 发布:保柏 知乎 编辑:程序博客网 时间:2024/06/03 13:46
Service:是一个可以在后台执行长时间运行操作而不使用用户界面的Android应用组件。启动Service有两种方式:startServie和bindService。通过startService开启的服务.一旦服务开启, 这个服务和开启他的调用者之间就没有任何的关系了.
调用者不可以访问 service里面的方法. 调用者如果被系统回收了或者调用了ondestroy方法, service还会继续存在 。通过bindService开启的服务,服务开启之后,调用者和服务之间 还存在着联系 ,
一旦调用者挂掉了.service也会跟着挂掉 (若该service仅与该调用者绑定,那么该调用者被销毁,那么该service也被销毁;若该service与多个调用者绑定,那么当所有调用者与该service解除绑定,该service被销毁)。
一、startService的方式启动Service,其生命周期为:onCreate–>onStartCommand(android2.0以前,为onStart)–>onDestroy.
下面为利用Service播放音乐的demo
MainActivity的xml文件,里面有播放音乐、停止播放和停止服务三个按钮
<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" > <Button android:id="@+id/play_musi" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:text="开始播放" /> <Button android:id="@+id/stop_music" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:text="停止播放播放" /> <Button android:id="@+id/stop_service" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:text="停止服务" /></LinearLayout>
MainActivity Java文件,当多次调用startService,Service的onCreate方法只会被调用一次,onStartCommand方法被多次调用,所以在onStartCommand实现播发和停止播放音乐的逻辑
package com.example.servicetest;import android.R.integer;import android.net.Uri;import android.os.Bundle;import android.app.Activity;import android.content.Intent;import android.view.Menu;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;public class MainActivity extends Activity implements OnClickListener { private Intent intent; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button play_music = (Button) findViewById(R.id.play_musi); Button stop_music = (Button) findViewById(R.id.stop_music); Button stop_service = (Button) findViewById(R.id.stop_service); intent = new Intent(); intent.setClass(this, MusicService.class); play_music.setOnClickListener(this); stop_music.setOnClickListener(this); stop_service.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.play_musi: LogUtil.d("播放音乐"); intent.putExtra("msg", 0); intent.putExtra("musicName", "music.mp3"); startService(intent); break; case R.id.stop_music: LogUtil.d("停止播放音乐"); intent.putExtra("msg", 1); startService(intent); break; case R.id.stop_service: LogUtil.d("停止服务"); stopService(intent); break; default: break; } }}
用于播放音乐的Service
package com.example.servicetest;import java.io.File;import java.io.FileDescriptor;import java.io.FileInputStream;import android.app.Service;import android.content.Intent;import android.content.res.AssetFileDescriptor;import android.media.AudioManager;import android.media.MediaPlayer;import android.os.IBinder;public class MusicService extends Service { private MediaPlayer mediaPlayer; // 媒体播放器对象 @Override public IBinder onBind(Intent arg0) { return null; } @Override public void onCreate() { super.onCreate(); mediaPlayer = new MediaPlayer(); LogUtil.d("onCreate"); } @Override public int onStartCommand(Intent intent, int flags, int startId) { int msg = intent.getIntExtra("msg", -1); String musicName = intent.getStringExtra("musicName"); LogUtil.d("onStartCommand" + "msg: " + msg + " musicName: " + musicName); if (msg == 0) { play(musicName); } if (msg == 1) { stop(); } return super.onStartCommand(intent, flags, startId); } private void play(String musicName) { try { LogUtil.d("play"); mediaPlayer.reset();// 把各项参数恢复到初始状态 AssetFileDescriptor fileDescriptor = getAssets() .openFd(musicName); mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); mediaPlayer.setDataSource(fileDescriptor.getFileDescriptor(), fileDescriptor.getStartOffset(), fileDescriptor.getLength()); mediaPlayer.prepare(); mediaPlayer.start(); } catch (Exception e) { LogUtil.d("播放失败:" + e.getMessage()); e.printStackTrace(); } } private void stop() { if (mediaPlayer != null && mediaPlayer.isPlaying()) { mediaPlayer.pause(); LogUtil.d("stop"); } } @Override public void onDestroy() { LogUtil.d("onDestroy"); stop(); mediaPlayer = null; super.onDestroy(); }}
二、bindService的方式启动Service,其生命周期为:onCreate–>onBind–>Service运行–>调用者unbindService或调用者被销毁–>–>onUnbind–>onDestroy.Service中还有一个onRebind方法,那么它何时被调用呢?如果调用者同时startService和bindService,当调用者和service解除绑定后,并且onUnbind返回为true(默认情况下,onUnbind方法返回return super.onUnbind(intent);而super.onUnbind(intent)为false,所以要手动返回为true),当调用者再次绑定Service时,onRebind会被调用。
以下bindService的demo中,MyService继承于Service,有个继承于Binder的内部类,并定义了MyServiBce方法,目的是通过MyBinder返回MyService的实例。
package com.example.bindservice;import android.app.Service;import android.content.Intent;import android.os.Binder;import android.os.IBinder;public class MyService extends Service{ private MyBinder mBinder = new MyBinder(); @Override public void onCreate() { super.onCreate(); LogUtil.d("onCreate"); } @Override public int onStartCommand(Intent intent, int flags, int startId) { LogUtil.d("onStartCommand"); return super.onStartCommand(intent, flags, startId); } @Override public boolean onUnbind(Intent intent) { LogUtil.d("onUnbind"); boolean re = super.onUnbind(intent); LogUtil.d("onUnbind默认返回: " + re); //return super.onUnbind(intent); return true; } @Override public void onRebind(Intent intent) { LogUtil.d("onRebind"); super.onRebind(intent); } @Override public IBinder onBind(Intent arg0) { LogUtil.d("onBind"); return mBinder; } public class MyBinder extends Binder{ public MyService getService(){ //返回serive实例 return MyService.this; } } public int sum(int a,int b){ return a + b; } @Override public void onDestroy() { LogUtil.d("onDestroy"); super.onDestroy(); }}
MainActivity的java文件,其通过ServiceConnection和Service通信,如调用Service中的sum方法
package com.example.bindservice;import android.os.Bundle;import android.os.IBinder;import android.app.Activity;import android.content.ComponentName;import android.content.Context;import android.content.Intent;import android.content.ServiceConnection;import android.util.Log;import android.view.Menu;import android.view.View;public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } public void bindMyService(View v) { LogUtil.d("绑定服务"); Intent intent = new Intent(); intent.setClass(this, MyService.class); //startService(intent); bindService(intent, conn, Context.BIND_AUTO_CREATE); } public void unbindMyService(View v) { LogUtil.d("解除绑定服务"); unbindService(conn); } private ServiceConnection conn = new ServiceConnection() { @Override public void onServiceConnected(ComponentName arg0, IBinder binder) { MyService myService = ((MyService.MyBinder) binder).getService(); int sum = myService.sum(1, 2); LogUtil.d("和: " + sum); } @Override public void onServiceDisconnected(ComponentName arg0) { } };}
startService完整demo
bindService的完整demo
- Android四大组件之 Service
- Android四大组件之 Service
- Android四大组件之 Service
- android四大组件之Service
- android四大组件之Service
- android四大组件之Service
- Android四大组件之Service
- Android四大组件之service
- Android四大组件之Service
- Android四大组件之 Service
- Android四大组件之Service
- Android四大组件之Service
- Android四大组件之service
- Android四大组件之Service
- Android四大组件之Service
- android四大组件之Service
- android四大组件之Service
- Android 四大组件之 Service
- android日历例子
- android ScrollView和ListView固定底部
- BillBoard 广告牌的两种实现方式
- MT6575驱动调试笔记
- android 下拉刷新案例
- Android四大组件之Service
- android MotionEvent中getY和getRawY的区别
- missing artifact com.oracle:ojdbc14:jar:10.2.0.4.0
- TeamTalk源码分析之http_msg_server对外提供API
- android 旋转向上向下图标(RotateAnimation)
- android 图片浏览案例
- Elasticsearch基础教程
- android OkHttp学习以及使用例子
- 水波按钮效果