Service 包括bound Service和unbound Service.首先我们先讨论unBound Service使用方法。详细内容可参考官方dev guide
创建一个Service 有两种方式,一是继承IntentService,或者继承Service。
一,unbound service(未绑定activity,service执行完任务后要自己停止,stopself 或者stopservice)
1、IntentSerivce
IntentService 是Service的一个子类,操作上是单线程的。当Intent Start 这个IntentService时,IntentService会自动执行onHandleIntent(Intent intent)里面的方法。IntentService对于每一个请求会创建一个工作线程进行处理,处理完成
后结束工作。对于不要求多线程,同步的程序,IntentService使用起来比较方便。把dev guide里面的例子拿过来。
public class HelloIntentService extends IntentService {
/**
* A constructor is required, and must call the super IntentService(String)
* constructor with a name for the worker thread.
*/
public HelloIntentService() {
super("HelloIntentService");
}
/**
* The IntentService calls this method from the default worker thread with
* the intent that started the service. When this method returns, IntentService
* stops the service, as appropriate.
*/
@Override
protected void onHandleIntent(Intent intent) {
// Normally we would do some work here, like download a file.
// For our sample, we just sleep for 5 seconds.
long endTime = System.currentTimeMillis() + 5*1000;
while (System.currentTimeMillis() < endTime) {
synchronized (this) {
try {
wait(endTime - System.currentTimeMillis());
} catch (Exception e) {
}
}
}
}
}
IntentService实际上是在Service上面添加了消息循环,Intent和IntentService的生命周期一致,所以每次处理请求是都会new 一个Thread进行处理工作,可以查看源码,参考博客地址http://android.blog.51cto.com/268543/528166,上面源码分析的很详细。
2、Service,如要程序要求同步,多线程,可以选择继承Service,这里需要自己手动写消息循环。Handler,loop。之参考dev guide 上面的例子,这个例子与上面的IntentService效果一致,一次只能助理一个请求。
public class HelloService extends Service {
private Looper mServiceLooper;
private ServiceHandler mServiceHandler;
// Handler that receives messages from the thread
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
// Normally we would do some work here, like download a file.
// For our sample, we just sleep for 5 seconds.
long endTime = System.currentTimeMillis() + 5*1000;
while (System.currentTimeMillis() < endTime) {
synchronized (this) {
try {
wait(endTime - System.currentTimeMillis());
} catch (Exception e) {
}
}
}
// Stop the service using the startId, so that we don't stop
// the service in the middle of handling another job
stopSelf(msg.arg1);
}
}
@Override
public void onCreate() {
// Start up the thread running the service. Note that we create a
// separate thread because the service normally runs in the process's
// main thread, which we don't want to block. We also make it
// background priority so CPU-intensive work will not disrupt our UI.
HandlerThread thread = new HandlerThread("ServiceStartArguments",
Process.THREAD_PRIORITY_BACKGROUND);
thread.start();
// Get the HandlerThread's Looper and use it for our Handler
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
// For each start request, send a message to start a job and deliver the
// start ID so we know which request we're stopping when we finish the job
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
mServiceHandler.sendMessage(msg);
// If we get killed, after returning from here, restart
return START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
// We don't provide binding, so return null
return null;
}
@Override
public void onDestroy() {
Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show();
}
}
二、bound service
当Service 和activity绑定之后,直到所有的activity结束绑定后,service才结束,一个service可以被多个activity绑定,具体声明周期参考官网Dev Guide。
bound service启动时通过其他Application(activity)调用 bindservice()方法启动,结束是用unbindSerivce();
在service中实现onbind(IBundler)方法,返回一个IBundler。通过IBundler与Activity进行信息交互IPC。这里需要定义一个接口用来传递Service中的方法和信息。原文如下:
To create a bound service, the first thing you must do is define the interface that specifies how a client can communicate with the service. This interface between the service and a client must be an implementation of IBinder
and is what your service must return from the onBind()
callback method. Once the client receives the IBinder
, it can begin interacting with the service through that interface.
1、继承binder。在service类中写一个继承自binder的内部类,在此内部类中写一个获得该Service实例的公共方法,这样Activity绑定Service的时候可以拿到这个binder,进一步拿到Service的实例,调用Service的各种方法。注意,这种消息方式只在同一个应用内使用,如果Service是其他Application调用的,需要后面的方法。
参考DEV GUIDE 上面的例子如下
import java.util.Random;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
public class LocalService extends Service{
private LocalBinder mBinder = new LocalBinder();
private Random mGenerator = new Random();
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
public class LocalBinder extends Binder
{
public LocalService getLocalService()
{
return LocalService.this;
}
}
public int getRandomNum()
{
return mGenerator.nextInt();
}
}
import com.android.service.LocalService.LocalBinder;
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.view.View;
import android.widget.Button;
public class LocalActivity extends Activity{
private LocalService localService;
boolean mBound = false;
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
mBound = false;
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
LocalBinder localBinder = (LocalBinder) service;
localService = localBinder.getLocalService();
mBound = true;
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
@Override
protected void onStop() {
super.onStop();
if(mBound)
{
unbindService(mConnection);
mBound = false;
}
}
@Override
protected void onStart() {
super.onStart();
Intent intent = new Intent(this,LocalService.class);
bindService(intent, mConnection , Context.BIND_AUTO_CREATE);
}
//点击button,onclick属性在xml中配置
public void click(View v)
{
Button button = (Button) v;
button.setText(String.valueOf(localService.getRandomNum()));
}
}
2、使用Messenger。通过Messenger发送消息到服务端。主要分为以下几个步骤
1)在Service子类中创建一个Handler子类的(内部类的方式),写好handlmessage方法
2)用Handler的子类创建一个Messenger
3)返回Messenger.getBinder();获得bundler,在onbind();方法中返回给Activity
4)在Activity中获得Binder,用这个binder构造一个Messenger,使用这个Messenger 发送message
注意如果处理响应容易死掉的任务,如获取网络数据,Hander用一个Looper构造,创建一个Handler线程处理任务,
HandlerThread.start(). HandlerThread.getLooper(); 这个Looper用来创建Handler
下面上代码,同样是参考DEV GUIDE 感觉本来做笔记,怎么写成一个翻译了- -!
import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.Messenger;
import android.os.Process;
import android.widget.Toast;
public class MyMessager extends Service {
Looper handlerLooper;
static final int MSG_SAY_HELLO = 1;
@Override
public void onCreate() {
super.onCreate();
HandlerThread mHandlerThread = new HandlerThread("mHandlerThread",
Process.THREAD_PRIORITY_BACKGROUND);
mHandlerThread.start();
handlerLooper = mHandlerThread.getLooper();
mServiceMessager = new Messenger(new IncomingHander(handlerLooper));
}
@Override
public IBinder onBind(Intent intent) {
return mServiceMessager.getBinder();
}
class IncomingHander extends Handler {
public IncomingHander(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_SAY_HELLO:
Toast.makeText(getApplicationContext(), "hello",
Toast.LENGTH_SHORT).show();
System.out.println("hello runs");
break;
default:
super.handleMessage(msg);
}
}
}
Messenger mServiceMessager;
}
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.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.view.View;
import android.widget.Button;
public class ActivityMessenger extends Activity{
private Messenger mMessenger;
private boolean mBound;
private ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
mMessenger = null;
mBound = false;
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mMessenger = new Messenger(service);
mBound = true;
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
@Override
protected void onStart() {
super.onStart();
Intent i = new Intent(this,MyMessager.class);
bindService(i, conn , Context.BIND_AUTO_CREATE);
}
public void click(View v)
{
Message msg = Message.obtain(null, MyMessager.MSG_SAY_HELLO, 0, 0);
try {
mMessenger.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
protected void onStop() {
super.onStop();
unbindService(conn);
mBound = false;
}
}
三、通过AIDL进行多线程,跨进程通信。这个步骤相对麻烦,也没完全弄懂,以后补上
以上内容纯属个人学习笔记,技术有限,希望不会误导其他人
分享到:
相关推荐
了解了Service的基本原理和使用方法后,我们可以结合ACDemo这个项目进行实践。该项目很可能是包含了一个简单的Service示例,展示了如何创建、启动、绑定Service以及使用Binder进行跨进程通信。通过分析ACDemo的源...
在Android应用开发中,`Service` 是一个非常重要的组件,用于在后台长时间运行任务,即使用户界面(Activity)...通过实践,你将更好地掌握 `Service` 的使用方法和技巧,为你的 Android 应用程序提供强大的后台支持。
android service使用的小demo 包括startService stopService bindService unbindService 两种开启、关闭service的小demo
理解它们的使用方法和注意事项,对于构建高效、稳定的应用至关重要。通过“android service toast 01”这个项目,开发者可以深入学习Android后台服务的使用,以及如何在非主线程中正确地更新用户界面。
在Android应用开发中,Service是四大核心组件之一,它主要用于执行长时间运行的后台任务,而不会受到用户界面交互的影响。...理解Service的使用方式和生命周期对于构建高效、稳定的Android应用至关重要。
总之,Android Service和EventBus的结合使用为Android应用提供了强大的后台处理和界面更新能力。Service负责后台任务,EventBus则作为通信桥梁,使得数据在Service和界面之间传递变得更加简单和高效。在实际项目中,...
本篇文章将深入探讨如何在Android中使用Service。 一、Service的基本概念 Service是Android系统中的一个特殊组件,它可以在后台运行,不与用户界面直接交互。Service可以启动(Start)或绑定(Bind),两种方式各有...
在`Activity`中启动`Service`,通常使用`startService()`方法,需要传入一个`Intent`对象,`Intent`中可以携带数据。例如: ```java Intent intent = new Intent(this, MyService.class); // 如果需要传递数据,...
4. 使用`startService()`或`bindService()`方法启动或绑定到Service。 接下来是Remote Service,它是运行在不同应用程序进程中的服务,通常用于跨进程通信(IPC)。Remote Service通过AIDL(Android Interface ...
本项目"Android 带进度条的使用Service实现的音乐播放器"聚焦于如何在后台Service中使用MediaPlayer类来实现音乐播放,并结合UI界面展示播放进度。以下是这个项目涉及到的关键知识点: 1. **Android Service**: ...
本文将深入探讨`Android Service`和定时器的基本概念、使用方法以及如何结合它们来实现每3秒打印一次日志的功能。 **Android Service** `Android Service`是一种在后台运行且不与用户界面直接交互的应用组件。它...
我们可以在Service的onStartCommand()或onBind()方法中创建新的线程,如使用Handler、AsyncTask或者Thread/Runnable。这样可以确保Service的后台任务不会影响到用户界面的响应速度。 4. AIDL方式的Service AIDL...
启动Service通常使用Context的startService()方法,而停止Service则使用stopService()。例如: ```java Intent intent = new Intent(this, MyService.class); startService(intent); // 启动Service stopService...
本篇文章将深入探讨`startService`类型的Android Service,通过一个简单的实例来展示其工作原理和使用方法。 `Service`分为两种主要类型:`Start Service`和`Bound Service`。`Start Service`主要用于执行非交互式...
"Android Service Demo"是一个示例项目,旨在展示如何在Android应用中使用Service。这个项目包含了从Activity启动Service以及Service内部的运作逻辑。 在Android中,Activity是用户与应用交互的界面,而Service则...
这篇博客文章将深入介绍Android Service类的基本概念、功能、生命周期以及如何在实际应用中使用。 首先,Service不同于Activity,Activity是用户可见且可交互的组件,而Service则是隐藏在后台运行,它不包含用户...
描述提到"android 后台服务定时更新前台Activity Ui 通过广播",这涉及到了Android的Service、UI更新以及BroadcastReceiver(广播接收器)的使用。 首先,Android的`Service`是用于执行长时间运行操作而不与用户...
8. **调试与优化**:在开发过程中,使用Android Studio的Logcat工具进行日志输出,可以帮助调试Service的生命周期和功能。同时,要注意优化Service的资源使用,避免影响用户的设备性能和电池寿命。 综上所述,QT ...
在本教程中,我们将探讨如何在Android中创建并使用一个简单的Service。 首先,让我们理解Service的基本概念。Service生命周期包含几个关键方法,它们是onCreate()、onStartCommand()、onBind()、onUnbind()和...