Android四大组件:Service

时间:2023-04-15 20:33 作者:乐鱼app
本文摘要:第二组件 Service(一)基础知识1.界说服务,是Android四大组件之一, 属于 盘算型组件2.作用提供 需在后台恒久运行的服务,如:庞大盘算、音乐播放、下载等3.特点无用户界面、在后台运行、生命周期长一个运行在后台执行长时间运行的操作组件,它不提供任何用户界面,作为与Activity同级的组件,它依旧是运行在主线程中(由于是在主线程,所以需开一个线程来执行耗时操作)。

乐鱼app

第二组件 Service(一)基础知识1.界说服务,是Android四大组件之一, 属于 盘算型组件2.作用提供 需在后台恒久运行的服务,如:庞大盘算、音乐播放、下载等3.特点无用户界面、在后台运行、生命周期长一个运行在后台执行长时间运行的操作组件,它不提供任何用户界面,作为与Activity同级的组件,它依旧是运行在主线程中(由于是在主线程,所以需开一个线程来执行耗时操作)。一个组件还可以与一个Service举行绑定来实现组件之间的交互,甚至可以执行IPC(Inter-Process Communication)历程间通信。Service可以在后台执行许多任务,好比处置惩罚网络事务,播放音乐,文件读写或者与一个内容提供者交互,等等。

(二)生命周期1.生命周期常用方法1、4个手动挪用方法startService() 启动服务stopService() 关闭服务bindService() 绑定服务unbindService() 解绑服务2、5个内部自动挪用方法onCreat() 建立服务onStartCommand() 开始服务onDestroy() 销毁服务onBind() 绑定服务onUnbind() 解绑服务2.生命周期方法详细先容1、startService()(1)作用:启动Service服务(2)自动挪用方法:onCreate()、onStartCommand()a)一个Service被sartService多次启用,onCreate()只会挪用一次,onStartCommand()可以多次挪用(=startService()挪用次数)b)onStartCommand()必须返回一个整数=形貌系统因异常(1.内存不足2.历程关闭等)在杀死onStartCommand()后的服务后应该如何继续运行Service中onStartCommand回调四种返回值的区别START_NOT_STICKY:系统在onStartCommand()返回后终止服务,不会重新启动服务。除非有挂起 Intent 要通报,否则系统不会重建服务。这是最宁静的选项,可以制止在不须要时服务自动重启以及应用能够轻松重启所有未完成的作业时运行服务。START_STICKY:系统在onStartCommand()返回后终止服务,会重新启动服务&挪用onStartCommand(),但不保留已传入的intent。

用null intent挪用onStartCommand()。除非有挂起的未发送完的启动服务的intent,会依此继续传入intent。适用于媒体播放器类似服务,不执行下令,但要一直执行并随时待命。

START_REDELIVER_INTENT:系统在onStartCommand()返回后终止服务,会重新启动service&通过通报给服务最后一个intent挪用onstartCommand()。任何挂起的未发送完的intent,会依此传入。

