Android五大组件-Service
2017-06-19 15:38
197 查看
Service本质
Service在是后台服务(即它的运行不依赖于UI,即Acitivy死掉了甚至程序关掉了Service仍然可以活着只要进程没死就可以),适合。。。。但它并不是异步也还是在主线程,故而不可做耗时操作生命周期
Service和线程:
Service仍然运行在主线程需要注意不可做耗时操作,但Service不依赖UI,只要进程活着就行。所以其生命周期可以很长
Thread是异步的,适合做耗时操作。但Activity很难把控Thread,Thread生命周期可以比Acitivity长。
Activity创建一个子线程,Activity死掉后其他的Activity无法获得该线程;而Service只要注册下就可以拿到。(这也就有了再Service中创建子线程去完成耗时任务的做法,IntentService)
Service的启动方式
第一种:无法通信,启动后就是失联了。//启动Service!第一次启动会调用onCreate,后面多次触发也只调用onStartCommand startService(new Intent(this,MyService.class)); //销毁Service stopService(new Intent(this,MyService.class));
第二种:通过Binder关联
@Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); //启动Service!bindService只调用一次,onCreate->onBinder->onUnbinder->onDestroy this.bindService(new Intent(this,MyService.class),conn, Context.BIND_AUTO_CREATE); //销毁Service this.unbindService(conn); } private MyService.MyBinder mBinder; private ServiceConnection conn = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { mBinder = (MyService.MyBinder) service; mBinder.getSome();//通信,获取数据 } @Override public void onServiceDisconnected(ComponentName name) { } }; class MyService extends Service{ @Nullable @Override public IBinder onBind(Intent intent) { return null; } public class MyBinder extends Binder { public String getSome(){ return "返回数据给Activity"; } } }
Service的几个方法
onCreate:第一次创建的时候调用,只调用一次onStartCommand:每次startService都会调用
onDestroy:销毁时调用
AIDL的使用
这个例子是两个app之间的交互应用A提供Service服务,应用B请求服务并获得回调的一个完整的交互(代码摘自公司项目,有些地方就打×××了)首先两个应用都需要有的两个adil文件(注意两个应用的包名需一致,直接复制完整路径即可)
package com.×××.aidl; import com.×××.aidl.IApkScanCallback; /** * IApkScanInterface.aidl * */ interface IApkScanInterface { /** * 扫描已安装apk * @param packageName 包名 * @param callback 扫描结果回调 */ oneway void scanInstall(String packageName,IApkScanCallback callback); }
package com.×××.aidl; /** * IApkScanCallback.aidl * */ interface IApkScanCallback { /** * 扫描垃圾结果 * * @param type 类型 * @param packageName 包名,没有则为null * @param appName 应用名,没有则为null * @param virusName 名称,没有则为null * @param virusDescription 描述,没有则为null */ oneway void onScanResult(int type, String packageName ,String appName, String virusName, String virusDescription); }
接下来是应用A提供服务
package com.×××.aidl; import android.app.Service; import android.content.Context; import android.content.Intent; import android.os.IBinder; import android.os.RemoteException; public class ApkScanService extends Service { private static final String TAG = "ApkScanService"; private Context mContext; public ApkScanService() { mContext = this; } @Override public IBinder onBind(Intent intent) { return mBinder; } private IApkScanInterface.Stub mBinder = new IApkScanInterface.Stub() { @Override public void scanInstall(String packageName, IApkScanCallback callback) throws RemoteException { callback.onScanResult(1, "包名", "应用名", "名称", "描述"); } }; }
注册下Service,需要注意的是android:exported属性设置为true,否则外部App访问不到
<service android:name=".aidl.ApkScanService" android:enabled="true" android:exported="true"></service>
最后是请求端应用B
package com.×××; import android.app.Activity; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; import android.util.Log; import com.×××.aidl.IApkScanCallback; import com.×××.IApkScanInterface; public class MainActivity extends Activity { public static final String TAG = "MainActivity"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Intent intent = new Intent(); intent.setComponent(new ComponentName("com.×××",//填写访问Service的包名 "com.×××.aidl.ApkScanService"));//填写访问Service的路劲 bindService(intent, conn, Context.BIND_AUTO_CREATE); try { apkScan.scanInstall("包名", apkCallback); } catch (RemoteException e) { e.printStackTrace(); } } private IApkScanCallback apkCallback = new IApkScanCallback.Stub(){ @Override public void onScanResult(int type, String packageName, String appName, String virusName, String virusDescription) throws RemoteException { Log.d(TAG,"type = " + type + "appName = " + appName + "virusName = " + virusName); } }; private IApkScanInterface apkScan; private ServiceConnection conn = new ServiceConnection() { @Override public void onServiceConnected(ComponentName componentName, IBinder iBinder) { apkScan = IApkScanInterface.Stub.asInterface(iBinder); } @Override public void onServiceDisconnected(ComponentName componentName) { } }; }
ps:
in out inout:非Java基本类型必须修饰,in out inout的含义是指:它们表示数据的流向,in表示C流向S,out表示S流向C,inout则两端均可互相流通。举个粟子,C调用method(in String a,out String b),这个时候S端收到的a是C传过来的a,b则为null,因为out无法从C流向S。详情
oneway 当接口使用oneway关键字修饰时,表示接口在远程调用时是不会block的,即接口调用时发送完transaction数据后立即返回而不会等待远端的结果。注意,这只针对IPC的调用,同样的接口如果是在同一进程内部被调用的话,oneway关键字不起任何效果,方法该阻塞就阻塞。
Service源码
待续。。。Service(杂)
Service可以绑定多个组件(Activity,BroadcastReceiver等)前台Service:Service在onCreate中创建Notification显示在状态栏中
IntentService
相关文章推荐
- android 应用五大核心组件之一(service)
- Android五大基本组件之一-----Service篇
- Android 五大基本组件之 Service 篇
- Anroid 4大组件之android.app.Service
- Android重要组件之一 Service 服务讲解学习(一)
- android四大组件值Service(2)启动方式
- Android的四大组件之一——Service
- Android成长日记-Android四大组件之Service组件的学习
- android 四大组件之Service(4)IntentService
- Android笔记二十七.Service组件入门(一).什么是Service?
- android 四大组件之Service(6) 粘性与非粘性
- Android四大组件之Service
- Android 编程下的四大组件之服务(Service)
- Android应用组件之服务(Service)---创建启动服务1
- Android 四大组件·五大布局
- Android 四大组件 Service 服务
- Android-Service组件
- Android中的BatteryService及相关组件
- 深入剖析Android四大组件(六)——相对完美的后台Service实现播放音乐功能
- Android四大组件——Service后台服务、前台服务、IntentService、跨进程服务、无障碍服务、系统服务