通过一个例子熟悉安卓组件通信:
第一:编写MainActivity:
package com.momo.componentcommunication;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity {
public static final int CMD_STOP_SERVICE = 0;// 定义一个常量作为停止服务的标记
private Button btnStart;// 启动服务按钮
private Button btnStop;// 关闭服务按钮
private TextView txtShow; // 用来接收Service传递过来的数据
private DataReciver dataReciver;// 用来接收来自于Service的数据
private OnClickListener myOnClickListener = new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.btnStart:
/** 创建Intent对象 */
Intent startService = new Intent(MainActivity.this,
RandomService.class);
MainActivity.this.startService(startService);// 发送Intent启动Service
break;
case R.id.btnStop:
/** 创建Intent对象 */
Intent stopService = new Intent();
stopService
.setAction("com.momo.componentcommunication.RandomService.STOPACTION");
stopService.putExtra("cmd", CMD_STOP_SERVICE);
sendBroadcast(stopService);// 发送广播
break;
default:
break;
}
}
};
/**
* @author Administrator
* @description 主要实现 Activity、Service、Broadcast Receiver 之间的通信 具体描述:在
* Activity中通过单击启动Service按钮来启动一个Service,而Service就会启动一个线程,
* 让该线程定时产生一个随机数,并将其封装到Intent对象中传递给Activity,Activity接收到Intent后
* 提取其中的信息将其显示到TextView控件上面;在服务运行的时候,可以单击Activity上的停止按钮来停止服 务。
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();// 初始化
}
/**
* 初始化界面组件
*/
private void init() {
/** 获取资源文件中的界面组件 */
btnStart = (Button) findViewById(R.id.btnStart);
btnStop = (Button) findViewById(R.id.btnStop);
txtShow = (TextView) findViewById(R.id.txtShow);
btnStart.setOnClickListener(myOnClickListener);
btnStop.setOnClickListener(myOnClickListener);
}
/**
* 单击按钮的监听器
*/
@Override
protected void onStart() {
// TODO Auto-generated method stub
dataReciver = new DataReciver();
IntentFilter filter = new IntentFilter();// 创建IntentFilter对象
filter.addAction("main_activity");
registerReceiver(dataReciver, filter);// 注册Broadcast Receiver
super.onStart();
}
@Override
protected void onStop() {
// TODO Auto-generated method stub
unregisterReceiver(dataReciver);// 取消注册Broadcast Receiver
super.onStop();
}
/**
*
* @author Administrator
* 内部类描述:服务启动后也会向Activity发Intent,所以Activity也必须注册一个Broadcast
* Receiver组件 用来接受Intent,注册之前需要编写实现了Broadcast Receiver 的子类,如下
*
*/
private class DataReciver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
double data = intent.getDoubleExtra("data", 0);
txtShow.setText("来自于Service的数据:" + data);// 将接收到的数据显示在屏幕上
}
}
}
第二:编写RandomService:
package com.momo.componentcommunication;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;
import android.util.Log;
public class RandomService extends Service {
public static final String TAG = "MYSERVICE";
private boolean flag;// 线程是否执行的标志
CommandReceiver cmdReceiver;
/**
* 重写onCreate方法
*/
@Override
public void onCreate() {
// TODO Auto-generated method stub
Log.i(TAG, "MyService:onCreate()");
flag = true;// 设置线程执行状态为:执行状态
cmdReceiver = new CommandReceiver();
super.onCreate();
}
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
Log.i(TAG, "MyService:onBind()");
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
Log.i(TAG, "MyService:onStartCommand");
IntentFilter filter = new IntentFilter();// 创建IntentFilter对象
registerReceiver(cmdReceiver, filter);// 注册Broadcast Receiver
doJob();// 调用方法启动线程
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
Log.i(TAG, "MyService:onDestroy");
unregisterReceiver(cmdReceiver);// 取消注册Broadcast Receiver
super.onDestroy();
}
public void doJob() {
new Thread() {// 创建一个新线程
public void run() {// 重写线程的run方法
while (true) {
try {
Thread.sleep(1000);// 线程睡眠一秒钟
} catch (Exception e) {
// TODO: handle exception
}
Intent intent = new Intent();// 创建Intent对象
intent.setAction("com.momo.componentcommunication.MainActivity");
intent.putExtra("data", Math.random());// 以data为键,随机数为值
sendBroadcast(intent);// 发送广播
}
}
}.start();
}
/**
*
* @author Administrator 继承于BroadcastReceiver的子类
*
*/
private class CommandReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Log.i(TAG, "CommandReceiver:onReceive");
/** 从 intent 对象中取出以“cmd”为键的值 */
int cmd = intent.getIntExtra("cmd", -1);// 获取Extra信息
/** 如果发来的消息是停止服务 */
if (cmd == MainActivity.CMD_STOP_SERVICE) {
flag = false;// 停止线程
stopSelf();// 停止服务
}
}
}
}
布局文件:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="${relativePackage}.${activityClass}" >
<Button
android:id="@+id/btnStart"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="开启服务" />
<Button
android:id="@+id/btnStop"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@+id/btnStart"
android:text="停止服务" />
<TextView
android:id="@+id/txtShow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@+id/btnStop"
android:layout_marginTop="42dp"
android:padding="20dip"
android:text="等待接收来自Service的数据" />
</RelativeLayout>
配置文件:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.momo.componentcommunication"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="16" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
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=".RandomService" android:process=":remote" >
<intent-filter>
<action android:name="com.momo.componentcommunication.RandomService.STOPACTION"/>
</intent-filter>
</service>
</application>
</manifest>