• Android学习总结——Service组件


        从Service的启动方式上,可以将Service分为Started Service和Bound Service。在使用Service时,要想系统能够找到此自定义Service,无论哪种类型,都需要在AndroidManifest.xml中声明:

    <service android:name=".MyService">

    一:StartService方式启动服务

        Started Service相对比较简单,通过context.startService(Intent serviceIntent)启动Service,context.stopService(Intent serviceIntent)停止此Service。

    AndroidManifest.xml

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.servicetest">
    
        <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:supportsRtl="true"
            android:theme="@style/AppTheme">
            <activity android:name=".MainActivity">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
    
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
            
            <service android:name=".MyService">
    
            </service>
        </application>
    
    </manifest>

    activity_main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <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="com.example.servicetest.MainActivity">
    
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="启动服务"
            android:id="@+id/btn_StartService" />
    
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="停止服务"
            android:id="@+id/btn_StopService" />
    </LinearLayout>

    MainActivity:
    package com.example.servicetest;
    
    import android.content.Intent;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.Button;
    
    public class MainActivity extends AppCompatActivity implements View.OnClickListener{
        private Button startService;
        private Button stopService;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            startService=(Button)findViewById(R.id.btn_StartService);
            stopService=(Button) findViewById(R.id.btn_StopService);
    
            startService.setOnClickListener(this);
            stopService.setOnClickListener(this);
        }
    
        @Override
        public void onClick(View view) {
            switch (view.getId()){
                case R.id.btn_StartService:
                    //启动服务
                    Intent intentStart=new Intent(MainActivity.this,MyService.class);
                    startService(intentStart);
                    break;
                case R.id.btn_StopService:
                    //停止服务
                    Intent intentStop=new Intent(MainActivity.this,MyService.class);
                    stopService(intentStop);
                    break;
            }
        }
    }
    MyService:
    package com.example.servicetest;
    
    import android.app.Service;
    import android.content.Intent;
    import android.os.IBinder;
    import android.support.annotation.Nullable;
    import android.util.Log;
    
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    /**
     * Created by xch on 2016/9/5.
     */
    public class MyService extends Service{
    
        private boolean flag=true;
    
        @Nullable
        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }
    
        @Override
        public void onCreate() {
            super.onCreate();
            Log.i("tag","服务被创建!");
    
        }
    
        @Override
        public void onDestroy() {
            super.onDestroy();
            Log.i("tag","服务被销毁!");
            new MyThread().setFlagFalse();
        }
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
    
            new MyThread().start();
    
            return super.onStartCommand(intent, flags, startId);
        }
    
        class MyThread extends Thread{
            public void setFlagFalse(){
                flag=false;
            }
            @Override
            public void run() {
                super.run();
    
                while (flag){
                    //每隔一秒钟打印当前时间一次
                    //设置时间打印格式
                    SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//24小时制
                    Date date=new Date();
                    String time=sdf.format(date);
                    Log.i("date",time);
                    try {
                        //沉睡1秒
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    二. BoundService方式启动服务

        bindService启动流程: context.bindService()  ——> onCreate()  ——> onBind()  ——> Service running  ——> onUnbind()  ——> onDestroy()  ——> Service stop

    MainActivity:
    package com.example.servicetest2;
    
    import android.content.ComponentName;
    import android.content.Context;
    import android.content.Intent;
    import android.content.ServiceConnection;
    import android.os.IBinder;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.Button;
    
    public class MainActivity extends AppCompatActivity implements View.OnClickListener{
        private Button bindService,unBindService;
        private Intent intent;
        private MyServiceConn conn=new MyServiceConn();
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            bindService=(Button)findViewById(R.id.btn_BindService);
            unBindService=(Button)findViewById(R.id.btn_UnBindService);
    
            bindService.setOnClickListener(this);
            unBindService.setOnClickListener(this);
        }
    
        @Override
        public void onClick(View v) {
            switch (v.getId()){
                case R.id.btn_BindService:
                    intent=new Intent(MainActivity.this,MyService.class);
                    bindService(intent,conn, Context.BIND_AUTO_CREATE);
                    break;
                case R.id.btn_UnBindService:
                    intent=new Intent(MainActivity.this,MyService.class);
                    unbindService(conn);
                    break;
            }
        }
        private class MyServiceConn implements ServiceConnection {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
               //在服务绑定成功的时候执行
            }
    
            @Override
            public void onServiceDisconnected(ComponentName name) {
               //当服务所在的进程被杀死,或崩溃的时候执行
            }
        }
    }
    MyService:
    package com.example.servicetest2;
    
    import android.app.Service;
    import android.content.Intent;
    import android.os.IBinder;
    import android.support.annotation.Nullable;
    import android.util.Log;
    
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    /**
     * Created by xch on 2016/9/7.
     */
    public class MyService extends Service {
        private boolean flag=true;
        private MyThread thread=new MyThread();
    
        @Nullable
        @Override
        public IBinder onBind(Intent intent) {
            thread.start();
            return null;
        }
    
        @Override
        public void onCreate() {
            Log.i("service","服务被创建!");
            super.onCreate();
        }
    
        @Override
        public void onDestroy() {
            super.onDestroy();
            Log.i("service","服务被销毁!");
            thread.setFlagFalse();
        }
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            return super.onStartCommand(intent, flags, startId);
        }
    
        class MyThread extends Thread{
            public void setFlagFalse(){
                flag=false;
            }
    
            @Override
            public void run() {
                super.run();
                while (flag){
                    Date date=new Date();
                    SimpleDateFormat sdf=new SimpleDateFormat("yyyy-mm-dd HH:mm:ss");
                    Log.i("date",sdf.format(date));
                    try {
                        sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
    
            }
        }
    }

    三.Service与Activity之间通讯

        BoundService可以实现,但是startService没有这个特点。这里需要注意的是,利用bindService启动的Service无法获取这个Service对象,所以这里需要在Service中将对象返回,既然有返回就需要接收。so,看代码:

    MyService:
    package com.example.servicetest2;
    
    import android.app.Service;
    import android.content.Intent;
    import android.os.Binder;
    import android.os.IBinder;
    import android.support.annotation.Nullable;
    import android.util.Log;
    
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    /**
     * Created by xch on 2016/9/7.
     */
    public class MyService extends Service {
        private boolean flag=true;
        private MyThread thread;
        private String format="yyyy-mm-dd HH:mm:ss";
    
        //更改系统时间的输出格式
        public void setFormat(String format){
            this.format=format;
        }
    
        public void changeFormat(String format){
            if(thread!=null){
                //调用方法,更改时间输出格式
                setFormat(format);
            }
        }
    
        @Nullable
        @Override
        public IBinder onBind(Intent intent) {
            thread.start();
            //将代理类返回回去
            return new ServiceBinder();
        }
    
        @Override
        public void onCreate() {
            Log.i("service","服务被创建!");
            thread=new MyThread();
            super.onCreate();
        }
    
        @Override
        public void onDestroy() {
            super.onDestroy();
            Log.i("service","服务被销毁!");
            thread.setFlagFalse();
        }
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            return super.onStartCommand(intent, flags, startId);
        }
    
        class MyThread extends Thread{
            public void setFlagFalse(){
                flag=false;
            }
    
            @Override
            public void run() {
                super.run();
                while (flag){
                    Date date=new Date();
                    SimpleDateFormat sdf=new SimpleDateFormat(format);
                    Log.i("date",sdf.format(date));
                    try {
                        sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
    
            }
        }
    
        /**
         * 当前服务的代理类,即可使用changeFormat()方法
         * 需要通过IBinder将这个代理类返回回去,即onBinder()方法
         */
        public class ServiceBinder extends Binder{
            public void changeServiceBinder(String format){
                if(thread!=null){
                    changeFormat(format);
                }
            }
    
        }
    }

    这里需要在service中定义一个代理类,并利用onBinder()方法返回去。

    MainActivity:

    package com.example.servicetest2;
    
    import android.content.ComponentName;
    import android.content.Context;
    import android.content.Intent;
    import android.content.ServiceConnection;
    import android.os.IBinder;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.Button;
    
    public class MainActivity extends AppCompatActivity implements View.OnClickListener{
        private Button bindService,unBindService,changeFormat;
        private Intent intent;
        private MyServiceConn conn=new MyServiceConn();
        //接收到的service对象
        private MyService.ServiceBinder serviceBinder;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            bindService=(Button)findViewById(R.id.btn_BindService);
            unBindService=(Button)findViewById(R.id.btn_UnBindService);
            changeFormat=(Button)findViewById(R.id.btn_changeFormat);
    
            bindService.setOnClickListener(this);
            unBindService.setOnClickListener(this);
            changeFormat.setOnClickListener(this);
        }
    
        @Override
        public void onClick(View v) {
            switch (v.getId()){
                case R.id.btn_BindService:
                    intent=new Intent(MainActivity.this,MyService.class);
                    bindService(intent,conn, Context.BIND_AUTO_CREATE);
                    break;
                case R.id.btn_UnBindService:
                    intent=new Intent(MainActivity.this,MyService.class);
                    unbindService(conn);
                    break;
                case R.id.btn_changeFormat:
                    serviceBinder.changeServiceBinder("HH:mm:ss");
                    break;
            }
        }
        private class MyServiceConn implements ServiceConnection {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
               //在服务绑定成功的时候执行,同时接收到了IBinder对象(类型为代理类对象,因为onBinder方法返回了代理类对象)
                serviceBinder= (MyService.ServiceBinder) service;
            }
    
            @Override
            public void onServiceDisconnected(ComponentName name) {
               //当服务所在的进程被杀死,或崩溃的时候执行
            }
        }
    }

       这里实现了ServiceConnection接口的自定义类需要实现如上两个方法,其中onServiceConnected(ComponentName name, IBinder service)方法能获取onBinder()返回的service对象。

     结果:










  • 相关阅读:
    区间DP——石子合并
    线性DP-最短编辑距离、编辑距离
    生成树协议
    交换机技术
    以太网原理
    接口知识点
    目前在中国有影响的几种现场总线比较
    委托
    C#有关继承知识点
    C#数组总结
  • 原文地址:https://www.cnblogs.com/xch-yang/p/5849151.html
Copyright © 2020-2023  润新知