zoukankan      html  css  js  c++  java
  • android学习笔记56——Service

    Service四大组件之一,需要在AndroidMainfest.xml中添加相关配置,运行于后台,不与用户进行交换,没有UI...

    配置时可通过《intent-filter.../》元素指定它可被那些Intent启动。

    Android系统本身提供了大量的Service组件,可通过这些系统Service来操作Android系统本身。

    BroadcastReceiver组件就是一个全局的事件监听器,只不过其用于监听系统发出的BroadCast,通过使用BroadcastReceiver,即可在不同应用程序之间通信。

    创建、配置Service操作步骤:

    1.定义一个基础Service的子类;

    2.在AndroidMainfest.xml中添加配置;

    Service与Activity都继承自Context,都可调用Context里定义的如:getResources()、getContentResolver()等方法。

    Service也定义了生命周期,方法如下:

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

    实例如下:

    配置如下:

    Android系统中运行Service有两种方式:

    1.通过Context的startService():通过该方法启动服务,访问者与服务直接没有关联,即使访问者退出了,服务仍然运行——因此Service和访问者直接无法进行通信、数据交换。

    2.通过Context的bindService():通过该方法启动服务,访问者与服务绑定在一起,访问者退出,服务也将跟随访问者状态被终止

     ——如果Service和访问者之间需要进行数据交换或方法调用,则应该使用bindService()和unbindService()方法启动、关闭服务。

     

    启动和停止Service

    如下图所示:

    注意:

    每当Service被创建时回调onCreate()方法,每次Service被启动时会回调onStart(),多次启动一个已有的Service组件将不会再回调onCreate(),但每次启动时都会回调onStart()。

    绑定本地Service并与之通信

    Context的bindService方法的完整方法签名为:bindService(Intent service,ServiceConnection conn,int flags):

    service——该参数通过Intent指定要启动的服务;

    ServiceConnection ——该参数是一个ServiceConnection对象,该对象用于监听访问者与Service之间的连接情况。

                 当访问者与Service之间连接成功时将回调该ServiceConnection对象的onServiceConnected(ComponetName name,IBinder binder)方法;

                 当访问者与Service之间断开连接时将回调该ServiceConnection对象的onServiceDisconnected(ComponentName name)方法。

    flags——指定绑定时是否自动创建Service(如果Service还未创建)。该参数可指定为0(不自动创建)或BIND_AUTO_CREATE(自动创建)。

    1.注意到ServiceConnection对象的onServiceConnected方法中有一个IBinder对象,该对象即可实现与被绑定Service之间的通信。

    2.当开发Service类时,该Service类必须提供一个IBinder binder(Intent intent)方法,在绑定本地Service的情况下,onBind(Intent intent)方法返回的IBinder对象将会传给ServiceConnection对象里的

     onSeviceConnected(ComponentName name ,IBinder binder)方法的service参数,这样访问者就可通过该IBinder对象与Service进行通信。

    注意:实际上开发时通常会采用继承Binder(IBinder的实现类)的方式实现自己的IBinder对象。

    实例如下:

    布局文件==》
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@drawable/photo12"
        android:gravity="center_horizontal|center_vertical"
        android:orientation="vertical"
        tools:context=".MainActivity" >
    
        <Button
            android:id="@+id/btnBinder"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="binder"
            android:textSize="25dp" />
    
        <Button
            android:id="@+id/btnUnBinder"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="20dp"
            android:text="unbinder"
            android:textSize="25dp" />
    
        <Button
            android:id="@+id/btnServiceStatus"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="20dp"
            android:text="service status"
            android:textSize="25dp" />
    
    </LinearLayout>
    
    AndroidMainfest.xml==>
    添加
     <service android:name="com.example.myservice1.BindService">
                <intent-filter>
                    <action android:name="com.example.myservice1.MainActivity"/>
                </intent-filter>
    </service>
    
    代码实现==》
    package com.example.myservice1;
    
    import android.app.Service;
    import android.content.Intent;
    import android.os.Binder;
    import android.os.IBinder;
    import android.util.Log;
    
    public class BindService extends Service
    {
    	private Integer count = 0;
    	private boolean quit;
    	// 定义onBinder方法所返回的对象
    	private MyBinder binder = new MyBinder();
    
    	// 通过继承Binder来实现IBinder类f
    	public class MyBinder extends Binder
    	{
    		public int getCount()
    		{
    			// 获取Service的运行状态:count
    			return count;
    		}
    	}
    
    	@Override
    	public IBinder onBind(Intent intent)
    	{
    		System.out.println("Service is Binded");
    		Log.i("swg", "Service is Binded");
    		return binder;
    	}
    
    	@Override
    	public void onCreate()
    	{
    		super.onCreate();
    		System.out.println("Service is onCreate");
    		Log.i("swg", "Service is onCreate");
    		// 启动一条线程、动态地修改count状态值
    		new Thread()
    		{
    			@Override
    			public void run()
    			{
    				while (!quit)
    				{
    					try
    					{
    						Thread.sleep(1000);
    					} catch (InterruptedException e)
    					{
    						e.printStackTrace();
    					}
    					count++;
    				}
    			}
    		}.start();
    	}
    
    	@Override
    	public void onDestroy()
    	{
    		super.onDestroy();
    		System.out.println("Service is onDestroy");
    		Log.i("swg", "Service is onDestroyed");
    		this.quit = true;
    	}
    
    	@Override
    	public boolean onUnbind(Intent intent)
    	{
    		System.out.println("Service is onUnbind");
    		Log.i("swg", "Service is onUnbind");
    		// return super.onUnbind(intent);
    		return true;
    	}
    
    }
    
    package com.example.myservice1;
    
    import com.example.myservice1.BindService.MyBinder;
    import android.os.Bundle;
    import android.os.IBinder;
    import android.util.Log;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.Toast;
    import android.annotation.SuppressLint;
    import android.app.Activity;
    import android.app.Service;
    import android.content.ComponentName;
    import android.content.Intent;
    import android.content.ServiceConnection;
    
    @SuppressLint("ShowToast")
    public class MainActivity extends Activity
    {
    	BindService.MyBinder binder;
    	final String TAG = "com.example.myservice1.MainActivity";
    
    	private ServiceConnection conn = new ServiceConnection()
    	{
    		// 当Activity与服务连接成功时回调该方法
    		@Override
    		public void onServiceConnected(ComponentName name, IBinder service)
    		{
    			System.out.println("-------------Service is onServiceConnected-------------");
    			Log.i("swg", "-------------Service is onServiceConnected-------------");
    			// 获取Service的onBind方法所返回的MyBinder对象
    			binder = (MyBinder) service;
    		}
    
    		// 当Activity与服务断开连接时回调该方法
    		@Override
    		public void onServiceDisconnected(ComponentName name)
    		{
    			System.out.println("-------------Service is onServiceDisconnected-------------");
    			Log.i("swg", "-------------Service is onServiceDisconnected-------------");
    		}
    
    	};
    
    	@Override
    	protected void onCreate(Bundle savedInstanceState)
    	{
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_main);
    
    		Button btnBinder = (Button) this.findViewById(R.id.btnBinder);
    		Button btnUnBinder = (Button) this.findViewById(R.id.btnUnBinder);
    		Button btnServiceStatus = (Button) this.findViewById(R.id.btnServiceStatus);
    		btnBinder.setOnClickListener(new MyButtonClick());
    		btnUnBinder.setOnClickListener(new MyButtonClick());
    		btnServiceStatus.setOnClickListener(new MyButtonClick());
    	}
    
    	private class MyButtonClick implements OnClickListener
    	{
    		@Override
    		public void onClick(View v)
    		{
    			Intent intent = new Intent();
    			intent.setAction(TAG);
    			try
    			{
    				switch (v.getId())
    				{
    				case R.id.btnBinder:
    					Log.i("swg", "-------------onClick is btnBinder-------------");
    					bindService(intent, conn, Service.BIND_AUTO_CREATE);// 绑定时自动创建服务
    					Toast.makeText(MainActivity.this, "Service btnBinder success", 3000)
    					.show();
    					break;
    				case R.id.btnUnBinder:
    					Log.i("swg", "-------------onClick is btnUnBinder-------------");
    					unbindService(conn);
    					Toast.makeText(MainActivity.this, "Service btnUnBinder success", 3000)
    					.show();
    					break;
    				case R.id.btnServiceStatus:
    					Log.i("swg", "-------------onClick is btnServiceStatus-------------");
    					// 获取并显示Service的count值
    					Toast.makeText(MainActivity.this, "Service count==" + binder.getCount(), 5000)
    							.show();
    					break;
    				}
    			} catch (Exception e)
    			{
    				//Toast.makeText(MainActivity.this, "Service error==" + e.getMessage(), 5000).show();
    				return;
    			}
    		}
    	}
    
    }
    

    运行效果:

    注意:对于Service的onBind()所返回的IBinder对象来说,其可被当成该Service组件所返回的回调对象,Service允许客户端通过该IBinder对象访问

    Service内部的数据,这样即可实现客户端与Service之间的通信。

    与多次调用startService()启动Service不同的是,多次调用bindService()并不会重复执行绑定;

    前者,启动一次服务,系统就会调用一次服务的onStart(),后者,系统只会调用onBind()方法一次。

     

  • 相关阅读:
    手机号码 正则表达式
    邮政编码的正则表达式
    对象为null,调用非静态方法产生空指针异常
    文件找不到异常(FileNotFoundException)
    数组下标越界异常解决方法
    空指针异常的解决方法
    需求:打印九九乘法表
    创建简单线程
    ·博客作业06--图
    博客作业05--查找
  • 原文地址:https://www.cnblogs.com/YYkun/p/5997318.html
Copyright © 2011-2022 走看看