适用于主动执行应该立刻恢复事情的活跃服务,好比下载文件。实例:服务public class MyService extends Service { private static final String TAG = MyService.class.getSimpleName(); @Override public void onCreate() { super.onCreate(); Log.e(TAG, "onCreate"); new Handler().postDelayed(new Runnable() { @Override public void run() { Log.e(TAG, "postDelayed"); // 制造异常,kill 掉该 Service int a = 1 / 0; } }, 3000L); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.e(TAG, "onStartCommand, intent: " + intent + ", startId: " + startId); return Service.START_STICKY_COMPATIBILITY; } @Nullable @Override public IBinder onBind(Intent intent) { return null; } @Override public void onDestroy() { Log.e(TAG, "onDestroy"); super.onDestroy(); }}123456789101112131415161718192021222324252627282930313233343536测试public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); startService(new Intent(MainActivity.this, MyService.class)); }}12345678910测试效果:1、使用 START_STICKY 作为返回值// 服务重新建立并重启,可是 intent 工具被置空了03-22 20:43:42.199 11233-11233/com.example.test E/MyService: onCreate03-22 20:43:42.209 11233-11233/com.example.test E/MyService: onStartCommand, intent: null, startId: 203-22 20:43:45.209 11233-11233/com.example.test E/MyService: postDelayed12342、使用 START_NOT_STICKY 作为返回值// 服务没有重新建立13、使用 START_REDELIVER_INTENT 作为返回值// 服务重新建立并启动,intent 工具没有被置空03-22 20:46:00.879 14792-14792/com.example.test E/MyService: onCreate03-22 20:46:00.879 14792-14792/com.example.test E/MyService: onStartCommand, intent: Intent { cmp=com.example.test/.MyService }, startId: 103-22 20:46:03.889 14792-14792/com.example.test E/MyService: postDelayed1234(3)示意图:2、stopService()(1)作用:关闭Service服务(a)未启动的服务(自己关闭)(b)启动&绑定&未解绑的服务无法挪用onDestroy()——>无法关闭服务(2)自动挪用的方法:onDestroy()(3)示意图:3、bindService()(1)作用:绑定Service服务(2)自动挪用的方法:onCreate()、onBind()(3)示意图:4、unbindService()(1)作用:解绑Service服务(2)自动挪用的方法:onUnbind()、onDestroy()(3)示意图:3.应用场景1、启动服务——只使用startService(1)流程图:(2)备注:1、一个Service的onCreate()只挪用一次(只有一个Service实例),onStartCommand()挪用次数=startService挪用次数2、startService与stopService配对(必须通过stopService关闭Service)3、只使用startService(),无法与Activity交互,绑定者无法操作Service2、绑定服务——只使用BindService(1)流程图:(2)备注:1、一个Service的onCreate()只挪用一次(只有一个Service实例),onBind()挪用次数=BindService挪用次数,多个绑定者可以绑定到同一个服务上2、bindService与unbindService配对,当该Service所有绑定者解绑后,系统会自动销毁服务(不需手动stop)3、bindService能让Activity与Service交互,绑定者通过一个iBinder接口与服务通信3、启动服务后绑定——startService()+bindService(1)流程图: (2)备注:1、关于操作Service:(1)startService()、stopService()只能开启&关闭Service,但无法操作Service(2)bindService()、unbindService()除了绑定Service还能操作Service2、关于Service销毁:(1)startService()开启的Service,绑定者退出后Service仍存在(2)bindService()开启的Service,绑定者退出后,Service随着挪用者退出销毁(三)Service分类1.类型1、按运行所在分(1)当地服务(2)远程服务2、按运行类型分(1)前台服务(2)后台服务3、按功效分(1)可通信服务(2)不行通信服务2.详细先容1、按运行所在分(1)当地服务1、特点:(1)运行在主线程(2)主线程被终止后,服务也会终止(3)节约资源,且不需要AIDL/IPC,轻便2、场景:(最常用)需要依附某个历程,不需要常驻的服务,如音乐播放3、使用:步骤1:新建子类继续Service类——需重写父类的onCreate()、onStartCommand()、onDestroy()和onBind()方法public class MyService extends Service { @Override public void onCreate() { super.onCreate(); System.out.println("执行了onCreat()"); } @Override public int onStartCommand(Intent intent, int flags, int startId) { System.out.println("执行了onStartCommand()"); return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy() { super.onDestroy(); System.out.println("执行了onDestory()"); } @Nullable @Override public IBinder onBind(Intent intent) { return null; }}123456789101112131415161718192021222324步骤2:构建用于启动Service的Intent工具步骤3:挪用startService()启动Service、挪用stopService()停止服务//构建启动服务的Intent工具Intent startIntent = new Intent(this, MyService.class);//挪用startService()方法-传入Intent工具,以此启动服务startService(startIntent);//构建停止服务的Intent工具Intent stopIntent = new Intent(this, MyService.class);//挪用stopService()方法-传入Intent工具,以此停止服务stopService(stopIntent);123456789步骤4:在AndroidManifest.xml里注册Service<application //注册Service服务 <service android:name=".MyService"> </service></application>12345(2)远程服务2.1)特点:运行在独立历程(占用一定资源)服务常驻后台,不受其他Activity影响(Activity所在历程被kill时,服务仍在举行)使用AIDL举行IPC2.2)应用场景:系统级别服务(常驻),多个应用法式共享同一个后台服务(跨历程通信)2.3)远程服务Service(含AIDL&IPC解说)2.4)IntentService用法&源码(客户端远程挪用服务器端的远程Service)1.AIDL与IPC(使用AIDL举行IPC)IPC:Inter-Process Communication,即跨历程通信AIDL:Android Interface Definition Language,即Android接口界说语言;用于让某个Service与多个应用法式组件之间举行跨历程通信,从而可以实现多个应用法式共享同一个Service的功效。

2.多历程通信中2个角色:服务端:步骤1:新建界说AIDL文件,并声明该服务需要向客户端提供的接口// 在新建的AIDL_Service1.aidl里声明需要与Activity举行通信的方法package scut.carson_ho.demo_service;interface AIDL_Service1 { void AIDL_Service();}12345步骤2:在Service子类中实现AIDL中界说的接口方法,并界说生命周期的方法(onCreat、onBind()、blabla)public class MyService extends Service { // 实例化AIDL的Stub类(Binder的子类) AIDL_Service1.Stub mBinder = new AIDL_Service1.Stub() { //重写接口里界说的方法,用于客户端挪用 @Override public void AIDL_Service() throws RemoteException { System.out.println("客户端通过AIDL与远程后台乐成通信"); } }; //重写与Service生命周期的相关方法 @Override public void onCreate() { super.onCreate(); System.out.println("执行了onCreat()"); } @Override public int onStartCommand(Intent intent, int flags, int startId) { System.out.println("执行了onStartCommand()"); return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy() { super.onDestroy(); System.out.println("执行了onDestory()"); } @Nullable @Override public IBinder onBind(Intent intent) { System.out.println("执行了onBind()"); //在onBind()返回继续自Binder的Stub类型的Binder,很是重要 return mBinder; } @Override public boolean onUnbind(Intent intent) { System.out.println("执行了onUnbind()"); return super.onUnbind(intent); }}1234567891011121314151617181920212223242526272829303132333435363738步骤3:在AndroidMainfest.xml中注册服务 & 声明为远程服务 <service android:name=".MyService" android:process=":remote" //将当地服务设置成远程服务 android:exported="true" //设置可被其他历程挪用 > //该Service可以响应带有scut.carson_ho.service_server.AIDL_Service1这个action的Intent。//此处Intent的action必须写成“服务器端包名.aidl文件名” <intent-filter> <action android:name="scut.carson_ho.service_server.AIDL_Service1"/> </intent-filter></service>1234567891011客户端:步骤1:拷贝服务端的AIDL文件到客户端目录下,并举行编译步骤2:使用Stub.asInterface接口获取服务器的Binder,凭据需要挪用服务提供的接口方法//界说aidl接口变量private AIDL_Service1 mAIDL_Service;//建立ServiceConnection的匿名类private ServiceConnection connection = new ServiceConnection() { //重写onServiceConnected()方法和onServiceDisconnected()方法 //在Activity与Service建设关联息争除关联的时候挪用 @Override public void onServiceDisconnected(ComponentName name) { } @Override public void onServiceConnected(ComponentName name, IBinder service) { //使用AIDLService1.Stub.asInterface()方法获取服务器端返回的IBinder工具 //将IBinder工具传换成了mAIDL_Service接口工具 mAIDL_Service = AIDL_Service1.Stub.asInterface(service); try { //通过该工具挪用在MyAIDLService.aidl文件中界说的接口方法,从而实现跨历程通信(客户端挪用服务端方法) mAIDL_Service.AIDL_Service(); } catch (RemoteException e) { e.printStackTrace(); } }};12345678910111213141516171819202122步骤3:通过Intent指定服务端的服务名称和所在包,绑定远程Service//通过Intent指定服务端的服务名称和所在包,与远程Service举行绑定//参数与服务器端的action要一致,即"服务器包名.aidl接口文件名"Intent intent = new Intent("scut.carson_ho.service_server.AIDL_Service1");//Android5.0后无法只通过隐式Intent绑定远程Service//需要通过setPackage()方法指定包名intent.setPackage("scut.carson_ho.service_server");//绑定服务,传入intent和ServiceConnection工具bindService(intent, connection, Context.BIND_AUTO_CREATE);123456782、按运行类型分(1)前台服务1.1)特点:在通知栏显示通知(用户可以看到)1.2)应用场景:服务使用时需要让用户知道并举行相关操作,如音乐播放服务(服务被终止时,通知栏的通知也会消失)1.3)使用方法:Service类onCreate()增加通知栏显示功效//添加下列代码将后台Service酿成前台Service//构建"点击通知后打开MainActivity"的Intent工具Intent notificationIntent = new Intent(this,MainActivity.class);PendingIntent pendingIntent = PendingIntent.getActivity(this,0,notificationIntent,0);//新建Builer工具Notification.Builder builer = new Notification.Builder(this);builer.setContentTitle("前台服务通知的标题");//设置通知的标题builer.setContentText("前台服务通知的内容");//设置通知的内容builer.setSmallIcon(R.mipmap.ic_launcher);//设置通知的图标builer.setContentIntent(pendingIntent);//设置点击通知后的操作Notification notification = builer.getNotification();//将Builder工具转酿成普通的notificationstartForeground(1, notification);//让Service酿成前台Service,并在系统的状态栏显示出来1234567891011121314(2)后台服务后台:后台任务运行完全不依赖UI,即时Activity被销毁/法式被关闭,只要历程还在,后台任务就可继续运行2.1)特点:处于后台的服务(用户无法看到)2.2)应用场景:服务使用时不需要让用户知道并举行相关操作,如天气更新,日期同步(服务被终止时,用户是无法知道的)3、按功效分(1)可通信服务1.1)特点:a)用bindServiceb)挪用者退出后,随挪用者销毁c)只有绑定Service服务(Binder类、bindService()、onBind()、unbindService()、onUnbind())才气与Activity通信1.2)应用场景:后台服务需要与Activity举行通信1.3)使用方法:步骤1:在新建子类继续Service类,并新建一个子类继续自Binder类、写入与Activity关联需要的方法、建立实例public class MyService extends Service { private MyBinder mBinder = new MyBinder(); @Override public void onCreate() { super.onCreate(); System.out.println("执行了onCreat()"); } @Override public int onStartCommand(Intent intent, int flags, int startId) { System.out.println("执行了onStartCommand()"); return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy() { super.onDestroy(); System.out.println("执行了onDestory()"); } @Nullable @Override public IBinder onBind(Intent intent) { System.out.println("执行了onBind()"); //返回实例 return mBinder; } @Override public boolean onUnbind(Intent intent) { System.out.println("执行了onUnbind()"); return super.onUnbind(intent); } //新建一个子类继续自Binder类 class MyBinder extends Binder { public void service_connect_Activity() { System.out.println("Service关联了Activity,并在Activity执行了Service的方法"); } }}12345678910111213141516171819202122232425262728293031323334353637步骤2:在Activity通过挪用MyBinder类中的public方法来实现Activity与Service的联系(Activity指挥Service执行的功效)1、构建绑定服务的Intent工具//构建绑定服务的Intent工具Intent bindIntent = new Intent(this, MyService.class);//挪用bindService()方法,以此停止服务bindService(bindIntent,connection,BIND_AUTO_CREATE);//参数说明//第一个参数:Intent工具//第二个参数:上面建立的Serviceconnection实例//第三个参数:标志位//这里传入BIND_AUTO_CREATE表现在Activity和Service建设关联后自动建立Service//这会使得MyService中的onCreate()方法获得执行,但onStartCommand()方法不会执行//挪用unbindService()解绑服务//参数是上面建立的Serviceconnection实例unbindService(connection);123456789101112132、建立ServiceConnection匿名类,,在Activity和Service建设息争除关联时挪用//建立ServiceConnection的匿名类private ServiceConnection connection = new ServiceConnection() { //重写onServiceConnected()方法和onServiceDisconnected()方法 //在Activity与Service建设关联息争除关联的时候挪用 @Override public void onServiceDisconnected(ComponentName name) { } //在Activity与Service排除关联的时候挪用 @Override public void onServiceConnected(ComponentName name, IBinder service) { //实例化Service的内部类myBinder //通过向下转型获得了MyBinder的实例 myBinder = (MyService.MyBinder) service; //在Activity挪用Service类的方法 myBinder.service_connect_Activity(); }};1234567891011121314151617(2)不行通信服务2.1)特点:a)用startService启动b)挪用者退出后,随挪用者销毁2.2)应用场景:该后台服务不举行任何通信(四)Service使用剖析【见Service分类】1.当地服务(普通服务、不行通信服务)2.可通信服务3.前台服务4.远程服务(五)AndroidManifest.xml中Service元素常见属性1、android:name: 服务类名。可以是完整的包名+类名。也可使用. 取代包名。

2、android:exported: 其他应用能否会见该服务,如果不能,则只有本应用或有相同用户ID的应用能会见。默认为false。3、android:process: 服务所运行的历程名。

默认是在当前历程下运行,与包名一致。4、android:permission: 申请使用该服务的权限,如果没有设置下相关权限,服务将不执行(六)对比1.Service和Thread区别(1)运行线程Service运行在主线程(不能处置惩罚耗时操作,否则会泛起ANR),Thread运行在事情线程(2)运行规模Service在历程运行完全不依赖UI/Activity,只要历程还在,Service就可继续运行所有的Activity都可与Service关联,获得Service实例&操作其中方法若要处置惩罚耗时操作,则在Service里建立Thread子线程执行Thread在Activity运行依赖于某个Activity在一个Activity中建立子线程,另一个Activity无法对其操作Activity很难控制Thread,且Activity被销毁后,无法再获取之前建立的子线程实例2.Service和IntentService区别(1)什么是IntentService?为什么要使用IntentService?Service是用于后台服务的,保证法式挂到后台时某些组件仍能正常事情。然而Service不是独立的历程,是默认运行在主线程中的。

所以如果直接在服务里去处置惩罚一些耗时的逻辑,就很容易泛起ANR(Application Not Responding)的情况。所以这个时候就需要用到Android多线程编程的技术了,我们可以在服务内开启线程,接纳thread+handler方式处置惩罚耗时操作。

但服务一旦启动,就会一直处于运行状态,必须挪用stopSelf()/stopService()才气让服务停止。编写逻辑较庞大。我们可以引用IntentService。IntentService是继续Service的,那么它包罗了Service的全部特性,固然也包罗service的生命周期,那么与service差别的是,IntentService在执行onCreate操作的时候,内部开了一个线程,去执行耗时操作。

IntentService是一个通过Context.startService(Intent)启动可以处置惩罚异步请求的Service,使用时你只需要继续IntentService和重写其中的onHandleIntent(Intent)方法吸收一个Intent工具,事情完成后会自动停止服务。所有的请求的处置惩罚都在一个事情线程中完成,它们会交替执行(但不会阻塞主线程的执行),一次只能执行一个请求。这是一个基于消息的服务,每次启动该服务并不是马上处置惩罚你的事情,而是首先会建立对应的Looper,Handler而且在MessageQueue中添加的附带客户Intent的Message工具,当Looper发现有Message的时候接着获得Intent工具通过在onHandleIntent((Intent)msg.obj)中挪用你的处置惩罚法式,处置惩罚完后即会停止自己的服务,意思是Intent的生命周期跟你的处置惩罚的任务是一致的,所以这个类用下载任务中很是好,下载任务竣事后服务自身就会竣事退出。

(2)特点会建立独立的worker线程来处置惩罚所有的Intent请求;会建立独立的worker线程来处置惩罚onHandleIntent()方法实现的代码,无需处置惩罚多线程问题;所有请求处置惩罚完成后,IntentService会自动停止,无需挪用stopSelf()方法停止Service;(3)实例(3.1)新建一个MyIntentService类继续自IntentService1、提供一个无参的结构函数,而且必须在其内部挪用父类的有参结构函数。2、在其子类中去实现onHandlerIntent()这个抽象方法,在这个方法中可以去处置惩罚一些详细的逻辑。(用于处置惩罚耗时操作,该方法在子线程中执行)public class MyIntentService extends IntentService{ public MyIntentService(){ super("MyIntentService"); //挪用父类的有参结构函数 } @Override protected void onHandlerIntent(Intent intent){ //打印当前线程的id Log.d("MyIntentService","Thread id is"+ Thread.currentThread().getId()); } @Override public void onDestroy() { super.onDestroy(); Log.d("MyIntentService","onDestroy executed");//运行竣事后服务自动停止 } } 123456789101112131415(3.2)在Activity启动服务public class MainActivity extends AppCompatActivity implements View.OnClickListener{@Overrideprotected void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.id.activity_main); Button startIntentService=(Button)findViewById(R.id.start_intent_service); startIntentService.setOnClickListener(this); } @Override public void onClick(View v){ switch(v.getId()) { ... case R.id.start_intent_service: //打印主线程的id Log.d("MainActivity","Thread id is"+Thread.currentThread().getId());Intent intentService=new Intent(this,MyIntentService.class);startService(intentService);//启动服务 break; default: break;}}} 1234567891011121314151617181920212223(3.3)在AndroidManifest注册服务<application<service android:name=".MyIntentService" /></application>123(4)IntentService与service的区别IntentService是继续并处置惩罚异步请求的一个类,在IntentService内有一个事情线程来处置惩罚耗时操作,启动IntentService的方式和启动传统的Service一样,同时,当任务执行完后,IntentService会自动停止,而不需要我们手动去控制或stopSelf()。

另外,可以启动IntentService多次,而每一个耗时操作会以事情行列的方式在IntentService的onHandleIntent回调方法中执行,而且,每次只会执行一个事情线程,执行完第一个再执行第二个,以此类推。它本质上就是一个封装了HandlerThread+Handler的异步框架(七)Activity与Service通信方式总结*方法1:binder+回调(listener)当Activity通过挪用bindService(Intent service, ServiceConnection conn,int flags),我们可以获得一个Service的一个工具实例,然后我们就可以会见Service中的方法,同时使用回调接口实现Service中进度变化主动通知Activity更新UI(1)新建一个回调接口,通过回调接口实现当Service中进度发生变化主动通知Activity更新UI(回调接口的明白见:一个经典例子让你彻彻底底明白java回调机制)public interface OnProgressListener { void onProgress(int progress);}123(2)新建一个Service类public class MsgService extends Service { public static final int MAX_PROGRESS = 100;//进度条最大值 private int progress = 0;//进度条进度值 private OnProgressListener onProgressListener;//更新进度的回调接口 public void setOnProgressListener(OnProgressListener onProgressListener) { //注册回调接口的方法,供外部挪用 this.onProgressListener = onProgressListener; } public int getProgress() { //增加get()方法,供Activity挪用,返回progress return progress; } /** * 模拟下载任务,每秒钟更新一次 */ public void startDownLoad(){ new Thread(new Runnable() { @Override public void run() { while(progress < MAX_PROGRESS){ progress += 5; //进度发生变化通知挪用方 if(onProgressListener != null){ onProgressListener.onProgress(progress); } try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); } @Override public IBinder onBind(Intent intent) { return new MsgBinder();//返回Binder工具 } public class MsgBinder extends Binder{ public MsgService getService(){ return MsgService.this;//返回当前service工具 } }}1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556(3)新建一个ServiceConnection工具,它是一个接口,Activity与Service绑定后,在onServiceConnected回调方法中返回服务工具。

onServiceConnected用于执行Activity与Service绑定后执行相关操作。ServiceConnection conn = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { } @Override public void onServiceConnected(ComponentName name, IBinder service) { //返回一个MsgService工具 msgService = ((MsgService.MsgBinder)service).getService(); } };12345678910(4)Activity代码public class MainActivity extends Activity { private MsgService msgService; private ProgressBar mProgressBar; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //绑定Service Intent intent = new Intent("com.example.communication.MSG_ACTION"); bindService(intent, conn, Context.BIND_AUTO_CREATE); mProgressBar = (ProgressBar) findViewById(R.id.progressBar1); Button mButton = (Button) findViewById(R.id.button1); mButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { //开始下载 msgService.startDownLoad(); } }); } ServiceConnection conn = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { } @Override public void onServiceConnected(ComponentName name, IBinder service) { //返回一个MsgService工具 msgService = ((MsgService.MsgBinder)service).getService(); //注册回调接口来吸收下载进度的变化 msgService.setOnProgressListener(new OnProgressListener() { @Override public void onProgress(int progress) { mProgressBar.setProgress(progress); } }); } }; @Override protected void onDestroy() { unbindService(conn); super.onDestroy(); }}1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253*方法2:广播(推荐LocalBroadcaseManager)使用系统的LocalBroadcastManager,Service send message, Activity receive message;Service向Activity发送消息,可以使用广播,固然Activity要注册相应的吸收器。适用于Service要向多个Activity发送同样的消息。当进度变化时发送一条广播,然后在Activity的注册广播吸收器,接受广播后更新progressbarpublic class MainActivity extends Activity { private ProgressBar mProgressBar; private Intent mIntent; private MsgReceiver msgReceiver; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //动态注册广播吸收器 msgReceiver = new MsgReceiver(); IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction("com.example.communication.RECEIVER"); registerReceiver(msgReceiver, intentFilter); mProgressBar = (ProgressBar) findViewById(R.id.progressBar1); Button mButton = (Button) findViewById(R.id.button1); mButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { //启动服务 mIntent = new Intent("com.example.communication.MSG_ACTION"); startService(mIntent); } }); } @Override protected void onDestroy() { //停止服务 stopService(mIntent); //注销广播 unregisterReceiver(msgReceiver); super.onDestroy(); } /** * 广播吸收器 * @author len * */ public class MsgReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { //拿到进度,更新UI int progress = intent.getIntExtra("progress", 0); mProgressBar.setProgress(progress); } }}123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354public class MsgService extends Service { /** * 进度条的最大值 */ public static final int MAX_PROGRESS = 100; /** * 进度条的进度值 */ private int progress = 0; private Intent intent = new Intent("com.example.communication.RECEIVER"); /** * 模拟下载任务,每秒钟更新一次 */ public void startDownLoad(){ new Thread(new Runnable() { @Override public void run() { while(progress < MAX_PROGRESS){ progress += 5; //发送Action为com.example.communication.RECEIVER的广播 intent.putExtra("progress", progress); sendBroadcast(intent); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { startDownLoad(); return super.onStartCommand(intent, flags, startId); } @Override public IBinder onBind(Intent intent) { return null; }}12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849方法3:binder+HandlerService 持有 Activity的Handler 工具,Service 通过往该Handler send message 的方式,到达通信的目的。

方法4:开源组件(EventBus,otto)使用反射或者注释的方式实现对注册类的注册,然后遍历当前的注册表,通过key举行查询,然后dispatch,挪用相应的事件处置惩罚方法。(差别的开源框架实现有所区别)方法5:AIDL。


本文关键词:Android,四大,组件,Service,第二,组件,Service,一,乐鱼app

本文来源:乐鱼app-www.dgtn1718.com