編輯:關於Android編程
Service沒有UI,因為service是後台運行
如:下載,網絡I/O 等等
Service的生命周期
從它被創建開始,到它被銷毀為止,
onCreate();
onStartCommand();
onBind();
onUnbind();
onRebind();
onDestroy();
一般分為三種方式
第一種:
當采用Context.startService()方法啟動服務,與之有關
的生命周期方法
onCreate() -> onStartCommand() -> onDestroy()
onCreate()該方法在服務被創建時調用,該方法只會被調
用一次,無論調用多少次startService()或bindService()方
法,服務也只被創建一次
onStart() 只有采用Context.startService()方法啟動服
務時才會調用該方法,該方法在服務開始運行時被調用,多次
調用startService()方法盡管不會多次創建服務,但onStart
()方法會被多次調用
onDestroy()該方法在服務被終止時調用
第二種:
當采用Context.bindService()方法啟動服務,與之有關
的生命周期方法
onCreate() -> onBind() -> onUnbind() -> onDestroy
()
onBind() 只有采用Context.bindService()方法啟動服務
時才會回調該方法,該方法在調用者與服務綁定時被盜用,當
調用者與服務已經綁定,多次調用,Context.bindService()方
法並不會導致該方法被多次調用。
onUnbind()只有采用Context.bindService()方法啟動服
務時才會回調該方法,該方法在調用者與服務解除綁定時被調
用。
第三種:混合啟動綁定服務
如果先采用startService()方法啟動服務,然後調用
bindService方法綁定到服務,在調用unbindService()方法
解除綁定,最後調用bindService()方法再次綁定到服務,觸
發的生命周I方法如下:
onCreate() ->
onStartCommand() ->
onBind() -> onUnbind()[重載後的方法需返回true]
->
onRebind()
采用Service實現電話竊聽器
1.新建一個類繼承Service
/*
* 采用Service實現電話竊聽器
*/
public class PersonService extends Service {
// 該方法只會被調用一次
@Override
public void onCreate() {
super.onCreate();
// 取得電話管理服務
TelephonyManager telephonyManager =
(TelephonyManager) getSystemService
(Context.TELEPHONY_SERVICE);
telephonyManager.listen(new
PhoneListener(),
PhoneStateListener.LISTEN_CALL_STATE);
}
// 電話監聽器
private final class PhoneListener extends
PhoneStateListener {
private String incomingNumberString;
private MediaRecorder mediaRecorder;
private File file;
@Override
public void onCallStateChanged(int
state, String incomingNumber) {
switch (state) {
// 來電
case
TelephonyManager.CALL_STATE_RINGING:
this.incomingNumberString = incomingNumber;
break;
// 接通電話
case
TelephonyManager.CALL_STATE_OFFHOOK:
try {
file = new
File(Environment.getExternalStorageDirectory(),
incomingNumber + System.currentTimeMillis());
mediaRecorder
= new MediaRecorder();
mediaRecorder.setAudioSource
(MediaRecorder.AudioSource.MIC);
mediaRecorder
.setOutputFormat
(MediaRecorder.OutputFormat.THREE_GPP);
mediaRecorder
.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mediaRecorder.setOutputFile(file.getAbsolutePath());
mediaRecorder.prepare();// 准備
mediaRecorder.start();// 開始錄音
} catch (IOException
e) {
}
break;
// 掛斷電話回歸到空閒狀態
case
TelephonyManager.CALL_STATE_IDLE:
if (mediaRecorder !=
null) {
mediaRecorder.stop();
mediaRecorder.release();
mediaRecorder
= null;
}
break;
}
}
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
2.配置清單文件
3.服務是不能自己運行的是需要調用啟動服務
比如說,開機啟動,那麼需要使用廣播接收者,
然後從廣播啟動服務
開機啟動的廣播接收者配置
android:name="com.example.service_demo.broadcast.MyBro
adcast">
android:name="android.intent.action.BOOT_COMPLETED"
/>
代碼:
public class MyBroadcast extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent
intent) {
context.startService(new Intent
(context,MyService.class));
}
}
4.配置必要的權限
android:name="android.permission.READ_PHONE_STATE" />
android:name="android.permission.WRITE_EXTERNAL_STORAG
E" />
android:name="android.permission.MOUNT_UNMOUNT_FILESYS
TEMS" />
android:name="android.permission.INTERNET" />
android:name="android.permission.RECORD_AUDIO" />
5.現在就可以啟動了
然後打電話就會被錄音
現在服務是在系統中啟動了,但是怎麼停止了?
如果不顯示關閉服務,而是由系統自己來關閉,就是當內存
不夠時,先終結掉後台繼承,如果後台進程還不夠,那麼就
需要結束掉服務進程
手動調用關閉服務是
Context.stopService();
建立能與訪問者進行相互通信的本地服務
通過startService()和stopService()啟動關閉服務,適用於
服務和訪問者之間沒有交互的情況
如果服務和訪問者之間需要方法調用或者傳遞參數,則需要使
用bindService()和unbindServie()方法啟動關閉服務
采用Context.bindService()方法啟動服務,在服務未被創建
時,系統會先調用服務的onCreate()方法,接著調用onBind()
方法,這個時候訪問者和服務綁定在一起,如果訪問者要與服
務進行通信,那麼,onBind()方法必須返回IBinder對象,
如果訪問者退出了,系統就會先調用服務器的onUnbind(),接
著調用onDestroy()方法,如果調用bindService()方法前服務
已經被綁定多次調用bindService()方法並不會導致多次創
建服務及綁定(也就是說onCreate()和onBind()方法並不會被
多次調用),
如果訪問者希望與正在綁定的服務解除綁定,可以調用
unbindService()方法,調用該方法也會導致調用系統的
unbind() -> onDestroy()
訪問者調用服務中的方法
1.當我們啟動調用bindService()時,系統會調用Service類的
onBind()方法 ,返回IBinder對象,所以我們創建一個內部類
繼承自Binder,並且聲明一個全局IBinder對象,返回Binder對
象的實例
2.創建一個繼承service的類
/*
* 綁定服務的過程是:客戶啟動服務,服務返回一個IBinder
對象
* 由於IBinder是一個接口,所以我們需要自定一個類繼承
Binder對象,然後把這個類的實例對象給接口對象
* 在將這個接口對象給返回
*/
public class MyService extends Service {
private String[] nameStrings = {"小明","小
王","夏利","校長"};
private IBinder binder = new StudentBinder();
public String query(int id){
if(id > 0 && id < 4){
return nameStrings[id-1];
}
return null;
}
@Override
public IBinder onBind(Intent intent) {
return binder;
}
private class StudentBinder extends Binder
implements IStudent{
public String queryStudent(int id){
return query(id);
}
}
}
3.創建一個接口
public interface IStudent {
String queryStudent(int id);
}
4.在Activity中調用
public class MainActivity extends Activity {
private ServiceConnection conn= new
StudentServiceConnection();
private IStudent iStudent;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final TextView tv = (TextView)
this.findViewById(R.id.textview);
final EditText txt = (EditText)
this.findViewById(R.id.editText);
this.findViewById
(R.id.button).setOnClickListener(new
View.OnClickListener() {
@Override
public void onClick(View v) {
String text =
iStudent.queryStudent(Integer.valueOf(txt.getText
().toString()));
tv.setText(text);
}
});
Intent service = new Intent
(this,MyService.class);
bindService(service, conn, BIND_AUTO_CREATE);
}
private class StudentServiceConnection implements
ServiceConnection{
@Override
public void onServiceConnected
(ComponentName name, IBinder service) {
iStudent = (IStudent)service;
}
@Override
public void onServiceDisconnected
(ComponentName name) {
iStudent = null;
}
}
@Override
protected void onDestroy() {
//當activity被摧毀時注銷綁定
unbindService(conn);
super.onDestroy();
}
}
這種服務就類似QQ中的發送一條消息,需要經過這樣的服務過
程
當然,發送UDP信息,沒有寫,這裡只是講綁定服務需要執行
的過程
使用AIDL和遠程服務實現進程通信
AIDL就是進程間通信
Android Interface Definition Language
AIDL是一種接口定義語言,用於約束兩個進程間的通訊規則,
供編譯器生成代碼
1.新建一個項目 作為服務端
新建一個接口,並且把這個.java文件格式改成.aidl
並且不能有訪問修飾符
刷新項目,在gen下會生成一個文件,不過這裡的文件不需
要我們來改,系統自動生成的
2.現在創建一個服務
代碼
public class queryStudentService extends Service {
private IBinder binder = new
StudentQueryBinder();
private String[] str = {"小王","呵呵","哈哈"};
public String query(int id){
return str[id];
}
@Override
public IBinder onBind(Intent intent) {
return binder;
}
private final class StudentQueryBinder extends
StudentQuery.Stub{
@Override
public String queryStudent(int number)
throws RemoteException {
return query(number);
}
}
}
配置文件
android:name="com.example.android_remote_aidl.service.
queryStudentServic">
android:name="com.enenya.service.queryStudentService"/
>
3.寫一個客戶端
把服務端的那個aidl包復制到客戶端項目中來
public class MainActivity extends Activity {
private ServiceConnection conn = new
StudentServiceConnection();
private StudentQuery studentQuery;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final TextView tv = (TextView)
this.findViewById(R.id.textview);
final EditText editText = (EditText)
this.findViewById(R.id.edittext);
this.findViewById
(R.id.button).setOnClickListener(new
View.OnClickListener(){
@Override
public void onClick(View v) {
try {
String aString
= studentQuery.queryStudent(Integer.valueOf
(editText.getText().toString()));
tv.setText
(aString);
} catch
(NumberFormatException e) {
// TODO Auto-
generated catch block
e.printStackTrace();
} catch
(RemoteException e) {
// TODO Auto-
generated catch block
e.printStackTrace();
}
}
});
Intent service = new Intent
("com.enenya.service.queryStudentService");
bindService(service, conn, BIND_AUTO_CREATE);
}
private class StudentServiceConnection implements
ServiceConnection{
@Override
public void onServiceConnected
(ComponentName name, IBinder service) {
studentQuery =
StudentQuery.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected
(ComponentName name) {
studentQuery = null;
}
}
@Override
protected void onDestroy() {
unbindService(conn);
super.onDestroy();
}
}
前言在Android開發中,顏色資源分兩種:一種是自定義顏色,一種是使用系統給我們自帶的顏色自定義顏色Android中顏色值的定義是由透明度alpha和RGB(紅綠藍)三
通過一個例子來熟悉下 Android 消息機制的使用,這個例子中主線程中有一個EditText、ImageView 和一個 Button,在 EditText 中輸入圖片
工廠方法模式,往往是設計模式初學者入門的模式,的確,有人稱之為最為典型最具啟發效果的模式。android中用到了太多的工廠類,其中有用工廠方法模式的,當然也有很多工廠並不
Android應用開發中我們常常需要發送手機短信。這對於android平台來說,是最簡單不過的功能了,無需太多代碼,也無需自定義代碼,只需要調用android提供的消息管