Activity、Service、BroadcastReceiver的通信
目的
本应用程序包括一个活动(testActivity)和一个服务(testService), 他们各自有自己的广播接收器(MyReceiver 和TestServiceReceiver).
当按下Start按钮, testActivity会通过意图(Intent)启动testService.
在testService的onStartCommand()创建并启动一个线程(thread),在线程里面重复发送广播(sendBroadcast()),把当前系统时间送给testActivity的MyReceiver.
当MyReceiver接收到,会把接收到的时间和新的系统时间比较,并把延迟时间显示出来.
当按下Stop按钮, testActivity会发送广播送给testService的TestServiceReceiver.
当TestServiceReceiver接收到,便会停止服务.
testActivity.java
package com.testActivity; 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.View; import android.widget.Button; import android.widget.TextView; public class testActivity extends Activity { final static String MY_ACTION = "testActivity.MY_ACTION" ; TextView textData; public static final int RQS_STOP_SERVICE = 1 ; MyReceiver myReceiver; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.main); textData = (TextView)findViewById(R.id.data); Button buttonStart = (Button)findViewById(R.id.start); Button buttonStop = (Button)findViewById(R.id.stop); buttonStart.setOnClickListener(buttonStartOnClickListener); buttonStop.setOnClickListener(buttonStopOnClickListener); } @Override protected void onStart() { // TODO Auto-generated method stub myReceiver = new MyReceiver(); IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(MY_ACTION); registerReceiver(myReceiver, intentFilter); //←Squek:注册receiver等待其他Broadcast传送 super .onStart(); } @Override protected void onStop() { // TODO Auto-generated method stub unregisterReceiver(myReceiver); //←Squek:取消注册 super .onStop(); } Button.OnClickListener buttonStartOnClickListener = new Button.OnClickListener(){ @Override public void onClick(View arg0) { // TODO Auto-generated method stub Intent intent = new Intent(testActivity. this , com.testActivity.testService. class ); testActivity. this .startService(intent); //←Squek:Service启动 }}; Button.OnClickListener buttonStopOnClickListener = new Button.OnClickListener(){ @Override public void onClick(View arg0) { // TODO Auto-generated method stub Intent intent = new Intent(); intent.setAction(testService.MY_ACTION); intent.putExtra( "RQS" , RQS_STOP_SERVICE); sendBroadcast(intent); //←Squek:Activity send Broadcast }}; //Broadcast Receiver宣告 private class MyReceiver extends BroadcastReceiver{ @Override public void onReceive(Context arg0, Intent arg1) { // TODO Auto-generated method stub long timestamp = arg1.getLongExtra( "timestamp" , 0 ); long curtime = System.currentTimeMillis(); long delay = curtime - timestamp; textData.setText(String.valueOf(timestamp) + " : " + String.valueOf(curtime) + " delay " + String.valueOf(delay) + "(ms)" ); } } } |
testService.java
package com.testActivity; 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.widget.Toast; public class testService extends Service { final static String MY_ACTION = "testService.MY_ACTION" ; TestServiceReceiver testServiceReceiver; boolean running; @Override public void onCreate() { // TODO Auto-generated method stub Toast.makeText(getBaseContext(), "TestServiceReceiver.onCreate" , Toast.LENGTH_LONG).show(); testServiceReceiver = new TestServiceReceiver(); super .onCreate(); } @Override public IBinder onBind(Intent arg0) { // TODO Auto-generated method stub return null ; } @Override public int onStartCommand(Intent intent, int flags, int startId) { // TODO Auto-generated method stub Toast.makeText(getBaseContext(), "TestServiceReceiver.onStartCommand" , Toast.LENGTH_LONG).show(); IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(MY_ACTION); registerReceiver(testServiceReceiver, intentFilter); running = true ; MyThread myThread = new MyThread(); myThread.start(); return super .onStartCommand(intent, flags, startId); } @Override public void onDestroy() { // TODO Auto-generated method stub this .unregisterReceiver(testServiceReceiver); super .onDestroy(); } public class MyThread extends Thread { @Override public void run() { // TODO Auto-generated method stub // TODO Auto-generated method stub while (running){ try { Thread.sleep( 1000 ); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } Intent intent = new Intent(); intent.setAction(testActivity.MY_ACTION); intent.putExtra( "timestamp" , System.currentTimeMillis()); sendBroadcast(intent); //←Squek:Service send Broadcast } } } public class TestServiceReceiver extends BroadcastReceiver { @Override public void onReceive(Context arg0, Intent arg1) { // TODO Auto-generated method stub int rqs = arg1.getIntExtra( "RQS" , 0 ); if (rqs == testActivity.RQS_STOP_SERVICE){ Toast.makeText(getBaseContext(), "TestServiceReceiver.onReceive w/ RQS_STOP_SERVICE" , Toast.LENGTH_LONG).show(); running = false ; stopSelf(); } } } } |
main.xml
<? xml version = "1.0" encoding = "utf-8" ?> android:orientation = "vertical" android:layout_width = "fill_parent" android:layout_height = "fill_parent" > < TextView android:layout_width = "fill_parent" android:layout_height = "wrap_content" android:text = "@string/hello" /> < Button android:id = "@+id/start" android:layout_width = "fill_parent" android:layout_height = "wrap_content" android:text = "- Start -" /> < Button android:id = "@+id/stop" android:layout_width = "fill_parent" android:layout_height = "wrap_content" android:text = "- Stop -" /> < TextView android:id = "@+id/data" android:layout_width = "fill_parent" android:layout_height = "wrap_content" /> </ LinearLayout > |
AndroidManifest.xml setting
<? xml version = "1.0" encoding = "utf-8" ?> package = "com.testActivity" android:versionCode = "1" android:versionName = "1.0" > < application android:icon = "@drawable/icon" android:label = "@string/app_name" > < activity android:name = ".testActivity" 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 = ".testService" /> </ application > < uses-sdk android:minSdkVersion = "7" /> </ manifest > |