zoukankan      html  css  js  c++  java
  • Android学习(十四) Service组件

    一、定义

      运行在后台,没有页面,不可见。优先级高于Activity,当系统内存不足时,会先释放一些Activity。注意,Service同样是运行在主线程中,不能做一些耗时操作。如果一定要做一些耗时的操作,启动一个新的线程,在新的线程中来处理。

    二、用途:

      播放音乐,记录地理位置的改变,监听某些动作。

    三、Sevice分类:

      1、本地服务(Local Service):是一种本地服务,一般用于应用程序内部,通过startService方法启动,通过stopService,stopSelf,stopSelfResult方法停止。另一种服务器启动方式:bindService,unbindService。

      2、远程服务(Remote Service):Android内部多个应用程序之间。定义Ibinder接口,暴露数据。

      

    四、Service声明周期:

      Service声明周期分为两种情况:

      1、通过startService方式启动的服务,为左边方式,onCreate-->onStartCommand-->service Running -->stopXXZXOnDestroy;

      特点:启动后服务和启动源没有任何联系,无法得到服务对象。

      2、通过bind方式启动服务,为右边所示方式,OnCreate--> onBind--> Clients are bound to service --> onUnbind -->onDestroy;

      特点:通过Ibinder接口实例,返回一个ServiceConnection对象给启动源。通过ServiceConnection对象的相关方法可以得到Service对象。

    示例:

    1、start方式声明周期示例

    AndroidManifest.xml,首先在配置文件中注册服务,添加服务名称

    <service android:name="MyService1"></service>

    MyService1.java,创建服务类,继承Service抽象方法,实现onCreate,onStartCommand,onDestroy,onBind方法,

    package com.example.servicedemo;
    
    import android.app.Service;
    import android.content.Intent;
    import android.os.IBinder;
    
    public class MyService1 extends Service{
        @Override  //服务创建方法,只启动一次
        public void onCreate() {
            System.out.println("onCreate");
            super.onCreate();
        }
        
        @Override  //服务启动方法
        public int onStartCommand(Intent intent, int flags, int startId) {
            System.out.println("StartCommand");
            return super.onStartCommand(intent, flags, startId);
        }
        
        @Override  //服务销毁方法
        public void onDestroy() {
            System.out.println("Destroy");
            super.onDestroy();
        }
        
        
        @Override
        public IBinder onBind(Intent intent) {
            // TODO Auto-generated method stub
            return null;
        }
    
    }

    main.xml,页面中添加两个按钮startService和stopService。

    <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:orientation="vertical">
    
        <TextView
            android:id="@+id/textView1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Start:" />
    
        <Button
            android:onClick="doClick"
            android:id="@+id/btn_start"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="StartService" />
    
        <Button
            android:onClick="doClick"
            android:id="@+id/btn_stop"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="StopService" />
    
    
    </LinearLayout>

    main.java,后台代码

    package com.example.servicedemo;
    
    import android.os.Bundle;
    import android.app.Activity;
    import android.content.Intent;
    import android.view.Menu;
    import android.view.View;
    
    public class MainActivity extends Activity {
        Intent intent;
        
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
        }
    
        public void doClick(View v) {
            switch (v.getId()) {
                case R.id.btn_start:
                    //创建intent对象
                    intent = new Intent(MainActivity.this,MyService1.class);
                    //启动一个服务
                    startService(intent);
                    break;
                case R.id.btn_stop:
                    //结束一个服务
                    stopService(intent);
                    break;
            }
        }
    
    }

       onCreate方法只是第一次被调用,只调用一次,除非Service对象被卸载了,onStartCommand点击一次就调用一次,可以重复点击,onDestory方法销毁方法。

    2、bind方式绑定

    AndroidManifest.xml,注册服务器对象

    <service android:name="com.example.servicedemo2.MyBindService"></service>

    main.xml,在页面上放置两个按钮,启动和卸载

    <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:orientation="vertical">
    
        <TextView
            android:id="@+id/textView1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="BindService:" />
    
        <Button
            android:onClick="doClick"
            android:id="@+id/btn_bindstart"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="BindService" />
    
        <Button
            android:onClick="doClick"
            android:id="@+id/btn_bindstop"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="UnBindService" />
    </LinearLayout>

    MyBindService.java,创建基于Bind绑定的服务类

    package com.example.servicedemo2;
    
    import android.app.Service;
    import android.content.Intent;
    import android.os.IBinder;
    
    public class MyBindService extends Service{
    
        @Override  //绑定方法
        public IBinder onBind(Intent intent) {
            System.out.println("Bind_onBind");
            return null;
        }
        
        @Override //创建时调用
        public void onCreate() {
            System.out.println("Bind_onCreate");
            super.onCreate();
        }
        
        @Override  //销毁时调用
        public void onDestroy() {
            System.out.println("Bind_onDestroy");
            super.onDestroy();
        }
        
        @Override  //解绑时调用
        public boolean onUnbind(Intent intent) {
            System.out.println("Bind_onUnbind");
            return super.onUnbind(intent);
        }
    
    }

    main.java,后台Activity代码

    package com.example.servicedemo2;
    
    import android.app.Activity;
    import android.app.Service;
    import android.content.ComponentName;
    import android.content.Intent;
    import android.content.ServiceConnection;
    import android.os.Bundle;
    import android.os.IBinder;
    import android.view.View;
    
    public class MainActivity extends Activity {
    
        private ServiceConnection conn = new ServiceConnection() {
            
            @Override
            public void onServiceDisconnected(ComponentName name) {
                
            }
            
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                
            }
        };
        
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
        }
        
        public void doClick(View v){
            switch(v.getId()){
                case R.id.btn_bindstart:
                    Intent intent = new Intent(MainActivity.this, MyBindService.class);
                    bindService(intent, conn,Service.BIND_AUTO_CREATE);
                    break;
                case R.id.btn_bindstop:
                    unbindService(conn);
                    break;
            }
        }
    }

      启动和结束按钮不能被多次点击,必须启动后才能释放,1对1,启动服务后,退出应用程序,也会报错,必须先释放绑定的服务源对象

    3、activity调用service中的方法

    main.xml 主页面,定义六个按钮,bind和unbind为绑定service,paly,pause,next,prev为调用service中的四个方法

    <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:orientation="vertical">
    
        <TextView
            android:id="@+id/textView1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="BindService:" />
    
        <Button
            android:onClick="doClick"
            android:id="@+id/btn_bindstart"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="BindService" />
    
        <Button
            android:onClick="doClick"
            android:id="@+id/btn_bindstop"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="UnBindService" />
    
        <TextView
            android:id="@+id/textView2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="播放器服务" />
    
        <Button
            android:onClick="musicClick"
            android:id="@+id/btnPlay"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="播放" />
    
        <Button
            android:onClick="musicClick"
            android:id="@+id/btnPause"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="暂停" />
    
        <Button
            android:onClick="musicClick"
            android:id="@+id/btnNext"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="下一首" />
    
        <Button
            android:onClick="musicClick"
            android:id="@+id/btnPrev"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="上一首" />
    
    </LinearLayout>

    mybindservice.java 服务方法

    package com.example.servicedemo2;
    
    import android.app.Service;
    import android.content.Intent;
    import android.os.Binder;
    import android.os.IBinder;
    
    public class MyBindService extends Service{
    
        //继承抽象类Binder
        public class MyBinder extends Binder{
            
            //定义获取绑定服务的方法
            public MyBindService getService(){
                return MyBindService.this;
            }
        }
        
        @Override  //绑定方法
        public IBinder onBind(Intent intent) {
            System.out.println("Bind_onBind");
            return new MyBinder();
        }
        
        @Override //创建时调用
        public void onCreate() {
            System.out.println("Bind_onCreate");
            super.onCreate();
        }
        
        @Override  //销毁时调用
        public void onDestroy() {
            System.out.println("Bind_onDestroy");
            super.onDestroy();
        }
        
        @Override  //解绑时调用
        public boolean onUnbind(Intent intent) {
            System.out.println("Bind_onUnbind");
            return super.onUnbind(intent);
        }
        
        //添加自定义的方法
        
        //播放方法
        public void play(){
            System.out.println("Play");
        }
        
        //暂停方法
        public void pause(){
            System.out.println("Pause");
        }
        
        //下一首
        public void next(){
            System.out.println("Next");
        }
    
        //上一首
        public void prev(){
            System.out.println("Prev");
        }
    }

    main.java 后台代码

    package com.example.servicedemo2;
    
    import com.example.servicedemo2.MyBindService.MyBinder;
    
    import android.app.Activity;
    import android.app.Service;
    import android.content.ComponentName;
    import android.content.Intent;
    import android.content.ServiceConnection;
    import android.os.Bundle;
    import android.os.IBinder;
    import android.view.View;
    
    public class MainActivity extends Activity {
    
        MyBinder b;
        
        private ServiceConnection conn = new ServiceConnection() {
            
            @Override  //当启动源和Service的连接意外丢失的时候会调用这个方法
            //当Service崩溃了,或者被强行杀死了,如果接触了绑定就不会被调用
            public void onServiceDisconnected(ComponentName name) {
                
            }
            
            //activity和service之间的参数传递。
            @Override  //当启动源跟Service成功连接之后将会自动调用这个方法
            public void onServiceConnected(ComponentName name, IBinder binder) {
                b = (MyBindService.MyBinder)binder;
            }
        };
        
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
        }
        
        //声明周期事件
        public void doClick(View v){
            switch(v.getId()){
                case R.id.btn_bindstart:
                    Intent intent = new Intent(MainActivity.this, MyBindService.class);
                    bindService(intent, conn,Service.BIND_AUTO_CREATE);
                    break;
                case R.id.btn_bindstop:
                    unbindService(conn);
                    break;
            }
        }
        
        
        public void musicClick(View v){
            //通过b.xxx调用service中的方法
            switch(v.getId()){
                case R.id.btnPlay:
                    b.getService().play();
                    break;
                case R.id.btnPause:
                    b.getService().pause();
                    break;
                case R.id.btnNext:
                    b.getService().next();
                    break;
                case R.id.btnPrev:
                    b.getService().prev();
                    break;
            }
        }
    }

    AndroidManifest.xml注册service对象

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.servicedemo2"
        android:versionCode="1"
        android:versionName="1.0" >
    
        <uses-sdk
            android:minSdkVersion="8"
            android:targetSdkVersion="18" />
    
        <application
            android:allowBackup="true"
            android:icon="@drawable/ic_launcher"
            android:label="@string/app_name"
            android:theme="@style/AppTheme" >
            <activity
                android:name="com.example.servicedemo2.MainActivity"
                android:label="@string/app_name" >
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
    
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
            <service android:name="com.example.servicedemo2.MyBindService"></service>
        </application>
    </manifest>
  • 相关阅读:
    20080619 SQL SERVER 输入 NULL 的快捷键
    20090406 Adobe的“此产品的许可已停止工作”错误的解决办法
    20080908 Office Powerpoint 2007 不能输入中文的解决办法
    20080831 ClearGertrude Blog Skin 's cnblogs_code class
    20080603 Facebook 平台正式开放
    20080519 安装 Microsoft SQL Server 2000 时提示 创建挂起的文件操作
    test
    Linux—fork函数学习笔记
    SOA的设计理念
    Why BCP connects to SQL Server instance which start with account of Network Service fail?
  • 原文地址:https://www.cnblogs.com/zhengcheng/p/4387773.html
Copyright © 2011-2022 走看看