`

Service使用方式

 
阅读更多

 

使用Service的场合:

1.一个或多个Activity需要向同一应用中的Service发出执行某一操作的命令。

PS:不需要绑定

 

 

 

2.某个Activity需要同一应用中的Service为其单独服务,当此Activity消毁时,也将为其服务的Service一并消毁。

PS:需要绑定

 

 

 

3.多个Activity绑定到同一个Service,仅当所有Activity取消了绑定,Service才消毁。

PS:只有第一个Activity绑定时才调用onBind()方法,第二个、第三个....第N个直接取得第一个Activity绑定时onBind()方法返回的IBinder对象

 

 

 

4.即使退出当前应用时,仍希望Service继续运行(如:上传或下载任务);或者此Service为其他应用提供服务。

PS:需要跨进程通信(IPC)

4.1当远程服务不需要支持多线程时,使用Messager.

 

Server端应用代码

 

public class RemoteServiceProxy extends Service {
    public static final int GET_RESULT = 1;
    private final Messenger mMessenger = new Messenger(new Handler() {
        private int status = 0;
        @Override
        public void handleMessage(Message msg) {
            if (msg.what == GET_RESULT) {
                try {
                    msg.replyTo.send(Message.obtain(null, GET_RESULT, status++, 0));
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            } else {
                super.handleMessage(msg);
            }
        }
    });
    
    @Override
    public IBinder onBind(Intent intent) {
        return mMessenger.getBinder();
    }
}

 

 

 

<service android:name=".module.photo.RemoteServiceProxy"
                 android:process=":remote" />
 

 

Client端应用代码

 

//开启一个服务
bindService(new Intent(this, RemoteServiceProxy.class), mConnection, BIND_AUTO_CREATE);

private Messenger mService;
private ServiceConnection mConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mService = new Messenger(service);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
        }
};
 

private Messenger mMessenger = new Messenger(new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if (msg.what == RemoteServiceProxy.GET_RESULT) {
                Log.i("M", "From Remote Service "+msg.arg1);
            } else {
                super.handleMessage(msg);
            }
        }
});

Message message = Message.obtain(null, RemoteServiceProxy.GET_RESULT);
message.replyTo = mMessenger;
try {
        mService.send(message);
} catch (RemoteException e) {
        e.printStackTrace();
}
 

 

 

4.2当远程服务需要同时响应多个Client的请求,使用AIDL.

注意:一般我们应用中是不需要使用AIDL的,这里仅仅是为了学习和深入理解Android的IPC机制。

 

Server端应用代码

 

在Server端应用新建IRemoteService.aidl和IRemoteCallback.aidl文件,编辑内容如下

 

 

package com.example.aidl;

interface IRemoteCallback {
    void executeCallback(String msg);
}

 

 

package com.example.aidl;

import com.example.aidl.IRemoteCallback;

interface IRemoteService {
    //注册回调
    void register(IRemoteCallback callback);
    //取消注册回调
    void unregister(IRemoteCallback callback);
    //执行回调
    void execute();
    //获取状态
    int getStatus(String flag);
}

 

创建Service类为客户端提供服务

 

 

package com.example.server.service;

import com.example.aidl.IRemoteCallback;
import com.example.aidl.IRemoteService;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.util.Log;

public class RemoteService extends Service {

	@Override
	public IBinder onBind(Intent intent) {
		return iBinder;
	}
	
	private final RemoteCallbackList<IRemoteCallback> remoteCallbackList = new RemoteCallbackList<IRemoteCallback>(); 
	
	private IRemoteService.Stub iBinder = new IRemoteService.Stub() {
		@Override
		public void register(IRemoteCallback cb) throws RemoteException {
			if (cb != null) remoteCallbackList.register(cb);
		}

		@Override
		public void unregister(IRemoteCallback cb) throws RemoteException {
			if (cb != null) remoteCallbackList.unregister(cb);
		}

		@Override
		public void execute() throws RemoteException {
			int size = remoteCallbackList.beginBroadcast();
			while (size > 0) {
				size--;
				remoteCallbackList.getBroadcastItem(size).executeCallback("Hello, Client.");
			}
			remoteCallbackList.finishBroadcast();
			Log.i("RS", "RemoteService.execute() has done.");
		}

		int status;
		@Override
		public int getStatus(String flag) throws RemoteException {
			Log.i("RS", "RemoteService.getStatus(flag) flag is "+flag);
			if ("reset".equals(flag)) status = 0;
			return status++;
		}
	};
}

 

在AndroidManifast.xml中配置Service,必需设置Action过滤

 

 

<service android:name=".server.service.RemoteService" android:process=":remote">
            <intent-filter>
            	<action android:name="test.remote.service"/>
            </intent-filter>
</service>
 

 

 

Client端应用代码

 

将Server端创建的IRemoteService.aidl和IRemoteCallback.aidl文件copy到Client端应用中

 

在Client端获取Server端的RemoteService对象的引用

 

 

package com.example;

import com.example.aidl.IRemoteCallback;
import com.example.aidl.IRemoteService;

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.os.RemoteException;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Toast;

public class ClientActivity extends Activity {
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.client_activity);
		
		/*
		   绑定远程服务,与其他进程Service通信。
		   注意:Client需要通过Action与RemoteService绑定,因为Client端是没有RemoteService.class的
		 */
		this.bindService(new Intent("test.remote.service"), sConnection, BIND_AUTO_CREATE);
		
		this.findViewById(R.id.execute_callback).setOnClickListener(mOnClickListener);
		this.findViewById(R.id.get_status).setOnClickListener(mOnClickListener);
	}

	private OnClickListener mOnClickListener = new OnClickListener() {
		@Override
		public void onClick(View button) {
			try {
				if (button.getId() == R.id.execute_callback) remoteService.execute();
				else {
					int remoteStatus = remoteService.getStatus("set");
					Toast.makeText(getApplicationContext(), "Status: "+remoteStatus+" is from RemoteService", Toast.LENGTH_LONG).show();
				}
			} catch (RemoteException e) {
				e.printStackTrace();
			}
		}
	};
	
	private IRemoteService remoteService;//远程服务
	private ServiceConnection sConnection = new ServiceConnection() {
		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			remoteService = IRemoteService.Stub.asInterface(service);
			//注册回调
			try {
				remoteService.register(remoteCallback);
			} catch (RemoteException e) {
				e.printStackTrace();
			}
		}

		@Override
		public void onServiceDisconnected(ComponentName name) {
			//意外断开连接时回调
			remoteService = null;
		}
	};
	
	private IRemoteCallback.Stub remoteCallback = new IRemoteCallback.Stub() {
		@Override
		public void executeCallback(String msg) throws RemoteException {
			Toast.makeText(getApplicationContext(), "ClientActivity: "+msg, Toast.LENGTH_LONG).show();
		}
	};
}
 

 

 

 

分享到:
评论
3 楼 大智若愚 2013-03-28  
学习一下
2 楼 wangguangji 2011-11-29  
不好意思 是我不会弄!是可以运行的!
1 楼 wangguangji 2011-11-29  
怎么你的这些代码 都编辑不能通过呢!不好意思我是初学android

相关推荐

    Service服务的各种使用方式

    在Android开发中,Service是四大组件之一,它用于在后台执行...理解并熟练运用各种Service使用方式,能够帮助开发者实现丰富的后台功能,提升应用体验。通过ServiceDemo项目,初学者可以更直观地学习和实践这些知识点。

    Service的使用方式

    本文将深入探讨`AccessibilityService`的使用方式,这是Service的一种特殊类型,主要用于帮助残障人士或者实现自动化操作。对于初学者来说,理解并掌握AccessibilityService的用法是非常有价值的。 首先,我们要...

    IOTService_使用说明_202007081

    安装完成后,用户可以通过桌面快捷方式或开始菜单启动IOTSERVICE工具。 3. 串口服务器设备连接 串口服务器设备是物联网系统中的重要组成部分,它们负责将串行数据转换为网络数据,以便于远程通信。IOTService支持...

    StartService方式启动Service

    `StartService` 的使用方式如下: ```java Intent intent = new Intent(this, MyStartService.class); startService(intent); ``` 这里 `MyStartService` 是我们自定义的 `Service` 类,需要继承自 `android.app....

    Java Service Wrapper使用总结

    Java Service Wrapper 使用总结 Java Service Wrapper 是一种可以将 Java 应用程序发布为可安装的服务的解决方案,它提供了一种简单的方式来将 Java 应用程序打包成一个独立的服务。下面是 Java Service Wrapper ...

    service的生命周期以及启动方式

    1. **启动方式(Started)**:使用`startService()`启动Service。这种方式下,Service会在后台持续运行,直到`stopService()`或`stopSelf()`被调用。适合执行不需要客户端交互的长时间任务,如音乐播放。 2. **绑定...

    android service使用详解

    本篇文章将深入探讨如何在Android中使用Service。 一、Service的基本概念 Service是Android系统中的一个特殊组件,它可以在后台运行,不与用户界面直接交互。Service可以启动(Start)或绑定(Bind),两种方式各有...

    Android service start方式启动

    本示例将探讨“startService”方式启动Android服务的基本概念、工作原理以及如何实现一个简单的服务示例。 首先,我们需要理解`startService()`这个方法。当你调用`startService()`时,Android系统会启动指定的服务...

    Service的入门,主要介绍service的概念和使用方法

    本资料包包括三个部分:15.Service学习(1).rar、16.Service学习(2).rar和17.Service学习(3).rar,分别深入讲解了Service的基本概念、启动方式以及实际应用。 首先,我们来了解一下Service的基本概念。Service是...

    Android Service使用示例

    本示例将详细介绍如何使用 `Service`,特别是 `Start Service` 和 `Bind Service` 两种启动方式,以及如何实现 `Service` 与 `Activity` 之间的数据交互。 ### 1. Start Service `Start Service` 主要用于启动一个...

    Service使用demo(Eclipse)

    本示例"Service使用demo(Eclipse)"将深入讲解如何在Eclipse环境中集成并运用Service,同时结合BroadcastReceiver实现更灵活的应用场景。 首先,我们来详细了解Service的基本概念。Service主要分为两种类型:START...

    广播方式与service通信

    在这个主题中,我们将深入探讨Service与Activity的通信以及使用广播方式进行通信。 首先,Service与Activity通信主要有以下几种方式: 1. ** Binder对象**:Service可以通过实现IBinder接口创建自己的Binder对象,...

    ServiceNow 基础手册

    ServiceNow平台的基础手册涵盖了该平台的基本使用方法,包括如何导航、管理记录以及搜索等操作。以下是对手册内容的详细解读。 首先,ServiceNow用户界面是与应用程序和信息交互的主要方式。ServiceNow的用户界面...

    Activity绑定Service(Kotlin)

    将Activity与Service绑定是一种常见的通信方式,尤其在需要在后台运行任务且需要与用户界面保持交互时。本教程将重点讲解如何在Kotlin环境中实现Activity与Service的绑定、启动、解绑以及关闭过程。 1. **Service的...

    Service 的基础使用方法

    创建Service主要有两种方式:通过继承`Service`类和实现其生命周期方法,或者使用`IntentService`,这是一种已经封装好的单线程Service,适用于执行简单的异步任务。 1. **创建自定义Service** - 首先,继承`...

    Service 启动与停止

    1. startService(): 这种方式启动的Service会执行onStartCommand()方法,每次调用startService()都会将Intent传递给Service并执行一次onStartCommand()。即使Service已经在运行,每次调用startService()也会触发新的...

    C#使用Http Post方式传递Json数据字符串调用Web Service

    C#中通过直接添加引用的方来调用Web Service的方式不够灵活,故采取手动发送Http请求的方式来调用Web Service。最后选择使用Post方式来调用Web Service

    BindService

    总结,`BindService`是Android中一种重要的Service使用方式,它提供了更灵活和高效的方式来与Service交互。在设计需要长时间运行并需要与UI组件通信的服务时,`BindService`是一个很好的选择。理解和熟练运用这个...

    进程内Activity和service使用Binder通信代码备份

    3. Activity绑定Service并使用Binder:在Activity中,我们可以通过bindService()方法绑定到Service,并在onServiceConnected()回调中获取到Binder对象。之后就可以调用Service中定义的方法了。 ```java public ...

    Service的三种交互方式源码

    Service的三种交互方式主要包括:通过Intent启动(startService)、绑定(bindService)以及混合使用这两种方法。下面我们将深入探讨这三种交互方式的源码实现及其应用场景。 一、启动Service(startService) ...

Global site tag (gtag.js) - Google Analytics