Activity与Service的交互二

在上一篇文章中讲解了如何利用Messenger和Binder类来实现与Activity的通信,这次就讲解下其他的两种通讯方式。不管是哪一种通讯,我们首先需要创建一个Service,下面就先创建一个Service,看过上一篇文章的就可以直接跳过这里。

Service的创建

1.创建MySerVice类继承Service并重写相关方法

    public class MyService extends Service {  
        public MyService() {  
        }  
      
        @Override  
        public IBinder onBind(Intent intent) {  
            // TODO Auto-generated method stub  
            return null;  
        }  
          
    }  

2.注册清单配置文件

    <application>  
    ...  
    <service android:name=".MyService" />  
    </application>

一、使用广播通讯

在Android的系统中,广播是大家经常用到的组件,比如我们希望一个软件在开机的时候就自动重启,其实就是利用了系统启动时发出的广播,我们接受到这个广播就开始运行我们的程序。这里只会简单使用广播机制,不会过多的阐述广播的实现,有需要的话我会在以后另外贴出。下面就开始使用它来完成我们的通讯:

1.activity_main.xml

添加两个按钮便于测试

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <Button
        android:id="@+id/button1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="onClick01"
        android:text="启动" />

    <Button
        android:id="@+id/button2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="onClick02"
        android:text="停止" />

</LinearLayout>

2.MainActivity.java

创建内部类继承BroadcastReceiver来实现广播消息的处理,并在Activity加载时注册广播

public class MainActivity extends Activity {
	//用于测试数据
	private int count;
	//Service的Intent对象
	private Intent intent;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		intent=new Intent(this, MyService.class);
		//注册广播
		MyReceiver receiver=new MyReceiver();
		IntentFilter filter=new IntentFilter();
		filter.addAction("com.receiver");
		registerReceiver(receiver, filter);
	}
	/**
	 * 启动服务
	 * @param v
	 */
	public void onClick01(View v){
		startService(intent);
	}
	/**
	 * 停止服务
	 * @param v
	 */
	public void onClick02(View v){
		stopService(intent);
	}
	@Override
	protected void onDestroy() {
		super.onDestroy();
		stopService(intent);
	}
	/**
	 * 内部内实现广播接口
	 * @author mm
	 *
	 */
	class MyReceiver extends BroadcastReceiver{
		@Override
		public void onReceive(Context context, Intent intent) {
			Log.i("Tag","count="+count++);
		}
	}
}

2.MyService.java

在service启动时,利用定时器不停的给Activity发送广播

public class MyService extends Service {
	private Intent intent;
	// 创建定时器对象
	private Timer mTimer;
	public MyService() {
	}
	/**
	 * 指定时间执行的任务类
	 * 
	 * @author mm
	 *
	 */
	class MyTimerTask extends TimerTask {
		@Override
		public void run() {
			Log.i("Tag", "sendBroadcast");
			// 发送广播
			sendBroadcast(intent);
		}
	}
	@Override
	public void onCreate() {
		super.onCreate();
		// 关联广播的Action
		intent = new Intent("com.receiver");
		mTimer = new Timer();
		// 每隔一秒发送一次广播
		mTimer.schedule(new MyTimerTask(), 0, 1000);
	}
	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		return null;
	}
	/**
	 * service销毁时,关闭定时器mTimer
	 */
	@Override
	public void onDestroy() {
		super.onDestroy();
		mTimer.cancel();
	}
}

程序运行结果图:

二、使用AIDL交互

  AIDL是Android Interface Definition Language的首字母缩写, 也就是Android接口定义语言。AIDL属于Android的IPC机制,常用于跨进程通信,主要实现原理基于底层Binder机制。

1、创建AIDLService端

1.1IDataService.aidl

在指定包中,创建文件IDataService.aidl文件,内容如下:

package com.example.adilservice;//包名

interface IDataService{
//自定义方法
 String getData();
}
保存后会在gen目录下生成IDataService.java文件,如下图所示

1.2ADILService.java

创建ADILService,返回绑定参数

public class ADILService extends Service {

	class AIDLServerBinder extends IDataService.Stub {

		@Override
		public String getData() throws RemoteException {
			return "data on service";
		}
	}

	@Override
	public IBinder onBind(Intent intent) {
		return new AIDLServerBinder();
	}
}
运行程序,使该Service驻留在手机内

2、创建ADILClient端

在使用前需要将aidl文件文件拿过来,如下图所示


2.1.activity_main.xml

在布局文件中加入一个按钮。便于测试

 <Button 
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="talk"
       android:onClick="onClick"/>

2.2.MainActivity.java

public class MainActivity extends Activity {
	private IDataService iDataService;
	private ServiceConnection conn = new ServiceConnection() {
		//绑定异常执行
		@Override
		public void onServiceDisconnected(ComponentName name) {
		}
		//绑定成功执行
		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			iDataService=IDataService.Stub.asInterface(service);
		}
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
	}
	public void onClick(View v){
		String data=null;
		try {
			data=iDataService.getData();
		} catch (RemoteException e) {
			e.printStackTrace();
		}
		Log.i("Tag", "data="+data);
	}
	@Override
	protected void onStart() {
		super.onStart();
		bindService(new Intent("com.example.adilservice"), conn,
				BIND_AUTO_CREATE);
	}
	@Override
	protected void onDestroy() {
		super.onDestroy();
		unbindService(conn);
	}
}

小结

service的数据交互到这就告一段落了,以后要有其他新的方法还会再次给出。如果有问题请帮忙指出 :)




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章