1.當在同一個進程中從一個Activity開啓另一個Activity時,它們的生命週期方法是這樣的:
A Activity 開啓了 B Activity:
A調用onPause(),B調用onCreate(),onStart(),onResume(),此時B Activity與用戶進行交互,
然後A Activity的onStop()方法調用,所以如果兩個界面共享一些數據,如存儲在數據庫
中的數據,則應該在A Activity的onPause()方法中保存數據,而不是onStop()方法。
2.橫豎屏切換
當用戶旋轉屏幕,切換屏幕狀態時,會創建新的Activity實例。
二、Service的onStartCommand()方法返回值
1.一個服務的onStartCommand()方法必須返回一個整數值,這個整數值描述了在系統因爲內存等問題殺死
該服務後,該服務在系統獲得了可用內存等資源如何繼續該服務,返回值必須爲以下其中之一:
a.START_NOT_STICKY:不要重新創建該服務,除非有意圖重新開啓該服務;
b.START_STICKY:用一個空的意圖重新創建該服務,如果有新的意圖,則用新的意圖開啓,適用於媒體播放器等邏輯;
c.START_REDELIVER_INTENT:用上一次開啓該服務的意圖重啓該服務,也就是繼續進行上次未完成的任務,
適用於文件下載,上傳等邏輯。
2.運行一個前臺服務:
前臺服務是用戶主動意識到的一種服務,因此在內存不足時,系統也不會考慮將其終止。 前臺服務必須爲狀態欄
提供通知,放在“正在進行”標題下方,這意味着除非服務停止或從前臺移除,否則不能清除通知。
要讓服務運行與前臺,需調用startForeground()方法,接收兩個參數,一個是通知的唯一標誌性ID,一個是
notification對象,如:
Notification notification = new Notification(R.drawable.icon, getText(R.string.ticker_text),
System.currentTimeMillis());
Intent notificationIntent = new Intent(this, ExampleActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.setLatestEventInfo(this, getText(R.string.notification_title),
getText(R.string.notification_message), pendingIntent);
startForeground(ONGOING_NOTIFICATION_ID, notification);
注:ID值不能爲0;要從前臺移除服務,請調用 stopForeground()。此方法接收一個布爾值,指示是否也移除狀態欄通知。 此方法不會停止
服務。 但是,如果在服務正在前臺運行時將其停止,則通知也會被移除。
3.定義可綁定的服務:
a.定義和客戶(client)交互的接口有三種方式,分別是:
(1)繼承Binder類,適用於此服務爲應用進程所私有,且client跟該服務處於同一應用進程中;
實現步驟:服務中定義一個類繼承Binder類,在服務的onBind()方法中返回一個自定義Binder實例對象,client在
onServiceConnected()方法中獲取該對象;
(2)使用Messager類提供跨進程綁定服務:
實現步驟:
服務實現一個 Handler,由其接收來自client的每個調用的回調,
Handler 用於創建 Messenger 對象(對 Handler 的引用),
Messenger 創建一個 IBinder,服務通過 onBind() 使其返回client,
client使用 IBinder 將 Messenger(引用服務的 Handler)實例化,然後使用後者將 Message 對象發送給服務,
服務在其 Handler 中(具體地講,是在 handleMessage() 方法中)接收每個 Message。
這樣,client並沒有調用服務的“方法”。而client傳遞的“消息”(Message 對象)是服務在其 Handler 中接收的。
如:
service:
public class MessengerService extends Service {
/** Command to the service to display a message */
static final int MSG_SAY_HELLO = 1;
/**
* Handler of incoming messages from clients.
*/
class IncomingHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_SAY_HELLO:
Toast.makeText(getApplicationContext(), "hello!", Toast.LENGTH_SHORT).show();
break;
default:
super.handleMessage(msg);
}
}
}
/**
* Target we publish for clients to send messages to IncomingHandler.
*/
final Messenger mMessenger = new Messenger(new IncomingHandler());
/**
* When binding to the service, we return an interface to our messenger
* for sending messages to the service.
*/
@Override
public IBinder onBind(Intent intent) {
Toast.makeText(getApplicationContext(), "binding", Toast.LENGTH_SHORT).show();
return mMessenger.getBinder();
}
}
Activity:
public class ActivityMessenger extends Activity {
/** Messenger for communicating with the service. */
Messenger mService = null;
/** Flag indicating whether we have called bind on the service. */
boolean mBound;
/**
* Class for interacting with the main interface of the service.
*/
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
// This is called when the connection with the service has been
// established, giving us the object we can use to
// interact with the service. We are communicating with the
// service using a Messenger, so here we get a client-side
// representation of that from the raw IBinder object.
mService = new Messenger(service);
mBound = true;
}
public void onServiceDisconnected(ComponentName className) {
// This is called when the connection with the service has been
// unexpectedly disconnected -- that is, its process crashed.
mService = null;
mBound = false;
}
};
public void sayHello(View v) {
if (!mBound) return;
// Create and send a message to the service, using a supported 'what' value
Message msg = Message.obtain(null, MessengerService.MSG_SAY_HELLO, 0, 0);
try {
mService.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
@Override
protected void onStart() {
super.onStart();
// Bind to the service
bindService(new Intent(this, MessengerService.class), mConnection,
Context.BIND_AUTO_CREATE);
}
@Override
protected void onStop() {
super.onStop();
// Unbind from the service
if (mBound) {
unbindService(mConnection);
mBound = false;
}
}
}
(3)AIDL,有待後續拓展4.客戶端(client)綁定服務:
client調用bindService()方法,然後服務會調用onBind()方法返回IBinder對象,但是因爲
這個綁定過程是異步的,bindService()調用後立即結束並不會返回IBinder()對象,因此需要一個ServiceConnection實例,
這個藉口提供onServiceConnected()和onServiceDisconnected()回調方法,當服務已經綁定時會調用onServiceConnected()方法,
並獲得IBinder實例對象;當服務崩潰或者被系統殺死時onServiceDisconnected()方法調用,而不是用戶調用unbindService()時調用。
如:
LocalService mService;
private ServiceConnection mConnection = new ServiceConnection() {
// Called when the connection with the service is established
public void onServiceConnected(ComponentName className, IBinder service) {
// Because we have bound to an explicit
// service that is running in our own process, we can
// cast its IBinder to a concrete class and directly access it.
LocalBinder binder = (LocalBinder) service;
mService = binder.getService();
mBound = true;
}
// Called when the connection with the service disconnects unexpectedly
public void onServiceDisconnected(ComponentName className) {
Log.e(TAG, "onServiceDisconnected");
mBound = false;
}
};
綁定服務:
Intent intent = new Intent(this, LocalService.class);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
5.bind service 生命週期:
6.Service完整生命週期: