`

Activity中使用AIDL让Service与Activity通信

阅读更多
简易计算器,默认执行1+1的计算,点击go按钮执行计算,先看效果图,如下




首先建立一个ICallback.aidl文件,作为Activity中的回调方法

// My AIDL file, named SomeClass.aidl
package com.zhang.test.service;
// See the list above for which classes need
// import statements (hint--most of them)
// Declare the interface.
interface ICallback {
// Methods can take 0 or more parameters, and
// return a value or void.

// Methods can even take other AIDL-defined parameters.
//BankAccount createAccount(in String name, int startingDeposit, in IAtmService atmService);
// All non-Java primitive parameters (e.g., int, bool, etc) require
// a directional tag indicating which way the data will go. Available
// values are in, out, inout. (Primitives are in by default, and cannot be otherwise).
// Limit the direction to what is truly needed, because marshalling parameters
// is expensive.

void showResult(int result);
}


然后再建立一个IService.aidl用来在Activity中接收Service回调,以及在Service中onBind时返回的Binder
注意:aidl中import不能写com.xxx.*,要写全类的路径

package com.zhang.test.service;

import com.zhang.test.service.ICallback;

interface IService {
	void registerCallback(ICallback cb);
	void unregisterCallback(ICallback cb);
}


接下来是service,CalculateService.java

package com.zhang.test.service;

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.util.Log;

public class CalculateService extends Service {
	private static final String TAG = "MainService";

	public static final String ACTION_CALCUlATE = "action_calculate";
	private RemoteCallbackList<ICallback> mCallbacks = new RemoteCallbackList<ICallback>();

	private IService.Stub mBinder = new IService.Stub() {

		@Override
		public void unregisterCallback(ICallback cb) {
			if (cb != null) {
				mCallbacks.unregister(cb);
			}
		}

		@Override
		public void registerCallback(ICallback cb) {
			if (cb != null) {
				mCallbacks.register(cb);
			}
		}
	};
        
         //这里的BroadcastReceiver实现了Activity主动与Service通信
	private BroadcastReceiver receiver = new BroadcastReceiver() {

		@Override
		public void onReceive(Context context, Intent intent) {
			String action = intent.getAction();
			if (ACTION_CALCUlATE.equals(action)) {
				int first;
				int second;
				try {
					first = Integer.parseInt(intent.getStringExtra("first"));
					second = Integer.parseInt(intent.getStringExtra("second"));
					callBack(first, second);
				} catch (NumberFormatException e) {
					e.printStackTrace();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	};
	private Handler mHandler = new Handler() {

		@Override
		public void handleMessage(Message msg) {
			//默认计算1+1
                            callBack(1, 1);
			super.handleMessage(msg);
		}
	};

	@Override
	public IBinder onBind(Intent intent) {
		Log.d(TAG, "onBind");
		return mBinder;
	}

	@Override
	public void onCreate() {
		Log.d(TAG, "onCreate");
		// 这里不知道为什么,直接使用callback方法回调showResult
		// mCallbacks.beginBroadcast()是0,需要用handler延迟1000毫秒
		// 也许是在activity中binService太耗时的原因?
		mHandler.sendEmptyMessageDelayed(0, 1000);
		super.onCreate();
		IntentFilter filter = new IntentFilter(ACTION_CALCUlATE);
		registerReceiver(receiver, filter);

	}

	@Override
	public void onDestroy() {
		mHandler.removeMessages(0);
		mCallbacks.kill();
		super.onDestroy();
	}

	private void callBack(int first, int second) {
		int N = mCallbacks.beginBroadcast();
		try {
			for (int i = 0; i < N; i++) {
				mCallbacks.getBroadcastItem(i).showResult(first + second);
			}
		} catch (RemoteException e) {
			Log.e(TAG, "", e);
		}
		mCallbacks.finishBroadcast();
	}

}


然后是CalculateActivity:

package com.zhang.test;

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 android.view.View;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.TextView;

import com.zhang.test.service.ICallback;
import com.zhang.test.service.IService;
import com.zhang.test.service.CalculateService;

public class CalculateActivity extends Activity {
	private static final String TAG = "MainActivity";

	private IService mService;

	private EditText first;// 第一个计算数
	private EditText second;// 第二个计算数
	private Button calculate;// 计算按钮
	private TextView result;// 计算结果

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		setUpViews();
		setUpEvents();
		Intent i = new Intent(this, CalculateService.class);
		bindService(i, mConnection, Context.BIND_AUTO_CREATE);
	}

	private void setUpViews() {
		first = (EditText) findViewById(R.id.first);
		second = (EditText) findViewById(R.id.second);
		calculate = (Button) findViewById(R.id.calculate);
		result = (TextView) findViewById(R.id.result);
	}

	private void setUpEvents() {
		calculate.setOnClickListener(new CompoundButton.OnClickListener() {

			@Override
			public void onClick(View v) {
				Intent intent = new Intent(CalculateService.ACTION_CALCUlATE);
				intent.putExtra("first", first.getText().toString());
				intent.putExtra("second", second.getText().toString());
				sendBroadcast(intent);
			}
		});
	}

	@Override
	protected void onDestroy() {
		if (mService != null) {
			try {
				mService.unregisterCallback(mCallback);
			} catch (RemoteException e) {
				Log.e(TAG, "", e);
			}
		}
		// destroy的时候不要忘记unbindService
		unbindService(mConnection);
		super.onDestroy();
	}

	/**
	 * service的回调方法
	 */
	private ICallback.Stub mCallback = new ICallback.Stub() {

		@Override
		public void showResult(int result) {
			Log.d(TAG, "result : " + result);
			CalculateActivity.this.result.setText(result + "");
		}
	};

	/**
	 * 注册connection
	 */
	private ServiceConnection mConnection = new ServiceConnection() {

		@Override
		public void onServiceDisconnected(ComponentName name) {
			Log.d(TAG, "onServiceDisconnected");
			mService = null;
		}

		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			Log.d(TAG, "onServiceConnected");
			mService = IService.Stub.asInterface(service);
			try {
				mService.registerCallback(mCallback);
			} catch (RemoteException e) {
				Log.e(TAG, "", e);
			}
		}
	};
}

最后不要忘记在manifest中加上service标记:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.zhang.test"
      android:versionCode="1"
      android:versionName="1.0">
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".CalculateActivity"
                  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=".service.CalculateService" />
    </application>
    <uses-sdk android:minSdkVersion="3" />

</manifest>


布局文件,main.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="horizontal" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="计算:" />

    <EditText
        android:id="@+id/first"
        android:layout_width="50dip"
        android:layout_height="wrap_content"
        android:text="1" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="+" />

    <EditText
        android:id="@+id/second"
        android:layout_width="50dip"
        android:layout_height="wrap_content"
        android:text="1" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="=" />

    <TextView
        android:id="@+id/result"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <Button
        android:id="@+id/calculate"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="go" />

</LinearLayout>


运行程序,查看Logcat
结果如下:



总结:
通过aidl总算实现了Service与Activity的通信,写起来麻烦点,使用诸如ContentProvider,Broadcast等也可以实现.
这样做很像是在使用MVC设计模式(Activity负责View,Service以及其他类负责Model,aidl(ServiceConnection)负责Controller)

源码见附件
  • 大小: 30.4 KB
  • 大小: 7.4 KB
分享到:
评论

相关推荐

    Activity和Service生命周期及使用AIDL通信实例备份

    本篇将深入探讨Activity和Service的生命周期以及如何利用Android Interface Definition Language (AIDL)进行进程间通信。 Activity是Android应用程序的用户界面,它负责与用户交互。Activity的生命周期分为几个关键...

    通过aidl service调用activity

    总结,通过AIDL,我们可以使Service与Activity在不同进程中相互通信,实现跨进程调用。同时,Service还可以通过Intent启动Activity。在实际开发中,需要注意跨进程通信的安全性和效率,合理设计接口,以提供高效且...

    AIDL Demo源码实现Activity与Service进程间通信

    当一个Service在不同的进程中运行时,如果需要与Activity通信,就需要使用AIDL来定义接口并实现跨进程调用。 下面是一步步实现AIDL Demo的过程: 1. **创建AIDL接口**: 在项目的`src/main/aidl`目录下创建一个新...

    Activity与远程Service通信,使用AIDL

    本篇文章将详细探讨如何使用AIDL实现Activity与远程Service的通信。 首先,理解AIDL的基本概念。AIDL是Android为了解决不同进程间的对象交互问题而设计的一种工具,它可以生成Java代码,使得在不同进程中运行的对象...

    android 本地服务通信 AIDL service服务与activity之间的通信

    本示例“android 本地服务通信 AIDL service服务与activity之间的通信”通过一个学号查询学生的例子,清晰地展示了如何利用AIDL实现在Activity和Service之间的数据传递。 首先,我们需要了解AIDL的基本概念。AIDL...

    aidl双向通信,Service加回调刷新自身Activity

    标题“aidl双向通信,Service加回调刷新自身Activity”涉及了两个关键概念:AIDL的双向通信以及通过Service回调更新Activity。 首先,让我们深入理解AIDL。AIDL是用来定义接口的,这些接口可以让一个Android进程...

    android Activity调用&&aidl;

    为了启动一个Activity,我们需要在AndroidManifest.xml文件中声明它,并在代码中使用Intent对象。例如,创建一个新的Intent,指定目标Activity的类名,然后调用startActivity()方法: ```java Intent intent = new ...

    service与activity之间的通信

    二、Service与Activity通信方式 1. startService(): 当Activity启动Service时,可以通过Intent传递数据。Service在onStartCommand()方法中接收这些数据,处理完任务后通过BroadcastReceiver或者返回结果到调用start...

    Activity和Service通过aidl交互(跨进程)

    下面我们将详细探讨如何通过AIDL让Activity和Service在不同的应用之间进行交互。 首先,AIDL是一种接口定义语言,它的主要作用是定义一个可以在不同进程间调用的接口。当我们创建一个AIDL文件时,实质上是在定义一...

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

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

    aidl.rar_AIDL_AIDL.rar_android AIDL service_android service_andr

    AIDL(Android Interface Definition Language)是Android系统提供的一种接口定义语言,用于在不同进程间进行通信,特别是当服务(Service)需要与客户端(如Activity)跨进程交互时。AIDL帮助开发者定义接口,使得...

    安卓Service和AIDL使用示例代码

    本示例代码将探讨如何在Android应用中使用Service和AIDL。 1. **Service基础** - **Service生命周期**:Service有其特定的生命周期,包括onCreate(), onStartCommand(), onBind(), onRebind(), onUnbind(), 和 ...

    Service与Activity通信示例

    本示例将深入探讨这个主题,帮助开发者更好地掌握Android中的Service和Activity通信机制。 首先,我们要了解Service的基本概念。Service是一种没有用户界面的组件,它可以在后台运行,执行任务,如播放音乐、处理...

    Android开发-Activity与Service使用Messenger通信代码

    然而,在某些情况下,Activity需要与Service进行通信,例如更新UI或者传递数据。在这种场景下,Android提供了多种进程间通信(IPC,Inter-Process Communication)方式,其中之一就是使用Messenger。本文将详细讲解...

    Android Studio AIDL实现跨进程通信

    本篇文章将深入探讨如何在Android Studio中使用AIDL来实现跨进程通信。 首先,我们需要理解AIDL的基本概念。AIDL是一种接口定义语言,它允许开发者声明服务端提供的接口,客户端通过这些接口调用服务端的方法,实现...

    AIDL 双向通信

    在Android应用开发中,当需要一个服务(Service)与另一个进程中的组件(如Activity)进行数据交换时,AIDL就显得尤为重要。本篇将深入探讨AIDL如何实现Activity与Service之间的双向通信。** ### 一、AIDL基本概念 ...

    浅析aidl过程和绑定service的过程(不会使用的撤).zip

    在Android系统中,AIDL(Android Interface Definition Language)和Service是两个重要的组件,它们分别用于进程间通信(IPC,Inter-Process Communication)和后台服务执行。本篇文章将深入探讨AIDL的工作原理以及...

    Android跨进程使用aidl通信。

    在Android系统中,进程间通信(IPC,Inter-Process Communication)是实现不同应用程序之间数据交换的关键技术。Android Aidl(Android Interface Definition Language)是官方提供的一种用于实现跨进程通信的接口...

Global site tag (gtag.js) - Google Analytics