首页 > 代码库 > Android学习总结——Service组件

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对象。

 结果:

技术分享
技术分享

技术分享

技术分享



Android学习总结——Service组件