第七天

来源:互联网 发布:万网域名登录网址 编辑:程序博客网 时间:2024/04/30 08:52
1、Service特点
    [1]   Service在Android中是一种长生命周期的组件,它不实现任何额用户界面,是一个没有界面的Acrivity
    [2]   Service长期在后台运行,执行不关乎界面的一些操作,例如:网易新闻服务每隔一分钟去服务器查看是否有最新的新闻
    [3]   Service和Thread有点相似,但是使用Thread不安全,不严谨
    [4]   Service和其他组件一样,都是运行在主线程中,因此不能用它来做耗时的操作,如果想要做耗时的操作,那么要在服务的内部创建子线程
2、什么时候使用Service,什么时候使用Thread呢?
    [1]   如果在整个过程中这个线程都无需和用户进行交互,那么选择Service
    [2]   如果线程在执行的过程中需要和用户进行交互,那么选择Thread 
3、android中的进程
    [1]   进程优先级由低到高
            Foreground process  前台进程 优先级最高  相当于Activity执行了onResume()方法  用户正在交互  
 
            Visible  process  可视进程  用户可见但是无法操纵  相当于Activity执行了onPause()方法
            
            Service process  服务进程  通过startService()开启了一个服务
             
             Background process  后台进程  相当于Activity执行了onStop()方法  界面不可见  但是Activity并没有被销毁

            Empty process    空进程   不会维持任何组件的运行
4、Start方式开启服务(StartService)
    [1] 创建一个类继承Service重写其生命周期方法onCreate()、onStartCommand()、onStop()、onDestroy()方法
    [2]  特点:
        [1]  第一次点击开启服务会执行onCreate()和onStartCommand()
        [2]  第二次点击开启服务只会执行onStartCommand()
        [3]  服务一旦开启,就会在后台长期运行,只能通过用户手动停止才可以 
5、Service 和 Thread之间的关系
     [1]  Thread只能在开启其的Activity中进行操作,一旦这个脱离这个Activity就无法获取这个线程的引用,而任何一个Activity都可以绑定同一个Service,如果在Service开启子线程,那么就可以获取线程的数据,所以Service并不是线程
     [2]  Service如果不在清单文件中指定android:process=".remote"那么是一个local Service那么就和Activity在同一个进程中,如果指定了这个选项,那么就在不同的进程中运行
6、电话监听器案例
    [1]  创建一个类继承Service
    [2]  重写onCreate()和onDestroy()方法
  1. public class PhoneListenerService extends Service {
  2. @Nullable
  3. @Override
  4. public IBinder onBind(Intent intent) {
  5. return null;
  6. }
  7. @Override
  8. public void onCreate() {
  9. super.onCreate();
  10. //[1] 拿到TelephonyManager的实例
  11. TelephonyManager telephonyManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
  12. //[2]
  13. telephonyManager.listen(new MyPhonyListener(),PhoneStateListener.LISTEN_CALL_STATE);
  14. }
  15. private class MyPhonyListener extends PhoneStateListener{
  16. MediaRecorder recorder;
  17. @Override
  18. public void onCallStateChanged(int state, String incomingNumber) {
  19. super.onCallStateChanged(state, incomingNumber);
  20. switch (state){
  21. case TelephonyManager.CALL_STATE_IDLE : //当电话空闲的时候
  22. if(recorder != null){
  23. recorder.stop();
  24. recorder.reset();
  25. recorder.release();
  26. }
  27. break;
  28. case TelephonyManager.CALL_STATE_OFFHOOK : //当电话接听的时候
  29. Log.d("offhook","开始录音");
  30. recorder.start();
  31. break;
  32. case TelephonyManager.CALL_STATE_RINGING: //当电话响铃的时候
  33. //[1] 获取录音记录
  34. recorder = new MediaRecorder();
  35. //[2] 设置录音来源
  36. recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
  37. //[3] 设置录音格式
  38. recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
  39. //[4] 设置了录音编码
  40. recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
  41. //[5] 设置录音输出目录
  42. recorder.setOutputFile(Environment.getExternalStorageDirectory().getPath()+"/audio.mp4");
  43. try {
  44. recorder.prepare();
  45. } catch (IOException e) {
  46. e.printStackTrace();
  47. }
  48. break;
  49. }
  50. }
  51. }
  52. public void onDestroy(){
  53. }
  54. }

    [3]  创建一个类继承Broadcast
    [4]  重写onReceive()方法
    [5]  在onReceive()里面开启Service
  1. public class ServiceStartReceiver extends BroadcastReceiver {
  2. @Override
  3. public void onReceive(Context context, Intent intent) {
  4. Intent intent1 = new Intent(context, PhoneListenerService.class);
  5. context.startService(intent1);
  6. }
  7. }
