- 浏览: 609386 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
kangh:
转载的也拿出来 都不试一下 完全错误
Nginx+ffmpeg的HLS开源服务器搭建配置及开发详解 -
wangtxlz:
#cd builders/cmake#cmake .系统提示命 ...
crtmpserver流媒体服务器的介绍与搭建 -
hnraysir:
支持支持支持
手机Android音视频采集与直播推送,实现单兵、移动监控类应用 -
wuent:
把web服务器和php框架绑定到一起?真不建议这样。。。
Swoole(PHP高级Web开发框架) -
wuent:
有更详细的性能比较吗?php,python,java
PHP中的(伪)多线程与多进程
android SDK提供了Service,用于类似*nix守护进程或者windows的服务。
Service有两种类型:
本地服务(Local Service):用于应用程序内部
远程服务(Remote Sercie):用于android系统内部的应用程序之间
前者用于实现应用程序自己的一些耗时任务,比如查询升级信息,并不占用应用程序比如Activity所属线程,而是单开线程后台执行,这样用户体验比较好。
后者可被其他应用程序复用,比如天气预报服务,其他应用程序不需要再写这样的服务,调用已有的即可。
编写不需和Activity交互的本地服务示例
本地服务编写比较简单。首先,要创建一个Service类,该类继承android的Service类。这里写了一个计数服务的类,每秒钟为计数器加一。在服务类的内部,还创建了一个线程,用于实现后台执行上述业务逻辑。
需要将该服务注册到配置文件AndroidManifest.xml中,否则无法找到:
在Activity中启动和关闭本地服务。
可通过日志查看到后台线程打印的计数内容。
编写本地服务和Activity交互的示例
上面的示例是通过startService和stopService启动关闭服务的。适用于服务和activity之间没有调用交互的情况。如果之间需要传递参数或者方法调用。需要使用bind和unbind方法。
具体做法是,服务类需要增加接口,比如ICountService,另外,服务类需要有一个内部类,这样可以方便访问外部类的封装数据,这个内部类需要继承Binder类并实现ICountService接口。还有,就是要实现Service的onBind方法,不能只传回一个null了。
这是新建立的接口代码:
修改后的CountService代码:
服务的注册也要做改动,AndroidManifest.xml文件:
Acitity代码不再通过startSerivce和stopService启动关闭服务,另外,需要通过ServiceConnection的内部类实现来连接Service和Activity。
编写传递基本型数据的远程服务
上面的示例,可以扩展为,让其他应用程序复用该服务。这样的服务叫远程(remote)服务,实际上是进程间通信(RPC)。
这时需要使用android接口描述语言(AIDL)来定义远程服务的接口,而不是上述那样简单的java接口。扩展名为aidl而不是java。可用上面的ICountService改动而成ICountSerivde.aidl,eclipse会自动生成相关的java文件。
编写服务(Service)类,稍有差别,主要在binder是通过远程获得的,需要通过桩(Stub)来获取。桩对象是远程对象的本地代理。
配置文件AndroidManifest.xml和上面的类似,没有区别。
在Activity中使用服务的差别不大,只需要对ServiceConnection中的调用远程服务的方法时,要捕获异常。
这样就可以在同一个应用程序中使用远程服务的方式和自己定义的服务交互了。
如果是另外的应用程序使用远程服务,需要做的是复制上面的aidl文件和相应的包构到应用程序中,其他调用等都一样。
编写传递复杂数据类型的远程服务
远程服务往往不只是传递java基本数据类型。这时需要注意android的一些限制和规定:
android支持String和CharSequence
如果需要在aidl中使用其他aidl接口类型,需要import,即使是在相同包结构下;
android允许传递实现Parcelable接口的类,需要import;
android支持集合接口类型List和Map,但是有一些限制,元素必须是基本型或者上述三种情况,不需要import集合接口类,但是需要对元素涉及到的类型import;
非基本数据类型,也不是String和CharSequence类型的,需要有方向指示,包括in、out和inout,in表示由客户端设置,out表示由服务端设置,inout是两者均可设置。
这里将前面的例子中返回的int数据改为复杂数据类型:
然后,需要在相同包下建一个同名的aidl文件,用于android生成相应的辅助文件:
package com.easymorse;
parcelable CountBean;
这一步是android 1.5后的变化,无法通过adt生成aidl,也不能用一个比如全局的project.aidl文件,具体见:
http://www.anddev.org/viewtopic.php?p=20991
然后,需要在服务的aidl文件中修改如下:
其他的改动很小,只需将CountService和调用CountService的部分修改为使用CountBean即可
转载:http://yangguangfu.iteye.com/blog/699306
Service有两种类型:
本地服务(Local Service):用于应用程序内部
远程服务(Remote Sercie):用于android系统内部的应用程序之间
前者用于实现应用程序自己的一些耗时任务,比如查询升级信息,并不占用应用程序比如Activity所属线程,而是单开线程后台执行,这样用户体验比较好。
后者可被其他应用程序复用,比如天气预报服务,其他应用程序不需要再写这样的服务,调用已有的即可。
编写不需和Activity交互的本地服务示例
本地服务编写比较简单。首先,要创建一个Service类,该类继承android的Service类。这里写了一个计数服务的类,每秒钟为计数器加一。在服务类的内部,还创建了一个线程,用于实现后台执行上述业务逻辑。
package com.easymorse; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.util.Log; public class CountService extends Service { private boolean threadDisable; private int count; @Override public IBinder onBind(Intent intent) { return null ; } @Override public void onCreate() { super .onCreate(); new Thread( new Runnable() { @Override public void run() { while ( ! threadDisable) { try { Thread.sleep( 1000 ); } catch (InterruptedException e) { } count ++ ; Log.v( " CountService " , " Count is " + count); } } }).start(); } @Override public void onDestroy() { super .onDestroy(); this .threadDisable = true ; Log.v( " CountService " , " on destroy " ); } public int getCount() { return count; } }
需要将该服务注册到配置文件AndroidManifest.xml中,否则无法找到:
<? xml version="1.0" encoding="utf-8" ?> < manifest xmlns:android ="http://schemas.android.com/apk/res/android" package ="com.easymorse" android:versionCode ="1" android:versionName ="1.0" > < application android:icon ="@drawable/icon" android:label ="@string/app_name" > < activity android:name =".LocalServiceDemoActivity" android:label ="@string/app_name" > < intent-filter > < action android:name ="android.intent.action.MAIN" /> < category android:name ="android.intent.category.LAUNCHER" /> </ intent-filter > </ activity > < service android:name ="CountService" /> </ application > < uses-sdk android:minSdkVersion ="3" /> </ manifest/>
在Activity中启动和关闭本地服务。
package com.easymorse; import android.app.Activity; import android.content.Intent; import android.os.Bundle; public class LocalServiceDemoActivity extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.main); this .startService( new Intent( this , CountService. class )); } @Override protected void onDestroy() { super .onDestroy(); this .stopService( new Intent( this , CountService. class )); } }
可通过日志查看到后台线程打印的计数内容。
编写本地服务和Activity交互的示例
上面的示例是通过startService和stopService启动关闭服务的。适用于服务和activity之间没有调用交互的情况。如果之间需要传递参数或者方法调用。需要使用bind和unbind方法。
具体做法是,服务类需要增加接口,比如ICountService,另外,服务类需要有一个内部类,这样可以方便访问外部类的封装数据,这个内部类需要继承Binder类并实现ICountService接口。还有,就是要实现Service的onBind方法,不能只传回一个null了。
这是新建立的接口代码:
package com.easymorse; public interface ICountService { public abstract int getCount(); }
修改后的CountService代码:
package com.easymorse; import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.IBinder; import android.util.Log; public class CountService extends Service implements ICountService { private boolean threadDisable; private int count; private ServiceBinder serviceBinder = new ServiceBinder(); public class ServiceBinder extends Binder implements ICountService{ @Override public int getCount() { return count; } } @Override public IBinder onBind(Intent intent) { return serviceBinder; } @Override public void onCreate() { super .onCreate(); new Thread( new Runnable() { @Override public void run() { while ( ! threadDisable) { try { Thread.sleep( 1000 ); } catch (InterruptedException e) { } count ++ ; Log.v( " CountService " , " Count is " + count); } } }).start(); } @Override public void onDestroy() { super .onDestroy(); this .threadDisable = true ; Log.v( " CountService " , " on destroy " ); } /* (non-Javadoc) * @see com.easymorse.ICountService#getCount() */ public int getCount() { return count; } }
服务的注册也要做改动,AndroidManifest.xml文件:
<? xml version="1.0" encoding="utf-8" ?> < manifest xmlns:android ="http://schemas.android.com/apk/res/android" package ="com.easymorse" android:versionCode ="1" android:versionName ="1.0" > < application android:icon ="@drawable/icon" android:label ="@string/app_name" > < activity android:name =".LocalServiceDemoActivity" android:label ="@string/app_name" > < intent-filter > < action android:name ="android.intent.action.MAIN" /> < category android:name ="android.intent.category.LAUNCHER" /> </ intent-filter > </ activity > < service android:name ="CountService" > < intent-filter > < action android:name ="com.easymorse.CountService" /> </ intent-filter > </ service > </ application > < uses-sdk android:minSdkVersion ="3" /> </ manifest >
Acitity代码不再通过startSerivce和stopService启动关闭服务,另外,需要通过ServiceConnection的内部类实现来连接Service和Activity。
package com.easymorse; import android.app.Activity; import android.content.ComponentName; import android.content.Intent; import android.content.ServiceConnection; import android.os.Bundle; import android.os.IBinder; import android.util.Log; public class LocalServiceDemoActivity extends Activity { private ServiceConnection serviceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { countService = (ICountService) service; Log.v( " CountService " , " on serivce connected, count is " + countService.getCount()); } @Override public void onServiceDisconnected(ComponentName name) { countService = null ; } }; private ICountService countService; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.main); this .bindService( new Intent( " com.easymorse.CountService " ), this .serviceConnection, BIND_AUTO_CREATE); } @Override protected void onDestroy() { this .unbindService(serviceConnection); super .onDestroy(); //注意先后 } }
编写传递基本型数据的远程服务
上面的示例,可以扩展为,让其他应用程序复用该服务。这样的服务叫远程(remote)服务,实际上是进程间通信(RPC)。
这时需要使用android接口描述语言(AIDL)来定义远程服务的接口,而不是上述那样简单的java接口。扩展名为aidl而不是java。可用上面的ICountService改动而成ICountSerivde.aidl,eclipse会自动生成相关的java文件。
package com.easymorse; interface ICountService { int getCount(); }
编写服务(Service)类,稍有差别,主要在binder是通过远程获得的,需要通过桩(Stub)来获取。桩对象是远程对象的本地代理。
package com.easymorse; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.os.RemoteException; import android.util.Log; public class CountService extends Service { private boolean threadDisable; private int count; private ICountService.Stub serviceBinder = new ICountService.Stub() { @Override public int getCount() throws RemoteException { return count; } }; @Override public IBinder onBind(Intent intent) { return serviceBinder; } @Override public void onCreate() { super .onCreate(); new Thread( new Runnable() { @Override public void run() { while ( ! threadDisable) { try { Thread.sleep( 1000 ); } catch (InterruptedException e) { } count ++ ; Log.v( " CountService " , " Count is " + count); } } }).start(); } @Override public void onDestroy() { super .onDestroy(); this .threadDisable = true ; Log.v( " CountService " , " on destroy " ); } }
配置文件AndroidManifest.xml和上面的类似,没有区别。
在Activity中使用服务的差别不大,只需要对ServiceConnection中的调用远程服务的方法时,要捕获异常。
private ServiceConnection serviceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { countService = (ICountService) service; try { Log.v( " CountService " , " on serivce connected, count is " + countService.getCount()); } catch (RemoteException e) { throw new RuntimeException(e); } } @Override public void onServiceDisconnected(ComponentName name) { countService = null ; } };
这样就可以在同一个应用程序中使用远程服务的方式和自己定义的服务交互了。
如果是另外的应用程序使用远程服务,需要做的是复制上面的aidl文件和相应的包构到应用程序中,其他调用等都一样。
编写传递复杂数据类型的远程服务
远程服务往往不只是传递java基本数据类型。这时需要注意android的一些限制和规定:
android支持String和CharSequence
如果需要在aidl中使用其他aidl接口类型,需要import,即使是在相同包结构下;
android允许传递实现Parcelable接口的类,需要import;
android支持集合接口类型List和Map,但是有一些限制,元素必须是基本型或者上述三种情况,不需要import集合接口类,但是需要对元素涉及到的类型import;
非基本数据类型,也不是String和CharSequence类型的,需要有方向指示,包括in、out和inout,in表示由客户端设置,out表示由服务端设置,inout是两者均可设置。
这里将前面的例子中返回的int数据改为复杂数据类型:
package com.easymorse; import android.os.Parcel; import android.os.Parcelable; public class CountBean implements Parcelable { public static final Parcelable.Creator < CountBean > CREATOR = new Creator < CountBean > () { @Override public CountBean createFromParcel(Parcel source) { CountBean bean = new CountBean(); bean.count = source.readInt(); return bean; } @Override public CountBean[] newArray( int size) { return new CountBean[size]; } }; public int count; @Override public void writeToParcel(Parcel dest, int flags) { dest.writeInt( this .count); } @Override public int describeContents() { return 0 ; } }
然后,需要在相同包下建一个同名的aidl文件,用于android生成相应的辅助文件:
package com.easymorse;
parcelable CountBean;
这一步是android 1.5后的变化,无法通过adt生成aidl,也不能用一个比如全局的project.aidl文件,具体见:
http://www.anddev.org/viewtopic.php?p=20991
然后,需要在服务的aidl文件中修改如下:
package com.easymorse; import com.easymorse.CountBean; interface ICountService { CountBean getCount(); }
其他的改动很小,只需将CountService和调用CountService的部分修改为使用CountBean即可
转载:http://yangguangfu.iteye.com/blog/699306
发表评论
-
Android之SurfaceView实现视频播放
2016-03-22 00:53 8361.案例一 布局文件: <?xml ver ... -
谈谈Android中的SurfaceTexture
2016-03-22 00:52 792由于很多人要代码,我把代码下载链接放在这里了。不过还是要说一 ... -
Android 5.0(Lollipop)中的SurfaceTexture,TextureView,
2016-03-22 00:37 1440SurfaceView, GLSurfaceView, Su ... -
TextureView+SurfaceTexture+OpenGL ES来播放视频(一)
2016-03-22 00:34 1424文/子雷(简书作者) ... -
Android画图最基本的三个对象(Color,Paint,Canvas)
2015-11-29 15:41 0Android画图最基本的三个对象(Color,Paint, ... -
android资源地址
2015-11-08 15:31 0Android Fragment 真正的完全解析 ... -
关于android分辨率兼容问题(一)
2015-11-07 16:38 881关于手机分辨率相关术语和概念 屏幕尺寸:实际 ... -
并发队列ConcurrentLinkedQueue和阻塞队列LinkedBlockingQueue用法
2015-03-17 11:01 1152在Java多线程应用中,队列的使用率很高,多数生产消费模型的 ... -
RabbitMQ (五)主题(Topic)
2015-02-27 17:05 0转载请标明出处:http://blog.csdn.net/l ... -
RabbitMQ (四) 路由选择 (Routing)
2015-02-27 17:04 0上一篇博客我们建立了一个简单的日志系统,我们能够广播日志消 ... -
RabbitMQ (三) 发布/订阅
2015-02-27 17:02 1247转发请标明出处:http://blog.csdn.net/l ... -
RabbitMQ (二)工作队列
2015-02-27 17:01 1292转载请标明出处:http:/ ... -
RabbitMQ 入门 Helloworld
2015-02-27 17:00 1189转载请标明出处:http://blog.csdn.net/l ... -
Android之NDK开发
2015-01-20 16:20 648一、NDK产生的背景 ... -
Android推送方案分析(MQTT/XMPP/GCM)
2015-01-18 20:18 1132方案1、 使用GCM服务(Go ... -
android AsyncTask
2014-12-22 16:44 788/** * AsyncTask是抽象类, ... -
Androidndk开发打包时我们应该如何注意平台的兼容(x86,arm,arm-v7a)
2014-12-17 17:44 1279很多朋友在开发Android JNI的的时候,会遇到fi ... -
android对html支持接口总结
2014-12-15 16:40 731项目中往往需要显示一段文本,如果对文本需要特定的效果,就 ... -
Smali基本语法
2014-11-10 23:30 0.field private isFlag:z 定义变量 ... -
android的Environment类
2014-11-10 23:29 797String MEDIA_BAD_REMO ...
相关推荐
以上就是Service与Activity交互的三种主要方式:通过Intent、Binder和Messenger。每种方式都有其适用的场景,开发者应根据实际需求选择合适的方法。在实际开发中,还需要注意处理线程安全、内存泄漏等问题,确保应用...
本示例"Android Service与Activity交互"旨在演示如何在Service启动后,通过线程进行异步操作,并在完成特定任务后,通过发送广播(Broadcast)通知Activity来更新用户界面。 首先,我们需要创建一个Service,通常在...
总结来说,Android中的Activity和Service通过绑定的方式可以实现高效、灵活的交互,提供丰富的功能。开发者需要理解它们各自的生命周期,掌握绑定和解绑的时机,以及选择合适的通信机制,以保证应用的稳定性和性能。...
Activity代表用户界面,而Service则用于在后台执行长时间运行的任务,不直接与用户交互。在实际项目中,常常需要多个Activity与一个Service进行通信,比如本例中提到的“service在后台下载”场景。这种通信机制对于...
在Android应用开发中,`Service`和`Activity`是两个重要的组件。`Service`用于在后台执行长时间运行的任务,而`Activity`则负责用户界面交互。在某些场景下,我们可能需要在`Service`和`Activity`之间传递数据,比如...
总结来说,理解Activity与Service的数据交互机制是Android开发中的重要技能。通过bindService,我们可以创建强大的、动态的数据同步机制,使得后台任务与用户界面能够无缝协作,提升用户体验。同时,正确地管理...
综上所述,Service与Activity通过Broadcast进行交互是一种常见的Android组件通信方式,它能够实现组件间的松耦合,提高代码的可维护性。在实际开发中,需要根据具体需求选择合适的方式来实现组件间的交互。
在Android应用开发中,Activity和服务(Service)是两个核心组件,它们之间经常需要进行数据交互。Activity作为用户界面,提供与用户的交互,而Service则在后台执行长时间运行的任务,不依赖于用户界面。本篇文章将...
Activity可以通过bindService()方法来与Service建立绑定关系,这种绑定方式主要用于当Activity需要与Service进行频繁交互或需要获取Service提供的接口时。绑定后,Activity可以通过返回的IBinder对象与Service进行...
本文主要探讨了四种不同的方式来实现Activity与Service之间的交互,以实现特定的功能,例如更新下载进度。 首先,通过广播交互是一种常见的方法。Service在执行任务时,比如下载,可以创建一个BroadcastReceiver,...
本文将详细讲解Service与Activity的三种交互方式。 1. **通过startService()启动服务** 这种方式主要用于启动一个服务执行一次性或周期性的任务,例如上面的CountService示例。在`onCreate()`方法中,服务创建一个...
Service用于在后台执行长时间运行的任务,而Activity则负责用户界面交互。在某些场景下,我们可能需要Service与Activity之间进行数据传递,例如本例中的“Service向Activity传值,实现Count累加的效果。定时传值”。...
"Service和Activity通过Broadcast共享数据"就是解决这种需求的一种常见方式。Broadcast(广播)是Android系统中的一个关键组件,它允许应用程序在不直接互相通信的情况下发送和接收消息。 首先,我们来了解什么是...
将Activity与Service绑定是一种常见的通信方式,尤其在需要在后台运行任务且需要与用户界面保持交互时。本教程将重点讲解如何在Kotlin环境中实现Activity与Service的绑定、启动、解绑以及关闭过程。 1. **Service的...
在Android应用开发中,Activity和Service是两个非常重要的组件。Activity负责用户界面的展示,而Service则用于在后台执行长时间运行的任务,不依赖用户界面。然而,在某些情况下,Activity需要与Service进行通信,...
在本文中,我们将深入探讨两种常见的Service与Activity通信方式:通过Binder对象以及使用Messenger。 1. **通过Binder对象** Binder是Android系统提供的跨进程通信(IPC)机制,它允许不同进程间的对象互相调用...
2. **使用Messenger或AIDL**: 这种方式适用于需要更复杂的交互,例如Service向Activity传递数据对象。创建一个Message对象,并通过Binder接口在Service和Activity之间传递。在Service中创建一个Handler,用于处理...
Service主要用于在后台执行长时间运行的操作,而Activity则是用户与应用交互的界面。在某些场景下,我们需要在Activity和Service之间进行数据交换,以便在前台的Activity更新用户界面或利用Service获取的数据来驱动...