【Android学习笔记】再探Android Service
来源:互联网 发布:淘宝店铺前期 编辑:程序博客网 时间:2024/06/05 07:20
转载请注明原文出处:http://blog.csdn.net/mxm691292118/article/details/50890320
我把Android重难点和读书笔记都整理在github上:https://github.com/miomin/AndroidDifficulty
如果你觉得对你有帮助的话,希望可以star/follow一下哟,我会持续保持更新。
引言:初学Android的时候,对Service是草草了之,现在反过来复习,才发现自己有很多知识没有掌握,在这里总结一下。Service是Android的四大组件之一,是Android中实现程序后台运行最合适的解决方案之一,非常适合被用于去执行那些不需要和用户界面交互而且要求长期运行的任务。
1、创建一个Service
- 服务中常用的几个方法分别是onCreate()、onStartCommand()、onDestroy()
public class MyService extends Service { @Override public IBinder onBind(Intent intent) { return null; } //每次服务启动时都会调用 @Override public int onStartCommand(Intent intent, int flags, int startId) { return super.onStartCommand(intent, flags, startId); } //在服务第一次创建的时候调用,放只需要执行一次的代码 @Override public void onCreate() { super.onCreate(); } //服务销毁的时候调用 @Override public void onDestroy() { super.onDestroy(); }}
- 在AndroidManifest.xml注册Service
<service android:name=".MyService" android:enabled="true" android:exported="true"></service>
2、启动和停止Service
//启动服务@Overridepublic void onClick(View v) { startService(new Intent(MainActivity.this, MyService.class));}//停止服务 @Overridepublic void onClick(View v) { stopService(new Intent(MainActivity.this,MyService.class));}
3、绑定Service
- 注意:startService()、stopService()和bindService()、unbindService()是成对出现的方法,startService()后,执行stopService()即可停止服务,bindService()后,执行unbindService()也可接除与服务的绑定;但是如果startService()后,接着调用bindService(),想要停止服务,必须先执行stopService(),再调用unbindService()。
@Overridepublic void onClick(View v) { bindService(new Intent(MainActivity.this,MyService.class), MainActivity.this, Context.BIND_AUTO_CREATE);}@Overridepublic void onClick(View v) { unbindService(MainActivity.this);}
- 还需要在启动Service的Activity里重写两个方法
@Override public void onServiceConnected(ComponentName name, IBinder service) { Log.i("miomin", "服务连接成功");}@Override public void onServiceDisconnected(ComponentName name) { Log.i("miomin", "服务连接关闭");}
4、Service的生命周期
- 下图可以看到,使用startService()启动Service和bindService()启动Service,所经历的生命周期是不同的。
想要更详细的了解Service生命周期,可以参考这篇博文,Activity和Service的生命周期(图)
5、跨应用启动和板吊顶Service
Android5.0以后,禁止使用隐式Intent启动Service,必须使用显式意图,对于跨引用启动,我们必须指明被作为启动对象的Service的完整包名。
//使用包名构造显示意图private Intent intent = new Intent();intent.setComponent(new ComponentName("scu.miomin.com.learnaidl", "scu.miomin.com.learnaidl.AppService"));switch (id) { case R.id.btnStartService: startService(intent); break; case R.id.btnStopService: stopService(intent); break; case R.id.btnBindService: bindService(intent, MainActivity.this,Context.BIND_AUTO_CREATE); break; case R.id.btnUnbindService: unbindService(MainActivity.this); break;}
6、与Service通信
(1)进程内部使用Binder通信
创建一个专门的Binder对象来构造Service与Activity的通信通道,在onServiceConnected()回调中接受由目标Service的unbind()方法返回的Binder对象,可以直接对Binder对象的方法进行操作,可以传入参数,返回数据等等;如果需要实现Service实时返回下载进度的功能,可以在Service中构建回调,具体的可以参考如下例子,相信大家都看得懂。
- MyService.java
public class MyService extends Service { // 控制任务是否执行 private boolean serviceRunning = false; private String data = "this is default message"; public void setCallback(Callback callback) { mCallback = callback; } @Override public IBinder onBind(Intent intent) { return new MyBinder(); } public class MyBinder extends Binder { public void setData(String newData) { MyService.this.data = newData; } public MyService getMyService() { return MyService.this; } } @Override public int onStartCommand(Intent intent, int flags, int startId) { return super.onStartCommand(intent, flags, startId); } @Override public void onCreate() { super.onCreate(); serviceRunning = true; new Thread() { @Override public void run() { int i = 0; while (serviceRunning) { i++; String str = i + ":" + data; if (mCallback != null) mCallback.onDataChange(str); Log.i("miomin", str); try { sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); } @Override public void onDestroy() { super.onDestroy(); serviceRunning = false; } private Callback mCallback; public interface Callback { void onDataChange(String date); }}
- MainActivity.java
public class MainActivity extends AppCompatActivity implements ServiceConnection { EditText etData; private MyService.MyBinder myBinder; private TextView tvOut; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViewById(R.id.startService).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { startService(new Intent(MainActivity.this, MyService.class)); } }); findViewById(R.id.stopService).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { stopService(new Intent(MainActivity.this, MyService.class)); } }); findViewById(R.id.bindService).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { bindService(new Intent(MainActivity.this, MyService.class), MainActivity.this, Context.BIND_AUTO_CREATE); } }); findViewById(R.id.unbindService).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { unbindService(MainActivity.this); } }); etData = (EditText) findViewById(R.id.etData); findViewById(R.id.btnSyncData).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (myBinder != null) { myBinder.setData(etData.getText().toString()); } } }); tvOut = (TextView) findViewById(R.id.tvOut); } @Override public void onServiceConnected(ComponentName name, IBinder service) { Log.i("miomin", "服务连接成功"); myBinder = (MyService.MyBinder) service; myBinder.getMyService().setCallback(new MyService.Callback() { @Override public void onDataChange(String date) { Message message = Message.obtain(); Bundle bundle = new Bundle(); bundle.putString("data", date); message.setData(bundle); handler.sendMessage(message); } }); } private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); tvOut.setText(msg.getData().getString("data")); } }; @Override public void onServiceDisconnected(ComponentName name) { Log.i("miomin", "服务连接关闭"); } @Override protected void onDestroy() { super.onDestroy(); unbindService(MainActivity.this); }}
(2)使用AIDL跨进程与Service通信
- 引言:在Android平台,一个进程通常不能访问另一个进程的内存空间,所以要想跨进行通信的话,需要将对象分解成操作系统可以理解的基本单元,并且有序的通过进程边界。而为了方便编码,Android系统提供了AIDL工具来处理这项工作。
- AIDL (Android Interface Definition Language) 是一种IDL 语言,用于生成可以在Android设备上两个进程之间进行进程间通信(interprocess communication, IPC)的代码。
AIDL接口文件,和普通的接口内容没有什么特别,只是它的扩展名为.aidl。如果想要使用AIDL进行跨进程通信,需要在两个工程的src文件夹下建立一模一样的AIDL文件,并且保证包名相同。
1、创建AIDL文件
interface IAppServiceAidlInterface { /** * Demonstrates some basic types that you can use as parameters * and return values in AIDL. */ void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString); void setData(String data); List<Car> getAllCar(); }
2、在Service中实现AIDL中定义的接口
- 注意:在实现接口前,需要先ReBuild。
@Overridepublic IBinder onBind(Intent intent) { return new IAppServiceAidlInterface.Stub() { @Override public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException { } @Override public void setData(String data) throws RemoteException { AppService.this.data = data; } @Override public List<Car> getAllCar() throws RemoteException { return null; } };}
3、在需要跨进程操作Service的Activity中接受Binder对象
@Overridepublic void onServiceConnected(ComponentName name, IBinder service) { IAppServiceAidlInterface AIDLBinder = IAppServiceAidlInterface.Stub.asInterface(service);}
- 【Android学习笔记】再探Android Service
- Android Service学习笔记
- Android Service学习笔记
- Android Service学习笔记
- android service 学习笔记
- Android学习笔记 - Service
- Android学习笔记-Service
- android Service学习笔记
- Android Service学习笔记
- [Android学习笔记] Service 学习
- Android Service学习笔记--声明Service
- Android Service学习笔记--创建Service
- Android Service学习笔记--Service生命周期
- Android Service学习笔记--Service知识概要
- android学习笔记之Service
- android学习笔记service介绍
- Android学习笔记--service部分
- android service 服务学习笔记
- CocoaPods安装和使用教程
- URI与URL那点事
- 调用成熟接口、谨慎使用未知接口------遇到问题时, 不一定要死死纠缠原因
- Android系统自带样式(@android:style/)
- Cplat项目开发记录
- 【Android学习笔记】再探Android Service
- Kafka学习(二):Kafka的基本结构和概念
- http协议详解(超经典)
- 冒号排序法
- 矩阵十大经典题目
- installshield 安装报错解决方法
- IOS超级简单上下左右滚动TableView,仿同花顺自选列表
- EmguCV第一个程序,读入图像并显示
- LinuxFileCommands