• Android之旅七 Service简介


    1、          Service是什么:它是一个应用程序组件、没有图形化界面、通常用来处理一些耗时比较长的操作(例如下载、播放MP3等等)、可以使用Service更新ContentProvider,发送Intent以及启动系统的通知等等。

    2、          Service不是一个单独的进程,也不是一个线程

    3、         要让系统知道我们的Service,我们仍然需要在AndroidMainifest.xml中进行注册。

      <service android:name=".MyService"></service>

    4、         启动一个Service使用startService(Intent);停止一个ServicestopService(Intent);

    5、         我们还可以通过bindService()来启动一个Service,它与startService的区别是:通过startService()stopService()启动关闭服务,适用于服务和访问者之间没有交互的情况,就是说Activity发送一个请求给Service,而Service是无法将信息或者它的状态传递给Activity的。如果服务和访问者之间需要方法调用或者传递参数或者知道其运行的情况,则需要使用bindService()unbindService()方法启动关闭服务。

    6、          Parcel就是一个存放读取数据的容器, Android系统中的binder进程间通信(IPC)就使用了Parcel类来进行客户端与服务端数据的交互,而且AIDL的数据也是通过Parcel来交互的。它可以存放任何类型的数据,得到Parcel对象通过Parcel.obtain()方法,通过writeXXX以及readXXX方法来存储和读取数据,数据都以二进制的形式被一个一个存放起来,当存入了很多数据,需要将其一个个取出来的时候,需要调用其setDatePosition方法将指针移动到最前面setDatePosition(0);

    7、         通过在Service里面继承Binder的类中复写onTransact方法和在Activity里面通过Bindertransact方法可以实现ActivityService之间的同步通信,相当与数据的发送和相应的一个过程,这在java web里面可以类似于客户端和服务器端的requestresponse数据交互。

    8、 与Activity相似的是,Service中定义了系列生命周期方法,如下所示:

             IBinder onBind(Intent intent):改方法是Service子类必须实现的方法。该方法返回一个IBinder对象,应用程序可通过该对象与Service组件通信
             void onCreate():当该Service第一次被创建后将立即回调该方法。
             void onDestroy():当该Service被关闭之前将会回调该方法
             void onStartCommand(Intent intent,int flags,int startld):该方法早起版本是void onStart(Intent intent,int startId),
             每次客户端调用startService(Intent)方法启动该Service时都会回调该方法 
             boolean onUnbind(Intent intent):当该service上绑定的所有客户端都断开连接时将会回调该方法。

    9、

            通过Context的startService()方法:通过该方法启用Service,访问者与Service之间没有关联,即使访问者退出了,Service仍然运行。
            通过Context的bindService()方法:使用该方法启用Service,访问者与Service绑定在了一起,访问者一旦退出,Service也就终止了。

    代码一:通过startService和StopService启动、关闭Service

    定义我们的Service类:

    package com.service.test;
    
    import android.app.Service;
    import android.content.Intent;
    import android.os.Binder;
    import android.os.IBinder;
    import android.os.Parcel;
    import android.os.RemoteException;
    
    public class MyService extends Service{
    
    	@Override
    	public IBinder onBind(Intent intent) {
    		System.out.println("service onBind");
    		IBinder binder=new FirstBinder();
    		//返回一个IBinder对象,将会调用客户端里面ServiceConnection中的onServiceConnected方法,并且将IBinder对象返回给客户端
    		//如果放回为null,将不会调用
    		return binder;
    	}
    	
    	class FirstBinder extends Binder{
    		public String getData(){
    			return "test data";
    		}
    	}
    	
    	/**
    	 * 第一次调用Service(startService、bindService)的时候会调用onCreate方法
    	 */
    	@Override
    	public void onCreate() {
    		super.onCreate();
    		System.out.println("service onCreate");
    	}
    	
    	@Override
    	public int onStartCommand(Intent intent, int flags, int startId) {
    		System.out.println(intent.getStringExtra("name"));
    		System.out.println(intent.getIntExtra("age", 0));
    		System.out.println("flags--->"+flags);
    		System.out.println("startId--->"+startId);
    		System.out.println("service onStartCommand");
    		return Service.START_NOT_STICKY;
    	}
    	
    	@Override
    	public void onStart(Intent intent, int startId) {
    		super.onStart(intent, startId);
    		System.out.println("Service onStart");
    	}
    	
    	/**
    	 * 当调用stopService和unbindService的时候会执行该方法
    	 */
    	@Override
    	public void onDestroy() {
    		super.onDestroy();
    		System.out.println("service onDestroy");
    	}
    
    }
    

    在Activity中调用startService和stopService方法:

        //通过startService启动Service
        class startServiceListener implements OnClickListener{
    		@Override
    		public void onClick(View v) {
    			Intent intent=new Intent();
    			intent.putExtra("name", "mary");
    			intent.putExtra("age", 32);
    			intent.setClass(MainActivity.this, MyService.class);
    			startService(intent);
    		}
        }
        
        //通过stopService停止Service
        class stopServiceListener implements OnClickListener{
    		@Override
    		public void onClick(View v) {
    			Intent intent=new Intent();
    			intent.setClass(MainActivity.this, MyService.class);
    			stopService(intent);
    		}
        }

    当我们执行startService时,我们自定义的Service中的onCreate、onStart、onStartCommand方法将会被执行,当我们执行stopService时,我们自定义的Service中的onDestory方法将会被执行。

    在Activity中绑定Service,调用我们的bindService方法,其中,我们需要在Activity中创建一个连接对象ServiceConnection

        //连接对象
        private ServiceConnection conn=new ServiceConnection(){
        	//连接时调用
    		@Override
    		public void onServiceConnected(ComponentName name, IBinder FirstBinder) {
    			System.out.println("service bind successed!");
    			FirstBinder binder=(FirstBinder)FirstBinder;
    			System.out.println(binder.getData());
    			Toast.makeText(MainActivity.this, "绑定成功!", Toast.LENGTH_LONG).show();
    		}
            
    		//断开连接时调用
    		@Override
    		public void onServiceDisconnected(ComponentName name) {
    			System.out.println("service unbind");
    		}
        };


    绑定Service:

        //通过bindService来绑定Service
        class bindServiceListener implements OnClickListener{
    		@Override
    		public void onClick(View v) {
    			Intent intent=new Intent();
    			intent.setClass(MainActivity.this, MyService.class);
    			bindService(intent, conn, Service.BIND_AUTO_CREATE);
    		}
        }


    解除绑定Service:

        class unbindServiceListener implements OnClickListener{
    		@Override
    		public void onClick(View v) {
    			Intent intent=new Intent();
    			intent.setClass(MainActivity.this, MyService.class);
    			unbindService(conn);
    		}
        	
        }

    当我们执行bindService方法的时候,我们自定义的Service中的onCreate、onBinder方法将会被执行,当我们执行unbindService方法的时候,我们自定义的Service中的onDestory方法将会被执行。

    所以Service的生命周期大致为:

        如果应用程序通过startService()方法来启动Service,Service的生命周期:

            调用startService() ——>onCreate——>onStartCommand()——>Service运行中——Service被自己或调用者停止——>onDestroy——>Service被关闭
        如果应用  程序通过bindService()方法来启动Service,Service的生命周期:
            调用bindService()——>onCreate——>onBind()——>客户端绑定到Service——调用unBindService取消绑定——>onUnbind()——>onDestroy——>Service被关闭

    通过bindService实现Activity和Service的数据交互 ,通过Binder里面的onTransact和transact方法

    定义我们的Service:注意要在AndroidMainifest.xml文件中进行配置:

    package com.harderxin.service;
    
    import android.app.Service;
    import android.content.Intent;
    import android.os.Binder;
    import android.os.IBinder;
    import android.os.Parcel;
    import android.os.RemoteException;
    
    public class FirstService extends Service {
    
    	@Override
    	public IBinder onBind(Intent intent) {
    		return new FirstBinder();
    	}
    	
    	class FirstBinder extends Binder{
    		
    		@Override
    		protected boolean onTransact(int code, Parcel data, Parcel reply,
    				int flags) throws RemoteException {
    			System.out.println("code---->"+code);
    			String str=data.readString();//接收Activity发送过来的请求
    			System.out.println(str);//处理请求
    			reply.writeString("from Service:reply");//Service将数据回送发给Activity
    			return super.onTransact(code, data, reply, flags);
    		}
    	}
    
    }
    


    在Activity中绑定service和发送请求给Service:

    package com.harderxin.service;
    
    import android.app.Activity;
    import android.app.Service;
    import android.content.ComponentName;
    import android.content.Intent;
    import android.content.ServiceConnection;
    import android.os.Binder;
    import android.os.Bundle;
    import android.os.IBinder;
    import android.os.Parcel;
    import android.os.RemoteException;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    
    /**
     * 实现了Activity和Service进行数据交互的一个过程,通过Binder里面的onTransact和transact方法进行实现
     * binder.transact(int code, Parcel data, Parcel reply,int flags);用户将data.writeXXX里面的数据发送给Service
     * Service通过onTransact(int code, Parcel data, Parcel reply,int flags);接收里面的data.readXXX数据,进行一系列的逻辑处理后
     * 通过reply.writeXXX将消息反馈给Activity,Activity通过reply.readXXX接收Service反馈过来的数据,这样就实现了客户端和服务端的通信
     * 的一个过程,并且这个过程是同步的,就是说binder.transact(0, data, reply, 0)和onTransact是同步进行的,请求发送---接收--回复--收到
     * 不会说哪个先执行完
     * @author Administrator
     *
     */
    public class MainActivity extends Activity {
    	private Button bindService=null;
    	private Button sendReply=null;
    	private Binder binder=null;
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            bindService=(Button)findViewById(R.id.bindService);
            sendReply=(Button)findViewById(R.id.sendReply);
            bindService.setOnClickListener(new bindServiceListener());
            sendReply.setOnClickListener(new sendReplyListener());
        }
        
        class bindServiceListener implements OnClickListener{
    		@Override
    		public void onClick(View v) {
    			Intent intent=new Intent();
    			intent.setClass(MainActivity.this,FirstService.class);
    			bindService(intent, conn, Service.BIND_AUTO_CREATE);
    		}
        }
        
        class sendReplyListener implements OnClickListener{
    		@Override
    		public void onClick(View v) {
    			Parcel data=Parcel.obtain();//获得Parcel对象,一个存放读取数据的容器
    			Parcel reply=Parcel.obtain();//获得Parcel对象
    			data.writeString("from activity:data");//发送请求给Service
    			try {
    				binder.transact(0, data, reply, 0);
    				String str=reply.readString();//接收Service发送过来的数据
    				System.out.println(str);
    			} catch (RemoteException e) {
    				e.printStackTrace();
    			}
    		}
        }
        
        private ServiceConnection conn=new ServiceConnection() {
    		@Override
    		public void onServiceConnected(ComponentName name, IBinder service) {
    		    MainActivity.this.binder=(Binder)service;//将从service返回过来的IBinder对象赋值给当前对象里面的binder
    		}
    		
    		@Override
    		public void onServiceDisconnected(ComponentName name) {
    			
    		}
    	};
    }
  • 相关阅读:
    maven创建的quickstart项目生成可执行jar
    spring boot 修改banner
    spring boot项目打包成war
    node集成mysql——pool连接池
    adb命令模拟按键输入keycode
    Spring 全局异常处理
    程序开发中版本管理之命名规则及格式
    群晖Nas中搭建Intellij Idea的LicenseServer服务
    uml-类图书写指南
    Spring Boot + Docker + K8S 简单示例
  • 原文地址:https://www.cnblogs.com/keanuyaoo/p/3397846.html
Copyright © 2020-2023  润新知