zoukankan      html  css  js  c++  java
  • Android笔记(十七) Android中的Service

    定义和用途

             Service是Android的四大组件之一,一直在后台运行,没有用户界面。Service组件通常用于为其他组件提供后台服务或者监控其他组件的运行状态,例如播放音乐、记录地理位置,监听用户操作等等。它的优先级要高于Activity。它运行在主线程中,所以不能一用它来做一些耗时的请求或者操作。

    Service的分类

             1. 本地服务(Local Service):主要用于程序内部

             2. 远程服务(Remote Service):用于Android系统内部的应用程序之间

    定义Service的步骤

             开发Service和定义一个Activity一样,只需两个步骤

             1. 定义一个继承Service的子类

             2. 在AndroidManiFest.xml中注册该Service

    Service的启动方式

    startService方式启动

    MainActivity.java

    package cn.lixyz.servicedemo;
    
    import android.app.Activity;
    import android.content.Intent;
    import android.os.Bundle;
    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);
    
            findViewById(R.id.btnStartService).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    intent = new Intent(MainActivity.this, MyStartService.class);
                    startService(intent);
                }
            });
    
            findViewById(R.id.btnStopService).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    stopService(intent);
                }
            });
        }
    }

    activity_layout.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"
        tools:context="cn.lixyz.servicedemo.MainActivity">
    
        <Button
            android:id="@+id/btnStartService"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="启动服务" />
    
        <Button
            android:id="@+id/btnStopService"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="关闭服务" />
    
    </LinearLayout>

    MyStartService.java

    package cn.lixyz.servicedemo;
    
    import android.app.Service;
    import android.content.Intent;
    import android.content.ServiceConnection;
    import android.os.IBinder;
    import android.support.annotation.Nullable;
    import android.util.Log;
    
    public class MyStartService extends Service {
    
        int i = 1;
    
        @Nullable
        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }
    
        @Override
        public void onCreate() {
            Log.d("TEST",i++ + ".onCreate方法执行。。。");
            super.onCreate();
        }
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            Log.d("TEST",i++ + ".onStartCommand。。。");
            return super.onStartCommand(intent, flags, startId);
        }
    
        @Override
        public boolean onUnbind(Intent intent) {
            Log.d("TEST",i++ + ".onUnbind。。。");
            return super.onUnbind(intent);
        }
    
        @Override
        public void onDestroy() {
            Log.d("TEST",i++ + ".onDestroy。。。");
            super.onDestroy();
        }
    }

    AndroidManiFest.xml

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="cn.lixyz.servicedemo" >
    
        <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:theme="@style/AppTheme" >
            <activity
                android:name=".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=".MyStartService"
                android:enabled="true"
                android:exported="true" >
            </service>
            <service
                android:name=".MyBindService"
                android:enabled="true"
                android:exported="true" >
            </service>
        </application>
    
    </manifest>

              连续点击三次启动服务按钮,再连续点击三次关闭服务按钮,Log如下

    bindService方式启动

    MainActivity.java

    package cn.lixyz.servicedemo;
    
    import android.app.Activity;
    import android.app.Service;
    import android.content.ComponentName;
    import android.content.Context;
    import android.content.Intent;
    import android.content.ServiceConnection;
    import android.os.Bundle;
    import android.os.IBinder;
    import android.util.Log;
    import android.view.View;
    
    public class MainActivity extends Activity implements ServiceConnection {
    
        Intent intent ;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            findViewById(R.id.btnStartService).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    intent = new Intent(MainActivity.this, MyBindService.class);
                    startService(intent);
                }
            });
    
            findViewById(R.id.btnStopService).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    stopService(intent);
                }
            });
    
            findViewById(R.id.btnBindService).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    intent = new Intent(MainActivity.this, MyBindService.class);
                    bindService(intent, MainActivity.this, Service.BIND_AUTO_CREATE);
                }
            });
    
            findViewById(R.id.btnUnbindService).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    unbindService(MainActivity.this);
                }
            });
        }
    
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.d("TEST","onServiceConnected方法执行了。。。。");
        }
    
        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.d("TEST","onServiceDisconnected。。。。");
        }
    }

    activity_layout.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"
        tools:context="cn.lixyz.servicedemo.MainActivity">
    
        <Button
            android:id="@+id/btnStartService"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="启动服务" />
    
        <Button
            android:id="@+id/btnStopService"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="关闭服务" />
    
        <Button
            android:id="@+id/btnBindService"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="绑定服务" />
    
        <Button
            android:id="@+id/btnUnbindService"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="取消绑定服务" />
    
    </LinearLayout>

    MyBindService.java

    package cn.lixyz.servicedemo;
    
    import android.app.Service;
    import android.content.Intent;
    import android.content.ServiceConnection;
    import android.os.Binder;
    import android.os.IBinder;
    import android.util.Log;
    
    public class MyBindService extends Service {
    
        int i = 1;
    
        public MyBindService() {
        }
    
        @Override
        public IBinder onBind(Intent intent) {
            return new Binder();
        }
    
        @Override
        public void onCreate() {
            Log.d("TEST", i++ + ".onCreate方法执行。。。");
            super.onCreate();
        }
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            Log.d("TEST", i++ + ".onStartCommand。。。");
            return super.onStartCommand(intent, flags, startId);
        }
    
        @Override
        public boolean onUnbind(Intent intent) {
            Log.d("TEST", i++ + ".onUnbind。。。");
            return super.onUnbind(intent);
        }
    
        @Override
        public void onDestroy() {
            Log.d("TEST", i++ + ".onDestroy。。。");
            super.onDestroy();
        }
    
    
    }

    AndroidManiFest.xml

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="cn.lixyz.servicedemo" >
    
        <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:theme="@style/AppTheme" >
            <activity
                android:name=".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=".MyStartService"
                android:enabled="true"
                android:exported="true" >
            </service>
            <service
                android:name=".MyBindService"
                android:enabled="true"
                android:exported="true" >
            </service>
        </application>
    
    </manifest>

             运行结果:

    Service的生命周期

             从上面的运行结果可以看出Service的生命周期

             1. 被启动的服务的声明周期:如果一个Service被某个Activity调用Context.startService()方法启动,那么不管是否有Activity使用bindService()绑定或者unbindService接触绑定到该Service,该Service都会在后台运行。如果一个Service被startService()方法多次启动,那么onCreate方法只调用一次,onstart()方法将会被调用多次,并且系统只会创建Service的一个实例(因此只需要调用一次stopService()),该Service将会一直在后台运行,而不管对应程序的Activity是否在运行,知道被调用stopService(),或者自身的stopSelf()。

             2. 被绑定的服务的生命周期:如果一个Service被某个Activity调用Content.bindService()方法绑定,不管调用bindService()调用几次,onCreate()方法都只会调用一次,同时onStart()方法始终不会被调用,当建立连接之后,Service将会一直运行,除非调用Context.unbindService()断开链接或者之前调用bindService的Context不存在了(如Activity被finish掉了),系统将会自动停止Service,对应onDestroy()将被调用。

             3. 被启动又被绑定的服务的生命周期:如果一个Service又被启动又被绑定,则该Service将会一直在后台运行,并且不管如何调用,onCreate()始终只会调用一次,对应startService() 调用多少次,Service的onStart()便会调用多少次,调用unbindService将不会停止Service,必须调用stopService或者Service的stopSelf来停止服务。

             4. 当服务停止时清楚服务:当一个Service被终止(①调用stopService ②调用stopSelf ③不再有绑定的连接(没有被启动时)),onDestroy()方法将会被调用,在这里你应当做一些清除工作,如停止在Service中创建并运行线程。

    Service中的数据传递

    startService并传递数据

    MainActivity.java

    package cn.lixyz.servicedemo;
    
    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.util.Log;
    import android.view.View;
    import android.widget.EditText;
    
    public class MainActivity extends Activity implements ServiceConnection {
    
        Intent intent ;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            findViewById(R.id.btnStartService).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    intent = new Intent(MainActivity.this, MyStartService.class);
                    String str = ((EditText)findViewById(R.id.et_input)).getText().toString();
                    intent.putExtra("data",str);
                    startService(intent);
                }
            });
    
            findViewById(R.id.btnStopService).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    stopService(intent);
                }
            });
    
            findViewById(R.id.btnBindService).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    intent = new Intent(MainActivity.this, MyBindService.class);
                    bindService(intent, MainActivity.this, Service.BIND_AUTO_CREATE);
                }
            });
    
            findViewById(R.id.btnUnbindService).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    unbindService(MainActivity.this);
                }
            });
        }
    
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.d("TEST","onServiceConnected方法执行了。。。。");
        }
    
        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.d("TEST","onServiceDisconnected。。。。");
        }
    }

    activity_layout.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"
        tools:context="cn.lixyz.servicedemo.MainActivity">
    
        <EditText
            android:id="@+id/et_input"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="请输入要传入的内容"/>
    
        <Button
            android:id="@+id/btnStartService"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="启动服务" />
    
        <Button
            android:id="@+id/btnStopService"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="关闭服务" />
    
        <Button
            android:id="@+id/btnBindService"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="绑定服务" />
    
        <Button
            android:id="@+id/btnUnbindService"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="取消绑定服务" />
    
    </LinearLayout>

    MyStartService.java

    package cn.lixyz.servicedemo;
    
    import android.app.Service;
    import android.content.Intent;
    import android.content.ServiceConnection;
    import android.os.IBinder;
    import android.os.IInterface;
    import android.os.Parcel;
    import android.os.RemoteException;
    import android.support.annotation.Nullable;
    import android.util.Log;
    
    import java.io.FileDescriptor;
    
    public class MyStartService extends Service {
    
        String str;
    
        @Nullable
        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }
    
        @Override
        public void onCreate() {
            super.onCreate();
            new Thread() {
                @Override
                public void run() {
                    super.run();
                    str = "预定内容";
                    for (int i = 0; i <= 50; i++) {
                        Log.d("TEST", str);
                        try {
                            sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }.start();
        }
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            str = intent.getStringExtra("data");
            return super.onStartCommand(intent, flags, startId);
        }
    
        @Override
        public boolean onUnbind(Intent intent) {
            return super.onUnbind(intent);
        }
    
        @Override
        public void onDestroy() {
            super.onDestroy();
        }
    }

    AndroidManiFest.xml

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="cn.lixyz.servicedemo" >
    
        <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:theme="@style/AppTheme" >
            <activity
                android:name=".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=".MyStartService"
                android:enabled="true"
                android:exported="true" >
            </service>
            <service
                android:name=".MyBindService"
                android:enabled="true"
                android:exported="true" >
            </service>
        </application>
    
    </manifest>

             运行结果:

    bindService并传递数据

    MainActivity.java

    package cn.lixyz.servicedemo;
    
    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.util.Log;
    import android.view.View;
    import android.widget.EditText;
    
    public class MainActivity extends Activity implements ServiceConnection {
    
        Intent intent ;
        MyBindService.Binder binder;
    
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            findViewById(R.id.btnStartService).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    intent = new Intent(MainActivity.this, MyStartService.class);
                    startService(intent);
                }
            });
    
            findViewById(R.id.btnStopService).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    stopService(intent);
                }
            });
    
            findViewById(R.id.btnBindService).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    intent = new Intent(MainActivity.this, MyBindService.class);
                    bindService(intent, MainActivity.this, Service.BIND_AUTO_CREATE);
                }
            });
    
            findViewById(R.id.btnUnbindService).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    unbindService(MainActivity.this);
                }
            });
    
            findViewById(R.id.btnSyncService).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    String str = ((EditText) findViewById(R.id.et_input)).getText().toString();
                    binder.setString(str);
                }
            });
        }
    
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.d("TEST","onServiceConnected方法执行了。。。。");
            binder = (MyBindService.Binder) service;
        }
    
        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.d("TEST","onServiceDisconnected。。。。");
        }
    }

    activity_layout.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"
        tools:context="cn.lixyz.servicedemo.MainActivity">
    
        <EditText
            android:id="@+id/et_input"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="请输入要传入的内容"/>
    
        <Button
            android:id="@+id/btnStartService"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="启动服务" />
    
        <Button
            android:id="@+id/btnStopService"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="关闭服务" />
    
        <Button
            android:id="@+id/btnBindService"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="绑定服务" />
    
        <Button
            android:id="@+id/btnUnbindService"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="取消绑定服务" />
    
        <Button
            android:id="@+id/btnSyncService"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="同步服务"/>
    
    </LinearLayout>

    MyBindService.java

    package cn.lixyz.servicedemo;
    
    import android.app.Service;
    import android.content.Intent;
    import android.content.ServiceConnection;
    import android.os.Binder;
    import android.os.IBinder;
    import android.util.Log;
    
    public class MyBindService extends Service {
    
        String str = "默认信息";
    
        public MyBindService() {
        }
    
        @Override
        public IBinder onBind(Intent intent) {
    
            return new Binder();
        }
    
        public class Binder extends android.os.Binder{
            public void setString(String str){
                MyBindService.this.str = str;
            }
        }
    
        @Override
        public void onCreate() {
            Log.d("TEST", ".onCreate方法执行。。。");
    
            new Thread(){
                @Override
                public void run() {
                    super.run();
    
                    for (int i = 0;i<80;i++){
                        Log.d("TEST",i + str);
                        try {
                            sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
    
                }
            }.start();
    
    
            super.onCreate();
        }
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            Log.d("TEST", ".onStartCommand方法执行。。。");
    
    
            return super.onStartCommand(intent, flags, startId);
        }
    
        @Override
        public boolean onUnbind(Intent intent) {
            Log.d("TEST", ".onUnbind方法执行。。。");
            return super.onUnbind(intent);
        }
    
        @Override
        public void onDestroy() {
            Log.d("TEST", ".onDestroy方法执行。。。");
            super.onDestroy();
        }
    
    
    }

    AndroidManiFest.xml

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="cn.lixyz.servicedemo" >
    
        <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:theme="@style/AppTheme" >
            <activity
                android:name=".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=".MyStartService"
                android:enabled="true"
                android:exported="true" >
            </service>
            <service
                android:name=".MyBindService"
                android:enabled="true"
                android:exported="true" >
            </service>
        </application>
    
    </manifest>

             运行结果:

  • 相关阅读:
    js正则表达式
    js遍历对象属性
    C# 带Cookies发送请求
    C# Cookies设置和读取
    C# ref 和 out 的使用
    jq 禁用复选框 和输入框
    C++学习之嵌套类和局部类
    C++学习之this指针
    C++学习之运算符重载的总结
    Labview中引用,属性节点,局部变量之间的区别
  • 原文地址:https://www.cnblogs.com/xs104/p/4750184.html
Copyright © 2011-2022 走看看