7、通过bindService调用
    [1]  创建一个类继承Service
  1. public class BindService extends Service

    [2]  重写onCreate()、onBind()两个方法
  1. public IBinder onBind(Intent intent) {
  2. return null;
  3. }
  4. @Override
  5. public void onCreate() {
  6. super.onCreate();
  7. }

    [3]  在ctivity中使用bindService()绑定服务
  1. myServiceConnection = new MyServiceConnection();
  2. bindService(intent,myServiceConnection,BIND_AUTO_CREATE);
  3. private class MyServiceConnection implements ServiceConnection{
  4. //当连接成功的时候调用
  5. @Override
  6. public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
  7. Log.d("bindService","绑定服务");
  8. }
  9. //当服务解绑的时候调用
  10. @Override
  11. public void onServiceDisconnected(ComponentName componentName) {
  12. Log.d("unbindService","解绑服务");
  13. }
  14. }

    [4]  使用unbindService解绑
  1. unbindService(myServiceConnection);
    [5]  使用bindService的特点
        [1]  第一次创建的时候调用onCreate()和onBind()方法
        [2]  当onBind方法返回null的时候onServiceConnected()方法不执行
        [3]  服务不可多次绑定
        [4]  不求同时生,但求同时死,指的是绑定者(Activity)和被绑定者(Service)之间的关系
        [5]  通过bind绑定的服务无法在设置页面找到相当于隐形的服务
8、如何在Activity里面调用Service里面的方法
    [1]  创建服务
    
  1. [3]  将这个类的对象返回
  2. public IBinder onBind(Intent intent) {
  3. return new MyBinder();
  4. }
  5. private void method(){
  6. Toast.makeText(getApplicationContext(),"调用了",Toast.LENGTH_SHORT).show();
  7. }
  8. [2]  写一个内部类继承Binder方法,然后在这个类里面调用Binder的方法
  9. public class MyBinder extends Binder{
  10. public void callMethod(){
  11. method();
  12. }
  13. }

    
    [4]  在Activity里面获取对象,然后调用
    
  1. protected void onCreate(Bundle savedInstanceState) {
  2. super.onCreate(savedInstanceState);
  3. setContentView(R.layout.activity_main);
  4. intent = new Intent(this,TestService.class);
  5. bindService(intent,new MyConn(),BIND_AUTO_CREATE); //初始化绑定,走onBinder
  6. }
  7. public void click(View view){
  8. service.callMethod(); //调用Binder里面的方法
  9. }
  10. private class MyConn implements ServiceConnection{
  11. @Override
  12. public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
  13. service = (TestService.MyBinder) iBinder; //获取Binder对象
  14. }
  15. @Override
  16. public void onServiceDisconnected(ComponentName componentName) {
  17. }
  18. }
9、在接口中调用服务方法
    [1]  接口的好处:接口可以暴露出程序员想要向用户暴露的方法。用户只需要实现需要实现的方法
    [2]  实现步骤
        [1]  定义一个接口
  1. public interface IService {
  2. public void callMethod();
  3. }
        [2]  实现这个接口,重写需要未实现方法
  1. private class MyBinder extends Binder implements IService{
  2. public void callMethod(){
  3. method();
  4. }
  5. }
        [3]  获取在这个实例,通过多态的方式实现
  1. service = (IService) iBinder;
10、需求:即想让服务长期运行,又想调用服务里面的方法
    步骤
        [1]  开启服务startService
        [2]  绑定服务  获取服务方法bindService
        [3]  解绑服务  unbindService
        [4]  停止服务 stopService
11、aidl
    本地服务:运行在自己应用中的服务
    远程服务:运行在其他应用中的服务
    实现进程间通信 IPC
    aidl:android interface definition language  接口描述语言。
    用途:专门用来解决进程间通信。 
     总结:使用aidl的步骤
     [1] 把IService.java文件变成一个aidl文件
     [2]  aidl语言不认识public
     [3]  自动生成一个Iservice.java文件 ,系统自动生成一个stub类
     [4]  我们自己定义的中间人直接继承Stub类
     [5]  保证2应用的aidl文件是同一个   保证aidl文件所在的报名相同
     [6]  获取中间人对象的方法不一样了   Stub.asInterface()拿到中间人对象
    Android Studio配置aidl文件的方法
    [1]  在Server端直接新建aidl文件
     [2] 将创建出来的文件所在的包名复制出来Copy Reference,将完整包名复制出来,在client端创建包
 
     [3]  然后build就可以了
0 0
原创粉丝点击