由於每個應用程序都運行在自己的進程空間,並且可以從應用程序UI運行另一個服務進程,而且經常會在不同的進程間傳遞對象。在Android平台,一個進程通常不能訪問另一個進程的內存空間,所以要想對話,需要將對象分解成操作系統可以理解的基本單元,並且有序的通過進程邊界。 通過代碼來實現這個數據傳輸過程是冗長乏味的,Android提供了AIDL工具來處理這項工作。
這里通過與鬧鍾實例來實現這一機制的簡單實現:
鬧鍾設置的實現是通過AlarmManager來實現的,AlarmManager提供系統警報服務,AlarmManager就會通過onReceive方法來執行這個事件,而將事件傳給onReceive就是通過注冊 ,然后利用android:process=":remote這一機制來實現的。
1 <receiver android:name=".AlarmReceiver" android:process=":remote"/>
而android:process=":remote意思就是說你配的這個組件會在另外一個進程中運行,這里面另一個就是pendingIntent,pendingIntent是一種特殊的Intent。主要的區別在於Intent的執行立刻的,而pendingIntent的執行不是立刻的。pendingIntent執行的操作實質上是參數傳進來的Intent的操作,但是使用pendingIntent的目的在於它所包含的Intent的操作的執行是需要滿足某些條件的。
下面是鬧鍾簡單源碼:
1 public class MainActivity extends Activity 2 { 3 Button mButton1; 4 Button mButton2; 5 6 TextView mTextView; 7 8 Calendar calendar; 9 10 @Override 11 public void onCreate(Bundle savedInstanceState) 12 { 13 super.onCreate(savedInstanceState); 14 15 setContentView(R.layout.activity_main); 16 /* 實例模式 */ 17 calendar=Calendar.getInstance(); 18 19 mTextView=(TextView)findViewById(R.id.text); 20 mButton1=(Button)findViewById(R.id.set); 21 mButton2=(Button)findViewById(R.id.cancle); 22 23 mButton1.setOnClickListener(new View.OnClickListener() 24 { 25 public void onClick(View v) 26 { 27 //獲取當前時間 28 calendar.setTimeInMillis(System.currentTimeMillis()); 29 int mHour=calendar.get(Calendar.HOUR_OF_DAY); 30 int mMinute=calendar.get(Calendar.MINUTE); 31 new TimePickerDialog(MainActivity.this, 32 new TimePickerDialog.OnTimeSetListener() 33 { 34 public void onTimeSet(TimePicker view,int hourOfDay,int minute) 35 { 36 calendar.setTimeInMillis(System.currentTimeMillis()); 37 calendar.set(Calendar.HOUR_OF_DAY,hourOfDay); 38 calendar.set(Calendar.MINUTE,minute); 39 calendar.set(Calendar.SECOND,0); 40 calendar.set(Calendar.MILLISECOND,0); 41 /* 建立Intent和PendingIntent,來調用目標組件 */ 42 Intent intent = new Intent(MainActivity.this, AlarnReceiver.class); 43 /*從系統取得一個用於向BroadcastReceiver的Intent廣播的PendingIntent對象*/ 44 PendingIntent pendingIntent=PendingIntent.getBroadcast(MainActivity.this,0, intent, 0); 45 AlarmManager am; 46 /* 獲取鬧鍾管理的實例 */ 47 am = (AlarmManager)getSystemService(ALARM_SERVICE); 48 /* 設置鬧鍾 */ 49 am.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent); 50 /* 設置周期鬧 */ 51 am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + (10*1000), (24*60*60*1000), pendingIntent); 52 String tmpS="設置鬧鍾時間為"+format(hourOfDay)+":"+format(minute); 53 mTextView.setText(tmpS); 54 } 55 },mHour,mMinute,true).show(); 56 } 57 }); 58 59 mButton2.setOnClickListener(new View.OnClickListener() 60 { 61 public void onClick(View v) 62 { 63 Intent intent = new Intent(MainActivity.this, AlarnReceiver.class); 64 PendingIntent pendingIntent=PendingIntent.getBroadcast(MainActivity.this,0, intent, 0); 65 AlarmManager am; 66 /* 獲取鬧鍾管理的實例 */ 67 am =(AlarmManager)getSystemService(ALARM_SERVICE); 68 /* 取消 */ 69 am.cancel(pendingIntent); 70 mTextView.setText("鬧鍾已取消!"); 71 } 72 }); 73 } 74 /* 格式化字符串(7:3->07:03) */ 75 private String format(int x) 76 { 77 String s = "" + x; 78 if (s.length() == 1) 79 s = "0" + s; 80 return s; 81 } 82 }
這里簡單實現功能就是到達我們設置的特定時間,就會通知onReceive方法來提示鬧鍾提示!而這前提就是開辟的另一個線程!
下面是另一個類的實現:
1 public class AlarnReceiver extends BroadcastReceiver 2 { 3 4 @Override 5 public void onReceive(Context arg0, Intent arg1) 6 { 7 Toast.makeText(arg0, "你設置的鬧鍾時間到了", Toast.LENGTH_LONG).show(); 8 } 9 10 }
-----------
android:process=":remote",代表在應用程序里,當需要該service時,會自動創建新的進程。而如果是android:process="remote",沒有“:”分號的,則創建全局進程,不同的應用程序共享該進程。